0
votes

I want to add to my pagination the next and prev button functionality so i can also move the pages through them. in my code i only manage to display the next or prev page and see the content from the second page on click but without also moving the selected number of the button from 1 to 2, or the next page if there are more and so on. same for the prev. also, if i cannot go next/prev i want to have the next/prev button disabled.

any help with this, please?

here is what i have till now:

window.onload = function(){

var data = {
  "headings": {
    "propBook": "Book",
    "propAuthor": "Author",
    "propYear": "Year",
  },
  "items": [{
      "fields": {
        "propBook": "The Great Gatsby",
        "propAuthor": "F Scott Fitzgerald",
        "propYear": "1925",
      },
      "button": {
        "name": "View book",
        "propURL": "https://google.com"
      }
    },
    {
      "fields": {
        "propBook": "The Grapes of Wrath",
        "propAuthor": "John Steinbeck",
        "propYear": "1939",
      },
      "button": {
        "name": "View book",
        "propURL": ""
      }
    },
    {
      "fields": {
        "propBook": "A Wild Sheep Chase",
        "propAuthor": "Haruki Murakami",
        "propYear": "1982",
      },
      "button": {
        "name": "View book",
        "propURL": "https://google.com"
      }
    }
  ]
}


const HEADINGS = data.headings;
const ITEMS = data.items;
const TABLE_WRAPPER = document.querySelector('.book-component .table-wrapper');
const TABLE = document.createElement('table');
TABLE.setAttribute('class', 'pagination');
  TABLE.setAttribute('data-pagecount', 2);
TABLE_WRAPPER.appendChild(TABLE);


for (const field in data) {
  const TABLE_ROW = document.createElement('tr');
  TABLE_ROW.setAttribute('id', 'myRow');

  if (field == 'headings') {
    for (const child in HEADINGS) {
      const HEADER_CELL = document.createElement('th');
      TABLE_ROW.appendChild(HEADER_CELL);
      HEADER_CELL.setAttribute('class', 'sort-cta');
      HEADER_CELL.innerText = HEADINGS[child];
      TABLE.appendChild(TABLE_ROW);
    }
  } else if (field == 'items') {
    for (const child in ITEMS) {
      const TABLE_ROW = document.createElement('tr');
      let item = ITEMS[child].fields;
      let btn = ITEMS[child].button;      

      for (const row in item) {
        const TABLE_DATA = document.createElement('td');
        TABLE_ROW.appendChild(TABLE_DATA);
        TABLE_DATA.innerText = item[row];
        TABLE.appendChild(TABLE_ROW);       
      }
      
      
      if (btn.propURL !== '') {
        let link = document.createElement('a');
        link.setAttribute('href', btn.propURL);
        link.innerHTML = btn.name;
        x = TABLE_ROW.insertCell(-1);
        x.appendChild(link);
      } else {
        let link = document.createElement('span');
        link.innerHTML = 'Reserved';
        x = TABLE_ROW.insertCell(-1);
        x.appendChild(link);
      }
    }
  }
}

  let perPage = 10;
  function genTables() {
    let tables = document.querySelectorAll('.pagination');
    tables.forEach((table) => {
      perPage = parseInt(table.dataset.pagecount);
      createFooters(table);
      createTableMeta(table);
      loadTable(table);
    });
  }
  // based on current page, only show the elements in that range
  function loadTable(table) {
    let startIndex = 0;
    if (table.querySelector('th')) startIndex = 1;
    const START = parseInt(table.dataset.currentpage) * table.dataset.pagecount + startIndex;
    const END = START + parseInt(table.dataset.pagecount);
    const TABLE_ROWS = table.rows;
    for (var x = startIndex; x < TABLE_ROWS.length; x++) {
      if (x < START || x >= END) TABLE_ROWS[x].classList.add('inactive');
      else TABLE_ROWS[x].classList.remove('inactive');
    }
  }

  function createTableMeta(table) {
    table.dataset.currentpage = '0';
  }

  function createFooters(table) {
    const COUTING_WRAPPER = document.createElement('div');
    COUTING_WRAPPER.setAttribute('class', 'counting-wrapper');
    const COUNTING_MSG = document.createElement('p');
    COUTING_WRAPPER.appendChild(COUNTING_MSG);
    let TABLE_WRAP = document.querySelector('.table-wrapper');
    TABLE_WRAP.appendChild(COUTING_WRAPPER);

    let hasHeader = false;
    if (table.querySelector('th')) hasHeader = true;
    let ROWS = table.rows.length;
    if (hasHeader) ROWS = ROWS - 1;
    let NUM_PAGES = ROWS / perPage;
    let pager = document.createElement('div');
    // add an extra page
    if (NUM_PAGES % 1 > 0) NUM_PAGES = Math.floor(NUM_PAGES) + 1;
    pager.className = 'pager';
    let nextPage = document.createElement('button');
    nextPage.innerHTML = 'next';
    nextPage.className = 'item';
    let prevPage = document.createElement('button');
    prevPage.innerHTML = 'prev';
    prevPage.className = 'item';
    pager.appendChild(prevPage);
    pager.appendChild(nextPage);


    nextPage.addEventListener('click', () => {
      table.dataset.currentpage = parseInt(table.dataset.currentpage) + 1;
      loadTable(table);
    });

    prevPage.addEventListener('click', () => {
      table.dataset.currentpage = parseInt(table.dataset.currentpage) - 1;
      loadTable(table);
    })

    for (var i = 0; i < NUM_PAGES; i++) {
      var page = document.createElement('button');
      page.innerHTML = i + 1;
      page.className = 'pager-item';
      page.dataset.index = i;
      if (i == 0) page.classList.add('selected');
      

      page.addEventListener('click', function () {
        var items = pager.querySelectorAll('.pager-item');
        for (var x = 0; x < items.length; x++) {
          items[x].classList.remove('selected');
        }
        this.classList.add('selected');
        table.dataset.currentpage = this.dataset.index;
        loadTable(table);

       
      });
      pager.appendChild(page);
    }

    // insert page at the top of the table
    table.parentNode.insertBefore(pager, table);
  }
  genTables();


};
tr.inactive {
  display: none;
}

