JavaScript/jQuery Pagination - Getting Started

NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.

Pagination is a UI component that allows users to navigate through pages and change page size at runtime.

This tutorial explains how to add Pagination to a page and configure the component's core settings. It also covers implementing remote pagination. Colored cards are loaded each time a user switches pages or changes page size. The final result is displayed below:

Each section in this tutorial describes a single configuration step. You can also find the full source code in the following GitHub repository:

View on GitHub

Create Pagination

Add DevExtreme to your jQuery application and use the following code to create a Pagination component:

index.js
index.html
  • $(function() {
  • $("#pagination").dxPagination({ });
  • });
  • <html>
  • <head>
  • <!-- ... -->
  • <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
  • <link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/24.2.5/css/dx.light.css">
  • <script type="text/javascript" src="https://cdn3.devexpress.com/jslib/24.2.5/js/dx.all.js"></script>
  • <script type="text/javascript" src="index.js"></script>
  • </head>
  • <body>
  • <div id="pagination"></div>
  • </body>
  • </html>

Configure Pagination

This tutorial step guides you through the basic Pagination setup.

Specify the following settings:

  • itemCount sets the total number of items. Pagination does not function properly without this setting.
  • pageIndex sets the initial page to display. This tutorial sets pageIndex to 3 (the default value is 1).
  • allowedPageSizes specifies page sizes available to users. Modify this list as needed. Include 'all' to allow users to display all items on one page. This tutorial uses the default value: [5, 10].
  • pageSize specifies the initial page size.

The following code snippet demonstrates how to apply the aforementioned settings:

index.js
  • const total = 100;
  • $(() => {
  • const pagination = $('#pagination')
  • .dxPagination({
  • showInfo: true,
  • showNavigationButtons: true,
  • itemCount: total,
  • pageIndex: 3,
  • pageSize: 5,
  • })
  • .dxPagination('instance');
  • });

Implement Remote Pagination

This section explains how to implement remote pagination. Client code generates a color list and requests a remote service for cards representing color entries on the screen. The pagination component helps users browse the resulting color cards.

Implementation can be broken down into three steps:

  1. Generate 100 hex codes.
  2. Fetch color cards from The Color API service when necessary:
    • On page load
    • On page size changes
    • On page index changes
  3. Display color cards obtained from the service.

Implement the first step. Generate 100 random pastel hex codes and add them to an array:

index.js
  • const hexCodes = [];
  •  
  • const getRandomPastelColor = () => {
  • const hue = Math.floor(Math.random() * 360);
  • const saturation = Math.random() * 0.4 + 0.2;
  • const brightness = Math.random() * 0.3 + 0.7;
  • return hsvToHex(hue, saturation, brightness);
  • };
  •  
  • const hsvToHex = (h, s, v) => {
  • let r = 0;
  • let g = 0;
  • let b = 0;
  • const i = Math.floor(h / 60);
  • const f = h / 60 - i;
  • const p = v * (1 - s);
  • const q = v * (1 - f * s);
  • const t = v * (1 - (1 - f) * s);
  • switch (i % 6) {
  • case 0: r = v; g = t; b = p; break;
  • case 1: r = q; g = v; b = p; break;
  • case 2: r = p; g = v; b = t; break;
  • case 3: r = p; g = q; b = v; break;
  • case 4: r = t; g = p; b = v; break;
  • case 5: r = v; g = p; b = q; break;
  • }
  • const toHex = (x) => {
  • const hex = Math.round(x * 255).toString(16);
  • return hex.length === 1 ? `0${hex}` : hex;
  • };
  • return toHex(r) + toHex(g) + toHex(b);
  • };
  • $(() => {
  • for (let i = 0; i < total; i += 1) {
  • hexCodes.push(getRandomPastelColor());
  • }
  •  
  • const pagination = $('#pagination')
  • .dxPagination({
  • // ...
  • })
  • .dxPagination('instance');
  • });

Fetch Data

The following code snippet demonstrates how to fetch data from the Color API:

