CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tabulator-tables

Interactive table generation JavaScript library with sorting, filtering, editing, formatting, and extensive customization capabilities

Pending
Overview
Eval results
Files

pagination.mddocs/

Pagination

Built-in pagination system with configurable page sizes and navigation controls for managing large datasets efficiently.

Capabilities

Page Navigation

Methods for controlling current page position and navigation.

/**
 * Set current page number
 * @param page - Page number to navigate to (1-based)
 * @returns Promise resolving when page loads
 */
setPage(page: number): Promise<void>;

/**
 * Navigate to page containing specific row
 * @param row - Row index to find and navigate to
 * @returns Promise resolving when page loads
 */
setPageToRow(row: any): Promise<void>;

/**
 * Get current page number
 * @returns Current page number (1-based)
 */
getPage(): number;

/**
 * Get maximum page number
 * @returns Total number of pages
 */
getPageMax(): number;

/**
 * Navigate to previous page
 * @returns Promise resolving to true if navigation occurred, false if already at first page
 */
previousPage(): Promise<boolean>;

/**
 * Navigate to next page  
 * @returns Promise resolving to true if navigation occurred, false if already at last page
 */
nextPage(): Promise<boolean>;

Usage Examples:

// Basic page navigation
await table.setPage(3); // Go to page 3
console.log("Current page:", table.getPage());
console.log("Total pages:", table.getPageMax());

// Navigate by row
await table.setPageToRow(150); // Go to page containing row 150

// Sequential navigation
if (await table.nextPage()) {
  console.log("Moved to next page");
} else {
  console.log("Already at last page");
}

await table.previousPage();

Page Size Control

Configure and modify the number of rows displayed per page.

/**
 * Set number of rows per page
 * @param size - Number of rows per page
 */
setPageSize(size: number): void;

/**
 * Get current page size
 * @returns Number of rows per page
 */
getPageSize(): number;

Usage Examples:

// Change page size
table.setPageSize(50);
console.log("Rows per page:", table.getPageSize());

// Dynamic page size based on screen size
function adjustPageSize() {
  const screenHeight = window.innerHeight;
  const rowHeight = 35; // Approximate row height
  const headerHeight = 100; // Header and controls
  const maxRows = Math.floor((screenHeight - headerHeight) / rowHeight);
  
  table.setPageSize(Math.max(10, maxRows));
}

window.addEventListener("resize", adjustPageSize);
adjustPageSize();

Pagination Configuration

Basic Pagination Setup

Enable and configure pagination behavior during table initialization.

interface PaginationConfig {
  /** Enable pagination */
  pagination?: boolean | "local" | "remote";
  /** Pagination mode */
  paginationMode?: "local" | "remote";
  /** Default page size */
  paginationSize?: number;
  /** Show page size selector */
  paginationSizeSelector?: boolean | number[];
  /** Page size selector options */
  paginationSizeOptions?: number[];
  /** Custom pagination element */
  paginationElement?: string | HTMLElement;
  /** Add rows to current page or table */
  paginationAddRow?: "table" | "page";
  /** Number of page buttons to show */
  paginationButtonCount?: number;
  /** Initial page to display */
  paginationInitialPage?: number;
}

Usage Examples:

// Basic pagination setup
const paginatedTable = new Tabulator("#paginated-table", {
  data: largeDataset,
  columns: columnDefinitions,
  pagination: true,
  paginationMode: "local",
  paginationSize: 25,
  paginationSizeSelector: [10, 25, 50, 100],
  paginationButtonCount: 5
});

// Remote pagination for server-side data
const remotePaginatedTable = new Tabulator("#remote-table", {
  ajaxURL: "/api/data",
  pagination: "remote",
  paginationMode: "remote", 
  paginationSize: 20,
  paginationSizeSelector: true,
  ajaxParams: { version: "2.0" }
});

// Custom pagination element
const customPaginationTable = new Tabulator("#custom-pagination", {
  data: tableData,
  columns: columnDefinitions,
  pagination: true,
  paginationElement: "#custom-pagination-controls",
  paginationSize: 15
});

