Make jQuery pagination/sorting work with multiple tables on the same page

I have put together some pagination and sorting scripts which work perfectly the problem is they wont work if there are multiple HTML tables on the same page which both need sorting and paging individually.

I have considered just copying and pasting the code and changing the classes but I thought that it may slow down the page, I need this to work with 2 maybe 3 different tables on the same page.

At the moment the sorting method rips both of the tables rows and compiles them into one table? I was just wondering if I should just duplicate the jQuery and change the classes and ID's or is there a smarter way to handle this problem.

https://jsfiddle.net/51Le6o06/5/

HTML

<input type="checkbox" id="filter-free"> Free Handset

<table id="internalActivities">
  <thead>
    <tr>
      <th>head1</th>
      <th>head2</th>
      <th>head3</th>
      <th>head4</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="handsetcost">?364.00 upfront</span>
        <br><span class="amount">?10.10 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="free">No upfront cost</span>
        <br><span class="amount">?40.40 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="free">No upfront cost</span>
        <br><span class="amount">?30.30 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="free">No upfront cost</span>
        <br><span class="amount">?16.04 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="handsetcost">?134.00 upfront</span>
        <br><span class="amount">?12.19 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="handsetcost">?120.00 upfront</span>
        <br><span class="amount">?14.22 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="free">No upfront cost</span>
        <br><span class="amount">?50.22 per month</span></td>
    </tr>
    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="free">No upfront cost</span>
        <br><span class="amount">?10.33 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="free">No upfront cost</span>
        <br><span class="amount">?40.45 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="handsetcost">?200.00 upfront</span>
        <br><span class="amount">?30.84 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="free">No upfront cost</span>
        <br><span class="amount">?16.14 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="free">No upfront cost</span>
        <br><span class="amount">?12.10 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="free">No upfront cost</span>
        <br><span class="amount">?14.02 per month</span></td>
    </tr>

    <tr>
      <td>data</td>
      <td>data</td>
      <td>data</td>
      <td><span class="free">No upfront cost</span>
        <br><span class="amount">?50.88 per month</span></td>
    </tr>
  </tbody>
</table>

<input type="button" id="seeMoreRecords" value="More">
<input type="button" id="seeLessRecords" value="Less">
<br>
<input type="checkbox" id="filter-free"> Free Handset
<table id="internalActivities">
  <thead>
    <tr>
      <th>head1</th>
      <th>head2</th>
      <th>head3</th>
      <th>head4</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="handsetcost">?364.00 upfront</span>
        <br><span class="amount">?10.10 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="free">no upfront cost-b</span>
        <br><span class="amount">?40.40 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="free">no upfront cost-b</span>
        <br><span class="amount">?30.30 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="free">no upfront cost-b</span>
        <br><span class="amount">?16.04 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="handsetcost">?134.00 upfront</span>
        <br><span class="amount">?12.19 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="handsetcost">?120.00 upfront</span>
        <br><span class="amount">?14.22 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="free">no upfront cost-b</span>
        <br><span class="amount">?50.22 per month-b</span></td>
    </tr>
    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="free">no upfront cost-b</span>
        <br><span class="amount">?10.33 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="free">no upfront cost-b</span>
        <br><span class="amount">?40.45 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="handsetcost">?200.00 upfront</span>
        <br><span class="amount">?30.84 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="free">no upfront cost-b</span>
        <br><span class="amount">?16.14 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="free">no upfront cost-b</span>
        <br><span class="amount">?12.10 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="free">no upfront cost-b</span>
        <br><span class="amount">?14.02 per month-b</span></td>
    </tr>

    <tr>
      <td>data-b</td>
      <td>data-b</td>
      <td>data-b</td>
      <td><span class="free">no upfront cost-b</span>
        <br><span class="amount">?50.88 per month-b</span></td>
    </tr>
  </tbody>
</table>
<input type="button" id="seeMoreRecords" value="More">
<input type="button" id="seeLessRecords" value="Less">

jQuery

jQuery(document).ready(function($) {
  var dataRows = [];

  //Create an array of all rows with its value (this assumes that the amount is always a number.  You should add error checking!!  Also assumes that all rows are data rows, and that there are no header rows.  Adjust selector appropriately.
  $('#internalActivities > tbody > tr').each(function(i, j) {
    dataRows.push({
      'amount': parseFloat($(this).find('.amount').text().replace(/?/, "")),
      'row': $(this)
    });
  })

  //Sort the data smallest to largest
  dataRows.sort(function(a, b) {
    return a.amount - b.amount;
  });

  //Remove existing table rows.  This assumes that everything should be deleted, adjust selector if needed :).
  $('#internalActivities > tbody').empty();

  //Add rows back to table in the correct order.
  dataRows.forEach(function(ele) {
    $('#internalActivities > tbody').append(ele.row);
  })
});

jQuery(document).ready(function($) {

  var trs = $("#internalActivities tbody tr");
  var btnMore = $("#seeMoreRecords");
  var btnLess = $("#seeLessRecords");
  var trsLength = trs.length;
  var currentIndex = 3,
    page = 3;

  trs.hide();
  trs.slice(0, currentIndex).show();
  checkButton();

  btnMore.click(function(e) {
    e.preventDefault();
    trs.slice(currentIndex, currentIndex + page).show();
    currentIndex += page;
    checkButton();
  });

  btnLess.click(function(e) {
    e.preventDefault();
    trs.slice(currentIndex - page, currentIndex).hide();
    currentIndex -= page;
    checkButton();
  });

  function checkButton() {
    var currentLength = trs.filter("tr:visible").length;

    if (currentLength >= trsLength) {
      btnMore.hide();
    } else {
      btnMore.show();
    }

    if (trsLength > page && currentLength > page) {
      btnLess.show();
    } else {
      btnLess.hide();
    }

  }
  $('#filter-free').change(function() {
    var $all = $("#internalActivities tbody tr").hide();
    trs = this.checked ? $all.has('.free') : $all;
    trsLength = trs.length;
    trs.slice(0, page).show();
    currentIndex = page;
  });
  $('#filter-free').click(function() {
    $('#seeLessRecords').hide();
  });
});