index.js
  • // ...
  • const apiEndpoint = 'https://www.thecolorapi.com/id?hex=';
  • const cache = new Map();
  •  
  • function fetchData(colorId) {
  • return new Promise((resolve, reject) => {
  • if (cache.has(colorId)) {
  • resolve(cache.get(colorId));
  • } else {
  • $.getJSON(apiEndpoint + colorId, (data) => {
  • const colorData = {
  • image: data.image.bare,
  • name: data.name.value,
  • };
  • cache.set(colorId, colorData);
  • resolve(colorData);
  • }).fail(() => {
  • reject(new Error(`Error loading color for hex: ${colorId}`));
  • });
  • }
  • });
  • }
  •  
  • $(() => {
  • // ...
  • const pagination = $('#pagination')
  • .dxPagination({
  • // ...
  • })
  • .dxPagination('instance');
  • });

Render Items

The render function determines the subset of cards to be displayed and populates the array with images and alt strings.

index.html
index.js
index.css
  • <html>
  • <head>
  • <!-- ... -->
  • </head>
  • <body>
  • <div id="pagination"></div>
  • <div id="cards"></div>
  • </body>
  • </html>
  • const renderCards = async (pageSize, pageIndex) => {
  • $('#cards').empty();
  • const startIndex = (pageIndex - 1) * pageSize;
  • const endIndex = pageIndex * pageSize;
  •  
  • const hexSubset = hexCodes.slice(startIndex, endIndex);
  • const promises = hexSubset.map((hex) => fetchData(hex));
  • try {
  • const pageColors = await Promise.all(promises);
  • pageColors.forEach((color) => {
  • const image = $('<img>').attr({
  • src: color.image,
  • alt: color.name,
  • });
  • $('#cards').append(image);
  • });
  • } catch (error) {
  • console.error('Error rendering cards:', error);
  • }
  • };
  •  
  • $(() => {
  • const pagination = $('#pagination')
  • .dxPagination({
  • // ...
  • })
  • .dxPagination('instance');
  •  
  • const pageSize = pagination.option('pageSize');
  • const pageIndex = pagination.option('pageIndex');
  • renderCards(pageSize, pageIndex);
  • });
  • #cards {
  • display: flex;
  • justify-content: center;
  • flex-wrap: wrap;
  • }

Handle Page Size and Index Changes

The render function is called on every page index/size change:

index.js
  • // ...
  •  
  • $(() => {
  • const pagination = $('#pagination')
  • .dxPagination({
  • // ...
  • onOptionChanged: (e) => {
  • if (e.name === 'pageSize' || e.name === 'pageIndex') {
  • const pageIndex = pagination.option('pageIndex');
  • const pageSize = pagination.option('pageSize');
  • renderCards(pageSize, pageIndex);
  • }
  • },
  • })
  • .dxPagination('instance');
  • // ...
  • });

Integrate LoadPanel

The following code integrate a load panel into the application. The panel appears when the app requests card data from the remote service. This step is optional.

To integrate the DevExtreme LoadPanel component:

  1. Add a LoadPanel to the code.
  2. Display it before calling the render function.
  3. Hide it after render.
index.html
index.js
  • <html>
  • <head>
  • <!-- ... -->
  • </head>
  • <body>
  • <div id="pagination"></div>
  • <div id="cards"></div>
  • <div id="load-panel"></div>
  • </body>
  • </html>
  • $(() => {
  • const loadPanel = $('#load-panel')
  • .dxLoadPanel({
  • position: {
  • my: 'top',
  • at: 'top',
  • of: '#cards',
  • },
  • visible: false,
  • showIndicator: true,
  • showPane: true,
  • hideOnOutsideClick: false,
  • })
  • .dxLoadPanel('instance');
  •  
  • const pagination = $('#pagination')
  • .dxPagination({
  • // ...
  • onOptionChanged: (e) => {
  • if (e.name === 'pageSize' || e.name === 'pageIndex') {
  • const pageIndex = pagination.option('pageIndex');
  • const pageSize = pagination.option('pageSize');
  • loadPanel.show();
  • renderCards(pageSize, pageIndex).finally(() => loadPanel.hide());
  • }
  • },
  • })
  • .dxPagination('instance');
  • // ...
  • loadPanel.show();
  • renderCards(pageSize, pageIndex).finally(() => loadPanel.hide());
  • });