Advanced Pagination Options

interface AdvancedPaginationConfig {
  /** Counter element selector */
  paginationCounter?: string | HTMLElement | Function;
  /** Counter text template */
  paginationCounterElement?: string | HTMLElement;
  /** Data received callback for remote pagination */
  paginationDataReceived?: { [key: string]: string };
  /** Data sent callback for remote pagination */
  paginationDataSent?: { [key: string]: string };
  /** Show first/last page buttons */
  paginationFirstLastButtons?: boolean;
  /** Pagination info display */
  paginationInfo?: boolean | Function;
}

Remote Pagination

Server-side Pagination

Configure table to work with server-side pagination systems.

interface RemotePaginationConfig {
  /** Remote pagination mode */
  paginationMode: "remote";
  /** AJAX URL for data requests */
  ajaxURL: string;
  /** Parameters sent with pagination requests */
  paginationDataSent?: {
    page?: string;      // Page number parameter name (default: "page")
    size?: string;      // Page size parameter name (default: "size") 
    sorters?: string;   // Sorters parameter name (default: "sort")
    filters?: string;   // Filters parameter name (default: "filter")
  };
  /** Expected response data structure */
  paginationDataReceived?: {
    data?: string;        // Data array property (default: "data")
    last_page?: string;   // Total pages property (default: "last_page")
    total?: string;       // Total records property (default: "total")
  };
}

Usage Examples:

// Server-side pagination with custom parameters
const serverPaginatedTable = new Tabulator("#server-table", {
  ajaxURL: "/api/users",
  pagination: "remote",
  paginationMode: "remote",
  paginationSize: 20,
  paginationDataSent: {
    page: "pageNumber",
    size: "recordsPerPage", 
    sorters: "sortBy",
    filters: "filterBy"
  },
  paginationDataReceived: {
    data: "users",
    last_page: "totalPages",  
    total: "totalRecords"
  },
  ajaxResponse: function(url, params, response) {
    // Transform server response if needed
    return {
      data: response.users,
      last_page: response.totalPages,
      total: response.totalRecords
    };
  }
});

// Handle server errors
serverPaginatedTable.on("dataLoadError", function(error) {
  console.error("Pagination data load failed:", error);
  showErrorMessage("Failed to load data. Please try again.");
});

Pagination Events

Page Change Events

Events triggered during pagination operations.

interface PaginationEvents {
  /** Fired when page is loaded */
  "pageLoaded": (pageno: number) => void;
  /** Fired when page changes */
  "pageChanged": (pageno: number) => void;
}

Usage Examples:

// Page change event handling
table.on("pageChanged", function(pageno) {
  console.log(`Navigated to page ${pageno}`);
  
  // Update URL with current page
  const url = new URL(window.location);
  url.searchParams.set("page", pageno);
  window.history.replaceState({}, "", url);
  
  // Update page info display
  document.getElementById("current-page").textContent = pageno;
  document.getElementById("total-pages").textContent = table.getPageMax();
});

table.on("pageLoaded", function(pageno) {
  console.log(`Page ${pageno} data loaded`);
  
  // Scroll to top after page load
  table.getElement().scrollIntoView();
  
  // Update analytics
  if (window.gtag) {
    gtag("event", "page_view", {
      custom_map: { table_page: pageno }
    });
  }
});

Custom Pagination Controls

Building Custom Controls

Create custom pagination interfaces with full control over appearance and behavior.

// Custom pagination control example
class CustomPaginationControls {
  constructor(table) {
    this.table = table;
    this.container = document.getElementById("custom-pagination");
    this.createControls();
    this.bindEvents();
  }
  