Answers 1

  • You should wrap your code in a function and adjust selectors. For example, you can create new jQuery method this way:

    jQuery.fn.extend({
        sortPaging: function() {
            return this.each(function() {
                var container = $(this);
                /* Your code for this table... */
            })
        }
    });
    

    Adjusted for your needs, look below:

    jQuery.fn.extend({
        sortPaging: function() {
            return this.each(function() {
    			var container = $(this);
                var dataRows = [];
    
                /**
    			 * Create an array of all rows with its value (this assumes that the amount is always a number.
    			 * You should add error checking!!
    			 * Also assumes that all rows are data rows, and that there are no header rows. Adjust selector appropriately.
    			 */
                container.find('.internalActivities > tbody > tr').each(function(i, j) {
                    dataRows.push({
                        'amount': parseFloat($(this).find('.amount').text().replace(/?/, "")),
                        'row': $(this)
                    });
                })
    
                //Sort the data smallest to largest
                dataRows.sort(function(a, b) {
                    return a.amount - b.amount;
                });
    
                //Remove existing table rows.  This assumes that everything should be deleted, adjust selector if needed :).
                container.find('.internalActivities > tbody').empty();
    
                //Add rows back to table in the correct order.
                dataRows.forEach(function(ele) {
                    container.find('.internalActivities > tbody').append(ele.row);
                })
    
    
                var trs = container.find(".internalActivities tbody tr");
                var btnMore = container.find(".seeMoreRecords");
                var btnLess = container.find(".seeLessRecords");
                var trsLength = trs.length;
                var currentIndex = 3,
                    page = 3;
    
                trs.hide();
                trs.slice(0, currentIndex).show();
                checkButton();
    
                btnMore.click(function(e) {
                    e.preventDefault();
                    trs.slice(currentIndex, currentIndex + page).show();
                    currentIndex += page;
                    checkButton();
                });
    
                btnLess.click(function(e) {
                    e.preventDefault();
                    trs.slice(currentIndex - page, currentIndex).hide();
                    currentIndex -= page;
                    checkButton();
                });
    
                function checkButton() {
                    var currentLength = trs.filter("tr:visible").length;
    
                    if (currentLength >= trsLength) {
                        btnMore.hide();
                    } else {
                        btnMore.show();
                    }
    
                    if (trsLength > page && currentLength > page) {
                        btnLess.show();
                    } else {
                        btnLess.hide();
                    }
    
                }
                container.find('.filter-free').change(function() {
                    var $all = container.find(".internalActivities tbody tr").hide();
                    trs = this.checked ? $all.has('.free') : $all;
                    trsLength = trs.length;
                    trs.slice(0, page).show();
                    currentIndex = page;
                });
                container.find('.filter-free').click(function() {
                    container.find('.seeLessRecords').hide();
                });
            })
        }
    });
    
    $('.sort_paging').sortPaging();
    table,
    tr,
    td {
        border: 1px solid black;
        padding: 8px;
    }
    
    h1 {
        font-size: 18px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <h1>Table sorting on page load with paging</h1>
    
    <div class="sort_paging">
    
        <p>
            <input type="checkbox" class="filter-free" /> Free Handset
        </p>
    
        <table class="internalActivities">
            <thead>
                <tr>
                    <th>head1</th>
                    <th>head2</th>
                    <th>head3</th>
                    <th>head4</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="handsetcost">?364.00 upfront</span>
                        <br><span class="amount">?10.10 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="free">No upfront cost</span>
                        <br><span class="amount">?40.40 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="free">No upfront cost</span>
                        <br><span class="amount">?30.30 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="free">No upfront cost</span>
                        <br><span class="amount">?16.04 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="handsetcost">?134.00 upfront</span>
                        <br><span class="amount">?12.19 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="handsetcost">?120.00 upfront</span>
                        <br><span class="amount">?14.22 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="free">No upfront cost</span>
                        <br><span class="amount">?50.22 per month</span></td>
                </tr>
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="free">No upfront cost</span>
                        <br><span class="amount">?10.33 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="free">No upfront cost</span>
                        <br><span class="amount">?40.45 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="handsetcost">?200.00 upfront</span>
                        <br><span class="amount">?30.84 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="free">No upfront cost</span>
                        <br><span class="amount">?16.14 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="free">No upfront cost</span>
                        <br><span class="amount">?12.10 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="free">No upfront cost</span>
                        <br><span class="amount">?14.02 per month</span></td>
                </tr>
    
                <tr>
                    <td>data</td>
                    <td>data</td>
                    <td>data</td>
                    <td><span class="free">No upfront cost</span>
                        <br><span class="amount">?50.88 per month</span></td>
                </tr>
            </tbody>
        </table>
    
        <input type="button" class="seeMoreRecords" value="More">
        <input type="button" class="seeLessRecords" value="Less"&g                                                                    

Related Articles