DEV Community

Cover image for Here's How I implement cursor-based pagination in jQuery Datatable.
Shiva Aryal
Shiva Aryal

Posted on

Here's How I implement cursor-based pagination in jQuery Datatable.

When working with large datasets in web applications, pagination is crucial for performance and user experience. Standard offset-based pagination, commonly used with data tables, can be inefficient for large datasets.

Cursor-based pagination offers a more performant alternative, especially when handling real-time updates or large data loads. In this article, I’ll walk you through how I implement cursor-based pagination in a jQuery DataTable.

Steps to Implement Cursor-Based Pagination in jQuery DataTable

1.Setting Up the Environment
Before diving into the pagination logic, make sure you have the following:

i. jQuery
ii. DataTables plugin
iii. Backend API (or database) that supports cursor-based pagination

2.Configuring the Backend API
Cursor-based pagination relies heavily on the backend to return the necessary data. Let’s assume we’re working with a REST API that returns a JSON response, including:

Data: An array of records
Cursor: A unique identifier, such as id or timestamp, indicating the current position in the dataset.

Here’s an example of a paginated response from the server:

{
  "data": [
    {"id": 101, "name": "John Doe", "email": "john@example.com"},
    {"id": 102, "name": "Jane Smith", "email": "jane@example.com"}
  ],
  "pagination": {
     "next_cursor": "eyJpZCI6MTgsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0",
        "prev_cursor": "eyJpZCI6MTAsIl9wb2ludHNUb05leHRJdGVtcyI6ZmFsc2V9"
   }
}
Enter fullscreen mode Exit fullscreen mode

3.jQuery DataTable Initialization
The DataTable is initialized using jQuery and linked with the backend API. Here’s a basic structure:

var ajaxurl = "your-ajax-url";

var oTable = jQuery("#product_list_tbl").DataTable({
  preDrawCallback: function (settings) {
    var dt = jQuery("#product_list_tbl").DataTable();
    var settings = dt.settings();
    if (settings[0].jqXHR) {
      settings[0].jqXHR.abort();
    }
  },
  pagingType: 'simple',
  pageLength: 9,
  serverMethod: "post",
  ajax: {
    url: ajaxurl + "?action=search_ids",
    data: function (d) {
      d.search_id = jQuery("#search_id").val();
      // other params
    }
  },
});
Enter fullscreen mode Exit fullscreen mode

4.Customize Pagination controls

var ajaxurl = "your-ajax-url";

var oTable = jQuery("#product_list_tbl").DataTable({
  preDrawCallback: function (settings) {
    var dt = jQuery("#product_list_tbl").DataTable();
    var settings = dt.settings();
    if (settings[0].jqXHR) {
      settings[0].jqXHR.abort();
    }
  },
  pagingType: 'simple',
  pageLength: 9,
  serverMethod: "post",
  ajax: {
    url: ajaxurl + "?action=search_ids",
    data: function (d) {
      d.cursor = jQuery("#product_list_tbl").data('current-cursor') || '';
      d.search_id = jQuery("#search_id").val();
      // other params
    }
  },
  drawCallback: function (json) {

    const pagination = json.json.pagination;

    if (pagination.next_cursor) {
      jQuery(document).find('.paginate_button.next').removeClass('disabled');
      jQuery(document).find('.paginate_button.next').attr('data-cursor', json.json.pagination.next_cursor ?? '' );
    } else {
      jQuery(document).find('.paginate_button.next').addClass('disabled');
    }

    if (pagination.prev_cursor) {
      jQuery(document).find('.paginate_button.previous').removeClass('disabled');
      jQuery(document).find('.paginate_button.previous').attr('data-cursor', json.json.pagination.prev_cursor ?? '' );
    } else {
      jQuery(document).find('.paginate_button.previous').addClass('disabled');
    }

  },
});

 // Custom click handlers for pagination buttons
  jQuery(document).on('click', '#product_list_tbl_paginate .paginate_button', function(e) {
    e.preventDefault();
    e.stopPropagation(); // Prevent event from bubbling up

    // Only proceed if this is actually a 'next' or 'previous' button
    if (!jQuery(this).hasClass('next') && !jQuery(this).hasClass('previous')) {
      return;
    }

    var cursor = jQuery(this).attr('data-cursor');

    // Set the cursor directly on the table element
    jQuery("#product_list_tbl").data('current-cursor', cursor);

    // Reload the table with the new cursor
    oTable.ajax.reload();
  });

  // Disable default DataTables click handlers for pagination
  jQuery(document).off('click.DT', '#product_list_tbl_paginate .paginate_button');
Enter fullscreen mode Exit fullscreen mode

5.Handling API and Frontend Sync
Each time a user clicks on the Next or Previous button, the cursor is updated and sent to the backend. The backend fetches the records from the database, starting from the current cursor position, and returns the appropriate dataset to the DataTable.

Here's gist: Click Here

Conclusion
Cursor-based pagination is a practical and efficient approach when working with large datasets or real-time applications. By implementing cursor-based pagination in jQuery DataTable, you enhance performance, improve user experience, and ensure accurate data handling. This technique is particularly useful for modern applications that demand fast, scalable, and reliable data management.

I hope this guide helps you implement cursor-based pagination in your own projects. Happy coding!

Top comments (0)