  createControls() {
    this.container.innerHTML = `
      <div class="pagination-controls">
        <button id="first-page" class="btn">First</button>
        <button id="prev-page" class="btn">Previous</button>
        <span class="page-info">
          Page <input id="page-input" type="number" min="1" style="width: 60px;"> 
          of <span id="total-pages">0</span>
        </span>
        <button id="next-page" class="btn">Next</button>
        <button id="last-page" class="btn">Last</button>
        <select id="page-size-select">
          <option value="10">10 per page</option>
          <option value="25">25 per page</option>
          <option value="50">50 per page</option>
          <option value="100">100 per page</option>
        </select>
      </div>
      <div class="pagination-info">
        Showing <span id="start-record">0</span> to <span id="end-record">0</span> 
        of <span id="total-records">0</span> records
      </div>
    `;
  }
  
  bindEvents() {
    const firstBtn = document.getElementById("first-page");
    const prevBtn = document.getElementById("prev-page");
    const nextBtn = document.getElementById("next-page");
    const lastBtn = document.getElementById("last-page");
    const pageInput = document.getElementById("page-input");
    const pageSizeSelect = document.getElementById("page-size-select");
    
    firstBtn.addEventListener("click", () => this.table.setPage(1));
    prevBtn.addEventListener("click", () => this.table.previousPage());
    nextBtn.addEventListener("click", () => this.table.nextPage());
    lastBtn.addEventListener("click", () => this.table.setPage(this.table.getPageMax()));
    
    pageInput.addEventListener("change", (e) => {
      const page = parseInt(e.target.value);
      if (page >= 1 && page <= this.table.getPageMax()) {
        this.table.setPage(page);
      }
    });
    
    pageSizeSelect.addEventListener("change", (e) => {
      this.table.setPageSize(parseInt(e.target.value));
    });
    
    // Update controls when page changes
    this.table.on("pageChanged", () => this.updateControls());
    this.table.on("dataLoaded", () => this.updateControls());
  }
  
  updateControls() {
    const currentPage = this.table.getPage();
    const maxPage = this.table.getPageMax();
    const pageSize = this.table.getPageSize();
    const totalRecords = this.table.getDataCount();
    
    document.getElementById("page-input").value = currentPage;
    document.getElementById("total-pages").textContent = maxPage;
    document.getElementById("page-size-select").value = pageSize;
    
    const startRecord = ((currentPage - 1) * pageSize) + 1;
    const endRecord = Math.min(currentPage * pageSize, totalRecords);
    
    document.getElementById("start-record").textContent = startRecord;
    document.getElementById("end-record").textContent = endRecord;
    document.getElementById("total-records").textContent = totalRecords;
    
    // Enable/disable navigation buttons
    document.getElementById("first-page").disabled = currentPage === 1;
    document.getElementById("prev-page").disabled = currentPage === 1;
    document.getElementById("next-page").disabled = currentPage === maxPage;
    document.getElementById("last-page").disabled = currentPage === maxPage;
  }
}

// Initialize custom controls
const customControls = new CustomPaginationControls(table);

Performance Considerations

Optimizing Large Datasets

// Performance-optimized pagination setup
const optimizedTable = new Tabulator("#optimized-table", {
  data: veryLargeDataset,
  columns: columnDefinitions,
  
  // Essential for large datasets
  pagination: true,
  paginationMode: "local",
  paginationSize: 100,
  
  // Virtual DOM for rendering performance
  virtualDom: true,
  virtualDomBuffer: 200,
  
  // Reduce DOM manipulation
  layoutColumnsOnNewData: false,
  responsiveLayout: false,
  
  // Efficient data processing
  dataFiltered: function(filters, rows) {
    // Only process visible page data
    console.log(`Filtered to ${rows.length} rows`);
  }
});

// Memory management for very large datasets
function cleanupPagination() {
  // Clear unused page data from memory
  if (table.getDataCount() > 10000) {
    // Force garbage collection of filtered data
    table.redraw(true);
  }
}

// Clean up periodically
setInterval(cleanupPagination, 300000); // Every 5 minutes

Install with Tessl CLI

npx tessl i tessl/npm-tabulator-tables

docs

cell-editing.md

clipboard.md

column-management.md

data-management.md

data-sorting.md

data-trees.md

event-system.md

filtering-search.md

history-undo.md

import-export.md

index.md

pagination.md

range-selection.md

row-grouping.md

table-construction.md

validation.md

tile.json