Pagination not updating number of pages on select change

I have a script that paginates pages in a table, which works fine. I also have a dropdown to select how many records to show in the table. Although this works, if I select say 20 records the pagination does not update to reflect the change.

When the table is run, the default records to show is 8 whih makes 9 pages. But if I select 20 in the drop down it still says 9 and if I go to page 9 it is obviously empty. I am also wondering if it is possible to have the script appear in both before and after the table. the reson for this is if a user gets to the bottom of say 100 records, then I would like this feature so they don't have to go all the way back to the top.

I would appreciate any help as my javascript is not 100%. Many thanks

php

<?php
    echo "<table class='paginated' cellspacing='0' cellpadding='0'>";
    echo "<div class='pager'></div>";
    echo "<thead><tr><th style='width: 5%;'>#</th><th>Service</th><th>Activity</th><th>Dept</th><th>Company</th><th>Address</th><th>User</th><th>Item</th><th>Date</th><th style='width: 19%;'>Action</th></tr></thead>";

    while($row = mysqli_fetch_array($result)){

    $id = $row['id'];
    $service = $row['service'];
    $activity = $row['activity'];
    $dept = $row['department'];
    $company = $row['company'];
    $address = $row['address'];
    $user = $row['user'];
    $box = $row['item'];
    $date = $row['date'];
    $date = date('d-m-Y h:i:s', strtotime($date));
    $edit = "<button type='button' class='btn btn-primary edit'>Edit</button>";
    $action = "<button type='button' class='btn btn-success action'>Action</button>";
    $delete = "<button type='button' class='btn btn-danger delete'>Delete</button>";

    // each looped row

    echo "<tr><td>".$id."</td><td>".$service."</td><td>".$activity."</td><td>".$dept."</td><td>".$company."</td><td>".$address."</td><td>".$user."</td><td>".$box."</td><td>".$date."</td><td>".$edit. ' ' .$action. ' ' .$delete."</td></tr>";

    } // End while loop
    echo "</table><br /><br /></div>";
?>

Open in new window


js

$('table.paginated').each(function() {
  var currentPage = 0;
  var numPerPage = 8;
  var $table = $(this);
  $table.bind('repaginate', function() {
    $table.find('tbody tr').hide().slice(currentPage * numPerPage, (currentPage + 1) * numPerPage).show();
  });
  $table.trigger('repaginate');
  var numRows = $table.find('tbody tr').length;
  var numPages = Math.ceil(numRows / numPerPage);
  var $pager = $('<div class="pager"></div>');
  for (var page = 0; page < numPages; page++) {
    $('<span class="page-number"></span>').text(page + 1).bind('click', {
      newPage: page
    }, function(event) {
      currentPage = event.data['newPage'];
      $table.trigger('repaginate');
      $(this).addClass('active').siblings().removeClass('active');
    }).appendTo($pager).addClass('clickable');
  }
  $pager.insertBefore($table).find('span.page-number:first').addClass('active');
  var $numberPicker = $('<div class="numberPicker"></div>');
  var dropdown = $('<select class="options"></select>');
  $([5, 10, 20]).each(function() {
    var $num = this;
    $('<option></option>').text(this).attr('value', this).appendTo(dropdown);
  });
  dropdown.bind('change', function() {
    numPerPage = this.value;
    $table.trigger('repaginate');
  }).insertBefore($table);
});

Open in new window

peter-cooperAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Julian HansenCommented:
Just for interest - why are you writing your own code rather than using a library like DataTables?

What you need to be doing is re-rendering the <div class="pager"> inside the repaginate() function

Keep your <div class="pager"> where it is but move the bit that renders the actual pages inside the repaginate() function.

Recommendation: In your PHP code consider using HEREDOC. You have a bunch of lines that do nothing but assign one variable to another just so you can use the second variable in the output - this makes no sense. Create a HEREDOC of HTML and simply use the row variables directly (inside { }).
peter-cooperAuthor Commented:
Hi Julian
The reason I am not using datatables i because it relies on bootstrap and if i use bootstrap it plays hell with my css coding. Would it be possible to mark up my code as per your recommendation as I need to learn and not quite sure how to code what you have suggested. Many thanks
peter-cooperAuthor Commented:
Julian
I have tried various ways to organise the code as per your comment. However, i just getting errors or nothing at all. Could you help with my code by way of an example please. Thanks
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

Julian HansenCommented:
Can you show me the code you have so far - with the changes.
peter-cooperAuthor Commented:
Hi Julian
Here you go. This is based on your comments. I have tried many ways and combinations, but no luck. Thanks

