jQuery Paging is a small, callback-driven pagination library. It calculates page ranges and navigation states but deliberately leaves the markup, content loading, and visual design to the application. The same core can therefore paginate an in-memory list, drive an Ajax endpoint, render page links, or control a table without imposing a fixed DOM structure.
Its compact format language controls which navigation elements are calculated. An onFormat callback turns each calculated element into application-specific HTML, while onSelect receives the exact slice bounds for the selected page. This separation is the useful part of the design: pagination arithmetic stays in one place, and presentation remains under local control.
Pagination Workbench
Change the data size, page width, overlap, or format string. The list shows the half-open slice selected by the plugin, and the navigation itself is generated through onFormat.
Installation and Basic Use
Load jQuery first and then the browser build:
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="jquery.paging.min.js"></script> Calling paging(number, options) on one or more containers creates the navigation and returns a controller. The plugin does not ship a required stylesheet or content template.
const pager = $('#pagination').paging(1337, {
format: '[< nncnn! >]',
perpage: 10,
page: 1,
onSelect: function (page) {
console.log(page, this.slice);
return false;
},
onFormat: formatPage
}); The Range Calculation
Let N be the number of items, P the number per page, and L the overlap between consecutive pages, with 0 <= L < P. The effective step is P - L. jQuery Paging computes the number of pages as follows:
pages = 1 + Math.ceil((N - P) / (P - L)); For one-based page p, the callback receives a JavaScript-compatible half-open interval [start, end):
start = (p - 1) * (P - L);
end = Math.min(start + P, N); The bounds can be passed directly to Array.prototype.slice(). If P = 10 and L = 2, the first slices are [0, 10), [8, 18), and [16, 26). The plugin reduces an overlap greater than or equal to the page width to P - 1, preventing a zero step.
Format Language
The format string controls which element types are sent to onFormat. Whitespace and other unknown characters are ignored; they are useful only for making the format readable.
| Token | Callback type and meaning |
|---|---|
| n and c | A page-number block. Its width is the token length; c fixes the current page's preferred position. |
| * | A block containing every page. |
| < and > | prev and next controls. |
| [ and ] | first and last controls. |
| q and p | left and right page shortcuts outside the central block. |
| - and . | Application-defined fill and leap elements. |
| (...) | A visibility group: its members are active or inactive together. |
| ! | After a number block, preserves its full width with inactive positions near the ends. |
For example, [< (q-) nncnn! (-p) >] requests first, previous, one left shortcut, a separator, five central page positions, a right separator and shortcut, next, and last. Formatting remains entirely in the callback.
Formatting Callback
onFormat(type) runs once per calculated navigation element. Its this object always includes number, lapping, pages, perpage, page, and slice. Depending on the token, it also provides value, pos, active, first, and last.
function formatPage(type) {
if (type === 'block') {
if (!this.active) return '<span>' + this.value + '</span>';
if (this.value === this.page) {
return '<span aria-current="page">' + this.value + '</span>';
}
return '<a href="#page-' + this.value + '">' + this.value + '</a>';
}
if (type === 'prev' || type === 'next') {
const label = type === 'prev' ? 'Previous' : 'Next';
return this.active
? '<a href="#page-' + this.value + '">' + label + '</a>'
: '<span>' + label + '</span>';
}
return '';
} Returned strings are inserted with jQuery's html(). Treat the callback as an HTML-producing boundary: escape or reject untrusted labels instead of interpolating user-controlled strings directly.
Selection Callback
onSelect(page) runs after initialization and after a page change. Its context contains number, lapping, pages, and slice. Returning true allows the clicked link's destination to be followed; returning false keeps navigation inside the callback.
let previous = [0, 0];
const rows = $('.result-row');
function selectPage(page) {
rows.slice(previous[0], previous[1]).hide();
rows.slice(this.slice[0], this.slice[1]).show();
previous = this.slice;
return false;
} An Ajax-backed implementation can use the same precomputed bounds without duplicating pagination arithmetic:
function selectPage(page) {
$.ajax({
url: '/records',
data: {
start: this.slice[0],
end: this.slice[1],
page: page
},
success: renderRows
});
return false;
} Options
| Option | Purpose |
|---|---|
| perpage | Items in one page; values below 1 fall back to 10. |
| lapping | Items shared by consecutive slices; defaults to 0. |
| page | Initial page. Negative values count from the end; null postpones initial selection. |
| format | Token string that defines the calculated navigation structure. |
| stepwidth | Pages moved by previous and next. Zero selects block-wise movement. |
| circular | Wraps previous and next around finite page ranges. |
| lock | Disables page changes and calls onSelect with page 0 when invoked. |
| refresh | Object with url and interval in seconds for periodic data checks. |
| onFormat | Produces HTML for each calculated navigation element. |
| onSelect | Consumes the selected page and slice bounds. |
| onClick | Replaces the built-in click handling; the application must call setPage(). |
| onRefresh | Receives data returned by the periodic refresh request. |
Controller Methods
setPage(page), setNumber(number), and setOptions(options) all return the controller, so updates can be chained. Calling setPage() without an argument redraws the configured page. A negative item count creates an endless paginator: there is no known last page, first/last behavior changes accordingly, and an all-pages * block is not meaningful.
pager
.setOptions({ perpage: 25, circular: true })
.setNumber(845)
.setPage(1); The browser build uses the classic jQuery plugin API and is compatible with the jQuery 3.6.4 runtime loaded by this page. Applications targeting a different jQuery major version should run their own integration tests, especially if they use the optional refresh path.