.table-wrapper {
  display: flex;
  flex-direction: column-reverse;
}

.pager {
  display: flex;
  justify-content: center;
  padding: 0;
  margin-top: 10px;
  font-weight: 800;
}

.pager-item.selected {
  outline: none;
  border-color: #0077cc;
  background: #0077cc;
  color: #fff;
  cursor: default;
}
<div class="book-component">
  <div class="table-wrapper">
  </div>
</div>
1

1 Answers

0
votes

Your loadTable function is updating the DOM based on the current state of your application. You can extend this to set the disabled state of the prev/next buttons, and to set the selected class of the page number button.

Here's an example where the button state is set by the loadTable function. The click event handlers should only update the current page (ie. set the state of the app). Then you can do your rendering of the state in the loadTable function.

// based on current page, only show the elements in that range
function loadTable(table) {
  let startIndex = 0;
  if (table.querySelector('th')) startIndex = 1;
  const START = parseInt(table.dataset.currentpage) * table.dataset.pagecount + startIndex;
  const END = START + parseInt(table.dataset.pagecount);
  const TABLE_ROWS = table.rows;
  for (var x = startIndex; x < TABLE_ROWS.length; x++) {
    if (x < START || x >= END) TABLE_ROWS[x].classList.add('inactive');
    else TABLE_ROWS[x].classList.remove('inactive');
  }
  
// You should move this calculation outside of the function
  const ROWS = table.rows.length - 1;
  const NUM_PAGES = Math.ceil(ROWS / perPage);
  
  const prevPage = document.getElementsByName('pagination-prev-button')[0];
  const nextPage = document.getElementsByName('pagination-next-button')[0];

  const isNextDisabled = +table.dataset.currentpage >= NUM_PAGES - 1;
  const isPrevDisabled = +table.dataset.currentpage === 0;

  if (isNextDisabled) {
    nextPage.setAttribute('disabled', true);
  } else {
    nextPage.removeAttribute('disabled');
  }

  if (isPrevDisabled) {
    prevPage.setAttribute('disabled', true);
  } else {
    prevPage.removeAttribute('disabled');
  }

  const items = document.querySelectorAll('.pager-item');
  for (var x = 0; x < items.length; x++) {
    if (x === +table.dataset.currentpage) {
      items[x].classList.add('selected');
    } else {
      items[x].classList.remove('selected');
    }
  }
}

Here's the full working example. https://jsfiddle.net/aloshea/r68gtvmc/