Update pagination after ajax call

I have a pagination script that is working fine under normal events. ie with no ajax calls etc. What I am doing is performing a search and when the results are displayed, the pagination is not getting updated. What I need to happen is when the search is finished and the results displaye, is to update the numer of pages to reflect the results of the search. For example if there is 1 result only show 1 page. if there are 10 results then update the number of paes based on the results.

I would be grateful if someone could help with this. Many thanks

js code

$(function() {
  $('table.paginated').each(function() {
    var currentPage = 0;
    var numPerPage = 8;
    var $table = $(this);
    var numRows = $table.find('tbody tr').length;
    var numPages = Math.ceil(numRows / numPerPage);
    var $pager1 = $('<div class="pager"></div>');
    var $pager2 = "";
    var $numberPicker = $('<div class="numberPicker"></div>');
    var dropdown = $('<select class="options"></select>');
    var dropdown2 = "";
    $table.bind('repaginate', function() {
      $table.find('tbody tr').hide().slice(currentPage * numPerPage, (currentPage + 1) * numPerPage).show();
    });
    $table.trigger('repaginate');

    function rePage(numPages) {
      $('.page-number').remove();
      for (var page = 0; page < numPages; page++) {
        $('<span class="page-number"></span>').text(page + 1).bind('click', {
          newPage: page
        }, function(event) {
          var selected = $(this).index();
          var selected2 = ($(this).index()) + numPages;
          currentPage = event.data['newPage'];
          $table.trigger('repaginate');
          $('span.page-number').removeClass('active');
          $("span.page-number").each(function(index) {
            if (index === selected) {
              $(this).addClass('active');
              $("span.page-number:eq(" + selected2 + ")").addClass('active')
            }
          });
        }).appendTo($pager1).addClass('clickable');
      }
      $pager2 = $pager1.clone(true);
      $pager2.insertAfter($table);
    }
    rePage(numPages);
    $pager1.insertBefore($table);
    $pager2.insertAfter($table);
    $('span.page-number:first-child').addClass('active');
    $([5, numPerPage, 10, 20]).each(function() {
      var $num = this;
      $('<option></option>').text(this).attr('value', this).appendTo(dropdown);
    });
    dropdown.bind('change', function() {
      var oldNumPerPage = numPerPage;
      numPerPage = this.value;
      numPages = Math.ceil(numRows / numPerPage);
      $table.trigger('repaginate');
      rePage(numPages);
      currentPage = Math.ceil((currentPage * oldNumPerPage) / numPerPage);
      $("span.page-number:eq(" + currentPage + ")").trigger('click');
      $('.options').val(numPerPage);
      $('.options2').val(numPerPage);
    }).insertBefore($pager2);
    dropdown2 = dropdown.clone(true);
    dropdown2.addClass('options2');
    dropdown2.insertAfter($pager1);
    $('.options').val(numPerPage);
    $('.options2').val(numPerPage);
  });
});

button search js

$(function() {
  $('#btn-search').on('click', function(e) {
    e.preventDefault();
    var search = $("#search").val();
    $.ajax({
      url: "tabletestajax.php",
      method: 'POST',
      data: {
        search1: search
      },
      success: function(data) {
        $("#search").val('');
        $(".paginated tbody").empty();
        var result = $.trim(data);
        if (result === "enter a search term") {
          $("input[name='search']").val(result).css({
            'color': 'red'
          });
          return false;
        } else if (result === "No Results Found") {
          $(".paginated tbody").html('<div>' + result + '</div>');
          return false;
        } else {
          $(".paginated tbody").html(result);
        }
      }
    });
  });
});

Well step 1: Dont put a <div> inside a <tbody>.
Step 2: What result are you getting from tabletestajax.php? Is the table being filled correctly?
Step 3: You’ve defined functions to do the repaging, but havent actually called them in your search function. So… call them. Javascript wont trigger the functions unless you tell it to.

Hi
Thats where I am getting stuck. It fills the data correctly but need ro repaginate based on number of search results. Any pointers you could give to get me started i wwould be grateful as I am quite new to JS. Many thanks

you’ve already done it before…

Yes but not from an ajax call. It is what I would call a staic anon function. Do i have to name the function before calling. Thanks

You’ve already made the AJAX call. The success block of the ajax call is, itself, a static, anon (often called a Lambda), and synchronous-within-itself function. Async functions that are triggered by a post-load event (in this case, a button push), can reliably call functions in the global scope and assume that the elements required are in place (in fact, your function already makes that assumption by calling $(".paginated tbody").empty() and other such functions). The calls are the same, though you may need to do a new numPages calculation.

(EDIT: Emphasis added. You may need to move the function required into the global scope, rather than being inside a function declaration)

This is where I get lost. I was under the impression that my script was GLOBAL. But i need to give it a function name to call it from success and recalculate the number of pages. I have only been scripting for a short while, so much of what you are saying to me is alien. But I shall try to keep up. Thanks

As a general (simplified) rule:

When you open a <script> tag, you’re in the global scope. (in the case of an external JS file, just imagine the entire document is wrapped in an imaginary script tag)
As soon as you type the word ‘function’, you’re in a different (local) scope. This scope lasts until the ending } of that function.

The simple answer is, take your rePage function outside of every container, put it in the base level script tag. Then your ajax success function can reference it.

1 Like

So does that mean i have to give my function a name for reference. Thanks

Your function already has a name.

function **rePage**(numPages) {

I thought that was in the local scope. I thought that global had to be cretaed outside the function. I meant use something like $.fn.pagination = function () {}; so my function had a name.

I tried this but didn’t make any difference after search. still showing 6 pages.

$(".paginated tbody").html(result).removeClass('noResult');
rePage(numPages);

I was also looking at this further and do i have to update this code from main script.

var numRows = $table.find('tbody tr').length; 
and 
var numRows = data.length;

currently, rePage is in a local scope (it’s actually down 3 local scopes, because scopes nest, inheriting from parents).
Moving it to the global scope is as simple as copy and pasting it somewhere in the global scope (because of hoisting).
.fn.extend is a jquery method of adding things to the jQuery function set, but it’s not really necessary here (mostly because we wont be calling something like $(“tbody”).rePage(), though if you wanted to go into that complexity, you could. )

As far as rePage(numPages); not doing anything… you havent recalculated numPages. So it still thinks there’s the same number of pages, and recreates the same number of buttons.

I tried this and it is returnging the correct number of rows after search.

$(".paginated tbody").html(result).removeClass('noResult');
var numrows = $(".paginated").find('tbody tr').length;

So what would the calculation for numPages be?

I cannot see how to reference the rePage(numPages); function because it is local and not global. So i’m kinda stuck

See inline.

Sorry. I am confused as to what I am supposed to do with this code. What do i have to paste in and what do you mean by inline. Thanks

I mean look at the code block. I’ve commented what you need to copy, and where to paste it.