NOTE!:

* If you have a different JSON format and need help with the processing code, please ask the question on StackOverflow or message me directly (gmail; wowmotty). Please don't open an issue for help with code.

Demo

First Prev 1 to 25 (80) Next Last
ID
Name
Country Code
District
Population
ID Name Country Code District Population
First Prev 1 to 25 (80) Next Last
1KabulAFGKabol1780000
2QandaharAFGQandahar237500
3HeratAFGHerat186800
4Mazar-e-SharifAFGBalkh127800
5AmsterdamNLDNoord-Holland731200
6RotterdamNLDZuid-Holland593321
7HaagNLDZuid-Holland440900
8UtrechtNLDUtrecht234323
9EindhovenNLDNoord-Brabant201843
10TilburgNLDNoord-Brabant193238
11GroningenNLDGroningen172701
12BredaNLDNoord-Brabant160398
13ApeldoornNLDGelderland153491
14NijmegenNLDGelderland152463
15EnschedeNLDOverijssel149544
16HaarlemNLDNoord-Holland148772
17AlmereNLDFlevoland142465
18ArnhemNLDGelderland138020
19ZaanstadNLDNoord-Holland135621
20´s-HertogenboschNLDNoord-Brabant129170
21AmersfoortNLDUtrecht126270
22MaastrichtNLDLimburg122087
23DordrechtNLDZuid-Holland119811
24LeidenNLDZuid-Holland117196
25HaarlemmermeerNLDNoord-Holland110722

Javascript

$(function(){

  // Initialize tablesorter
  // ***********************
  $("table")
    .tablesorter({
      theme: 'blue',
      widthFixed: true,
      sortLocaleCompare: true, // needed for accented characters in the data
      widgets: ['zebra']
    })

    // initialize the pager plugin
    // ****************************
    .tablesorterPager({

      // **********************************
      //  Description of ALL pager options
      // **********************************

      // target the pager markup - see the HTML block below
      container: $(".pager"),

      // use this format: "http:/mydatabase.com?page={page}&size={size}&{sortList:col}"
      // where {page} is replaced by the page number, {size} is replaced by the number of records to show,
      // {sortList:col} adds the sortList to the url into a "col" array, and {filterList:fcol} adds
      // the filterList to the url into an "fcol" array.
      // So a sortList = [[2,0],[3,0]] becomes "&col[2]=0&col[3]=0" in the url
      // and a filterList = [[2,Blue],[3,13]] becomes "&fcol[2]=Blue&fcol[3]=13" in the url
      ajaxUrl : 'assets/City{page}.json',

      // process ajax so that the following information is returned:
      // [ total_rows (number), rows (array of arrays), headers (array; optional) ]
      // example:
      // [
      //   100,  // total rows
      //   [
      //     [ "row1cell1", "row1cell2", ... "row1cellN" ],
      //     [ "row2cell1", "row2cell2", ... "row2cellN" ],
      //     ...
      //     [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
      //   ],
      //   [ "header1", "header2", ... "headerN" ] // optional
      // ]
      ajaxProcessing: function(data){
        if (data && data.hasOwnProperty('rows')) {
          var r, row, c, d = data.rows,
          // total number of rows (required)
          total = data.total_rows,
          // array of header names (optional)
          headers = data.cols,
          // all rows: array of arrays; each internal array has the table cell data for that row
          rows = [],
          // len should match pager set size (c.size)
          len = d.length;
          // this will depend on how the json is set up - see City0.json
          // rows
          for ( r=0; r < len; r++ ) {
            row = []; // new row array
            // cells
            for ( c in d[r] ) {
              if (typeof(c) === "string") {
                row.push(d[r][c]); // add each table cell data to row array
              }
            }
            rows.push(row); // add new row array to rows array
          }
          return [ total, rows, headers ];
        }
      },

      // output string - default is '{page}/{totalPages}'; possible variables: {page}, {totalPages}, {startRow}, {endRow} and {totalRows}
      output: '{startRow} to {endRow} ({totalRows})',

      // apply disabled classname to the pager arrows when the rows at either extreme is visible - default is true
      updateArrows: true,

      // starting page of the pager (zero based index)
      page: 0,

      // Number of visible rows - default is 10
      size: 25,

      // if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
      // table row set to a height to compensate; default is false
      fixedHeight: false,

      // remove rows from the table to speed up the sort of large tables.
      // setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
      removeRows: false,

      // css class names of pager arrows
      cssNext        : '.next',  // next page arrow
      cssPrev        : '.prev',  // previous page arrow
      cssFirst       : '.first', // go to first page arrow
      cssLast        : '.last',  // go to last page arrow
      cssPageDisplay : '.pagedisplay', // location of where the "output" is displayed
      cssPageSize    : '.pagesize', // page size selector - select dropdown that sets the "size" option
      cssErrorRow    : 'tablesorter-errorRow', // error information row

      // class added to arrows when at the extremes (i.e. prev/first arrows are "disabled" when on the first page)
      cssDisabled    : 'disabled' // Note there is no period "." in front of this class name

    });

});