$(function() {
$('table.paginated').each(function() {
  var currentPage = 0;
  var numPerPage = 8;
  var $table = $(this);
  $table.bind('repaginate', function() {
    $table.find('tbody tr').hide().slice(currentPage * numPerPage, (currentPage + 1) * numPerPage).show();
    var $numberPicker = $('<div class="numberPicker"></div>');
  var dropdown = $('<select class="options"></select>');
  $([5, 10, 20]).each(function() {
    var $num = this;
    $('<option></option>').text(this).attr('value', this).appendTo(dropdown);
  });
  dropdown.bind('change', function() {
    numPerPage = this.value;
    $table.trigger('repaginate');
  }).insertAfter($table);
});
  });
  $table.trigger('repaginate');
  var numRows = $table.find('tbody tr').length;
  var numPages = Math.ceil(numRows / numPerPage);
  var $pager = $('<div class="pager"></div>');
  for (var page = 0; page < numPages; page++) {
    $('<span class="page-number"></span>').text(page + 1).bind('click', {
      newPage: page
    }, function(event) {
      currentPage = event.data['newPage'];
      $table.trigger('repaginate');
      $(this).addClass('active').siblings().removeClass('active');
    }).appendTo($pager).addClass('clickable');
  }
  $pager.insertBefore($table).find('span.page-number:first').addClass('active');
  
});

Open in new window

Julian HansenCommented:
I have re-engineered your code a bit
<script>
$(function() {
  
  $('table.paginated').each(function() {
    populateTable(this);
    var numPerPage = 5;
    var currentPage = 0;
    var $table = $(this);
    
    var $pager = $('<div class="pager"></div>');
    $pager.insertBefore($table);
    
    $table.bind('repaginate', function() {
      $table.find('tbody tr').hide().slice(currentPage * numPerPage, (currentPage + 1) * numPerPage).show();
      renderPager($table, $pager);
    });
    
    $table.trigger('repaginate');
    var $numberPicker = $('<div class="numberPicker"></div>');
    
    var dropdown = $('<select class="options"></select>');
    $([5, 10, 20]).each(function() {
      var $num = this;
      $('<option></option>').text(this).attr('value', this).appendTo(dropdown);
    });
    dropdown.bind('change', function() {
      numPerPage = this.value;
      $table.trigger('repaginate');
    }).insertBefore($table);

    function renderPager($table, $pager)
    {
      var numRows = $table.find('tbody tr').length;
      var numPages = Math.ceil(numRows / numPerPage);
      $pager.empty();
      var startPage = Math.max(currentPage-3, 0);
      var endPage = Math.min(startPage+6, numPages-1);
      $('<a>', {class: 'page-index'}).html('<<').data('page', 0).appendTo($pager);
      for (var page = startPage; page < endPage; page++) {
        var page_link = $('<a>', {class:'page-index'}).data('page', page);
        page_link.html(page + 1);
        page_link.appendTo($pager);
      }
     // Reset current page to start
     currentPage = 1;
      $('<a>', {class: 'page-index'}).html('>>').data('page', numPages-1).appendTo($pager);
    }
    
    $('.pager').on('click', '.page-index', function(event) {
      event.preventDefault();
      currentPage = $(this).data('page');
      $table.trigger('repaginate');
      $('.page_link').removeClass('active');
      $(this).addClass('active');
    })
  });
  
  function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
  }
  
  function randomContent(type)
  {
    var arbitary = ["John Smith", "fred@somewhere.com", "Apple", "Kangaroo", "Empire State Building", "Tesla", "The Sphynx", "Star Wars", "Microsoft Windows", "Granite", "Greece"];
    
    switch(type) {
      case 1: 
        return getRandomInt(-1000,1000);
      case 2:
        max = 1000;
        min = -1000;
        return (Math.random() * (max - min) + min).toFixed(2);
      default:
        var i = getRandomInt(0,10);
        return arbitary[i];
    }
  }
  
  function populateTable(table)
  {
    var type = [];
    var nRows = getRandomInt(100,500);
    console.log(nRows);
    var nCols = getRandomInt(5,10);
    for(var i = 0; i < nCols; i++) {
      type[i] = getRandomInt(1,5);
    }
    
    for(var r = 0; r < nRows; r++) {
      var row = table.insertRow()
      for(var c = 0; c < nCols; c++) {
        row.insertCell().innerHTML = randomContent(type[c]);
      }
    }
  }
});
</script>

Open in new window


You can see it working here

The above sample auto-generates content and the shows a pager that adapts to the number of items shown per page.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
peter-cooperAuthor Commented:
Julian
I have checked your working demo. But it dosen't update the number of pages to reflect the change. Unless I am missing something in your example. I am assuming the numebrs 1-6 should change on the dropdown change. Cheers
Julian HansenCommented:
You need to go to the end of the set - the generation code generates a lot more than 6 pages so you won't see it on the first page.

Open the page - click the go to end button (>>) and then change the drop down OR go to page 10.

I have it that it resets the table to page 1 when you change the drop down as well so after each change go to the last page to see that the number of pages has changed.
peter-cooperAuthor Commented:
OIC Thanks very much julian for all your help
peter-cooperAuthor Commented:
Thanks once again
Julian HansenCommented:
You are welcome.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.