CSS

/* pager wrapper, div */
.pager {
  padding: 5px;
}
/* pager wrapper, in thead/tfoot */
td.pager {
  background-color: #e6eeee;
}
/* pager navigation arrows */
.pager img {
  vertical-align: middle;
  margin-right: 2px;
}
/* pager output text */
.pager .pagedisplay {
  font-size: 11px;
  padding: 0 5px 0 5px;
  width: 50px;
  text-align: center;
}

/*** loading ajax indeterminate progress indicator ***/
#tablesorterPagerLoading {
  background: rgba(255,255,255,0.8) url(icons/loading.gif) center center no-repeat;
  position: absolute;
  z-index: 1000;
}

/*** css used when "updateArrows" option is true ***/
/* the pager itself gets a disabled class when the number of rows is less than the size */
.pager.disabled {
  display: none;
}
/* hide or fade out pager arrows when the first or last row is visible */
.pager img.disabled {
  /* visibility: hidden */
  opacity: 0.5;
  filter: alpha(opacity=50);
}

HTML

<table class="tablesorter">
  <thead>
    <tr>
      <td class="pager" colspan="5">
        <img src="../addons/pager/icons/first.png" class="first"/>
        <img src="../addons/pager/icons/prev.png" class="prev"/>
        <span class="pagedisplay"></span> <!-- this can be any element, including an input -->
        <img src="../addons/pager/icons/next.png" class="next"/>
        <img src="../addons/pager/icons/last.png" class="last"/>
        <select class="pagesize">
          <option value="25">25</option>
        </select>
      </td>
    </tr>
    <tr>
      <th>1</th> <!-- thead text will be updated from the JSON; make sure the number of columns matches the JSON data -->
      <th>2</th>
      <th>3</th>
      <th>4</th>
      <th>5</th>
    </tr>
  </thead>
  <tfoot>
    <tr>
      <th>1</th> <!-- tfoot text will be updated at the same time as the thead -->
      <th>2</th>
      <th>3</th>
      <th>4</th>
      <th>5</th>
    </tr>
    <tr>
      <td class="pager" colspan="5">
        <img src="../addons/pager/icons/first.png" class="first"/>
        <img src="../addons/pager/icons/prev.png" class="prev"/>
        <span class="pagedisplay"></span> <!-- this can be any element, including an input -->
        <img src="../addons/pager/icons/next.png" class="next"/>
        <img src="../addons/pager/icons/last.png" class="last"/>
        <select class="pagesize">
          <option value="25">25</option>
        </select>
      </td>
    </tr>
  </tfoot>
  <tbody> <!-- tbody will be loaded via JSON -->
  </tbody>
</table>

Next up: Pager plugin + filter widget ››