Basic Usage

Get started with SkarGrid in just a few lines of code.

Quick Start: Initialize SkarGrid with your container ID and data array.

Simple Table

const grid = new Skargrid('table-basic', {
    data: users,
    columns: [
        { field: 'name', title: 'Name' },
        { field: 'email', title: 'Email' },                  
        { field: 'role', title: 'Role' }
    ]
});

Custom Rendering

Customize how data is displayed in table cells.

Rich Cell Rendering

columns: [
    { 
        field: 'status', 
        title: 'Status',
        render: (value) => {
            const colors = { active: 'success', inactive: 'danger' };
            return `<span class="badge bg-${colors[value]}">${value}</span>`;
        }
    }
]

Themes

Switch between light and dark themes.

Theme Demo

const grid = new Skargrid('table', {
    theme: 'dark' // or 'light'
});

// Toggle theme dynamically
grid.setTheme('dark');

Responsive Design

Tables that adapt to any screen size.

Responsive Table

new Skargrid('table', {
    data: users,
    responsive: true
});

Pagination

Handle large datasets with built-in pagination controls.

Paginated Table

new Skargrid('table', {
    pagination: true,
    pageSize: 10,
    pageSizeOptions: [10, 25, 50, 100]
});

Multi-Column Sorting

Sort data by one or multiple columns.

Sort Types: 📝 text (A-Z) • 🔢 number (0-9) • 📅 date (chronological)

Different Sort Types

columns: [
    { field: 'name', title: 'Name', sortType: 'text' },
    { field: 'age', title: 'Age', sortType: 'number' },
    { field: 'salary', title: 'Salary', sortType: 'number' },
    { field: 'joinDate', title: 'Join Date', sortType: 'date' }
],
sortable: true

Advanced Filtering

Filter data with multiple criteria.

Filter Types: 📝 text (partial match) • 📋 select (dropdown) • 🔢 number (>, <,=, !=) • 📅 date (before/after/between)

Multiple Filter Types

columns: [
    { field: 'name', filterable: true, filterType: 'text' },
    { 
        field: 'department', 
        filterable: true, 
        filterType: 'select',
        filterOptions: ['Engineering', 'Sales', 'HR']
    },
    { field: 'age', filterable: true, filterType: 'number' },
    { field: 'salary', filterable: true, filterType: 'number' },
    { field: 'joinDate', filterable: true, filterType: 'date' }
],
columnFilters: true

Global Search

Search across all columns instantly.

Searchable Table

new Skargrid('table', {
    searchable: true,
    columnFilters: true
});

Row Selection

Select single or multiple rows with checkboxes.

Selectable Rows

const grid = new Skargrid('table', {
    selectable: true
});

// Get selected rows
const selected = grid.getSelectedRows();

Column Configuration

Show, hide, and reorder columns. Configuration is persisted in localStorage.

Configurable Columns

new Skargrid('table', {
    data: users,
    columnConfig: true,
    persistColumnConfig: true
});

Data Export

Export data to CSV, JSON, or XLSX.

Exportable Table

new Skargrid('table', {
    exportCSV: true,
    exportXLSX: true
});

State Persistence

Automatically save and restore table state including pagination, sorting, filters, search, column config, and density.

💾 Auto-Saved to localStorage: Page size, current page, sort order, filter values, search term, column visibility/order, and density level. All changes persist across page reloads!

Persistent State Demo

Try these actions and reload the page - everything will be restored:
• Change page size or navigate pages
• Sort by any column
• Filter data by Department, Age, Salary
• Search for names or cities
• Hide/show/reorder columns (⚙️ Config)
• Change density (Row height in Config)

new Skargrid('table', {
    data: users,
    columns: [
        { field: 'name', title: 'Name', filterable: true, filterType: 'text' },
        { field: 'department', title: 'Department', filterable: true, filterType: 'select' },
        { field: 'age', title: 'Age', filterable: true, filterType: 'number' }
    ],
    // ✅ Enable persistence features
    persistColumnConfig: true,  // Saves: column visibility, order, density
    columnConfig: true,          // Enables column config UI
    columnFilters: true,         // Filters auto-persisted
    sortable: true,              // Sort state auto-persisted
    searchable: true,            // Search term auto-persisted
    pagination: true,            // Page size/number auto-persisted
    pageSize: 10,
    density: 'large'            // Initial density (persisted when changed)
});

// Clear persisted state programmatically
localStorage.removeItem('skargrid_table_config');
localStorage.removeItem('skargrid_table_state');

Row Grouping PRO

Organize data by grouping rows based on column values. Click group headers to expand/collapse.

Click department names to expand/collapse groups.

Grouped Table

Grouped by Department

const salesData = [
    { region: 'North', category: 'Electronics', product: 'Laptop', quantity: 10, price: 3500, revenue: 35000 },
    { region: 'North', category: 'Electronics', product: 'Mouse', quantity: 50, price: 89, revenue: 4450 },
    { region: 'North', category: 'Furniture', product: 'Desk', quantity: 8, price: 890, revenue: 7120 },
    { region: 'South', category: 'Electronics', product: 'Monitor', quantity: 15, price: 1200, revenue: 18000 },
    { region: 'South', category: 'Furniture', product: 'Chair', quantity: 12, price: 950, revenue: 11400 }
];

const grid = new Skargrid('table', {
    data: salesData,
    columns: [
        { field: 'region', title: 'Region', width: 150 },
        { field: 'category', title: 'Category', width: 150 },
        { field: 'product', title: 'Product', width: 220 },
        { 
            field: 'quantity', 
            title: 'Qty',
            width: 100,
            aggregations: [{ type: 'sum' }]  // Sum quantity per group
        },
        { 
            field: 'price', 
            title: 'Avg Price',
            width: 140,
            aggregations: [{ type: 'avg' }],
            render: (val) => `$${val.toFixed(2)}`
        },
        { 
            field: 'revenue', 
            title: 'Revenue',
            width: 150,
            aggregations: [{ type: 'sum' }],
            render: (val) => `$${val.toLocaleString()}`
        }
    ],
    
    // Enable Row Grouping
    rowGrouping: true,
    
    // Auto-group by region on load
    groupByColumns: ['region'],
    
    searchable: true,
    sortable: true,
    columnFilters: true,
    licenseKey: window.SKARGRID_LICENSE_KEY
});

// Dynamic grouping API:
grid.groupBy('region');                // Group by one column
grid.groupBy(['region', 'category']);  // Multi-level hierarchy
grid.ungroupAll();                     // Remove all grouping
grid.expandAllGroups();                // Expand all
grid.collapseAllGroups();              // Collapse all

Server-Side Processing PRO

Handle millions of records efficiently by processing data on the server.

Note: This demo simulates server-side processing. In production, sorting, filtering, and pagination requests would be sent to your backend API.

Server-Side Table

Total Records: 500 (Simulated API)

// Mock Server Endpoint (simulates backend)
async function mockServerEndpoint(params) {
    const { page, pageSize, search, sort, filters } = params;
    
    // 1. Filter by global search
    let filtered = fullDataset.filter(item => {
        if (!search) return true;
        const searchLower = search.toLowerCase();
        return (
            item.name.toLowerCase().includes(searchLower) ||
            item.email.toLowerCase().includes(searchLower)
        );
    });
    
    // 2. Filter by specific columns
    if (filters) {
        Object.entries(filters).forEach(([field, value]) => {
            if (value) {
                filtered = filtered.filter(item => item[field] === value);
            }
        });
    }
    
    // 3. Sort
    if (sort && sort.field) {
        filtered.sort((a, b) => {
            const aVal = a[sort.field];
            const bVal = b[sort.field];
            if (aVal < bVal) return sort.direction === 'asc' ? -1 : 1;
            if (aVal > bVal) return sort.direction === 'asc' ? 1 : -1;
            return 0;
        });
    }
    
    // 4. Paginate
    const start = (page - 1) * pageSize;
    const data = filtered.slice(start, start + pageSize);
    
    return { data, total: filtered.length };
}

// Intercept grid requests to use mock
const originalFetch = window.fetch;
window.fetch = async function(url, options) {
    if (url && url.includes('mock://server')) {
        const body = JSON.parse(options.body);
        const response = await mockServerEndpoint(body);
        return {
            ok: true,
            status: 200,
            json: async () => response
        };
    }
    return originalFetch.apply(this, arguments);
};

const grid = new Skargrid('table', {
    columns: [
        { field: 'id', title: 'ID', width: 80, sortable: true },
        { field: 'name', title: 'Name', width: 180, sortable: true },
        { field: 'email', title: 'Email', width: 220 },
        { 
            field: 'department', 
            title: 'Department', 
            width: 140,
            sortable: true,
            filterable: true,
            filterType: 'select'
        },
        { 
            field: 'city', 
            title: 'City', 
            width: 150,
            filterable: true,
            filterType: 'select'
        }
    ],
    
    serverSide: {
        url: 'mock://server',
        method: 'POST'
    },
    
    pagination: true,
    pageSize: 25,
    sortable: true,
    searchable: true,
    columnFilters: true,
    
    licenseKey: window.SKARGRID_LICENSE_KEY
});

Virtual Scrolling PRO

Render 10,000+ rows with smooth scrolling performance.

Performance: Only visible rows are rendered in the DOM. Scroll through 10,000 rows instantly!

Virtual Scroll Table

50,000 rows loaded - Scroll smoothly without lag!

// Generate 50,000 rows
function generateLargeDataset(count) {
    const data = [];
    const departments = ['IT', 'Sales', 'Marketing', 'HR', 'Finance'];
    const cities = ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix'];
    
    for (let i = 1; i <= count; i++) {
        data.push({
            id: i,
            name: `Employee ${i}`,
            email: `employee${i}@company.com`,
            department: departments[Math.floor(Math.random() * departments.length)],
            city: cities[Math.floor(Math.random() * cities.length)],
            salary: Math.floor(Math.random() * 10000) + 3000,
            hireDate: new Date(2020 + Math.floor(Math.random() * 5), 
                              Math.floor(Math.random() * 12), 
                              Math.floor(Math.random() * 28) + 1)
        });
    }
    return data;
}

const largeData = generateLargeDataset(50000);

const grid = new Skargrid('table', {
    data: largeData,
    columns: [
        { field: 'id', title: 'ID', width: 80, sortable: true },
        { field: 'name', title: 'Name', width: 200, sortable: true },
        { field: 'email', title: 'Email', width: 250 },
        { 
            field: 'department', 
            title: 'Department', 
            width: 150,
            sortable: true,
            filterable: true,
            filterType: 'select'
        },
        { 
            field: 'salary', 
            title: 'Salary', 
            width: 120,
            sortable: true,
            render: (val) => `$${val.toLocaleString()}`
        }
    ],
    
    // Virtual Scrolling enabled
    virtualization: true,
    virtualRowHeight: 42,      // Fixed row height
    virtualVisibleRows: 25,    // Visible rows
    virtualBufferSize: 10,     // Buffer for smooth scrolling
    
    // Other features work normally
    searchable: true,
    sortable: true,
    columnFilters: true,
    selectable: true,
    columnConfig: true,
    
    density: 'medium',
    licenseKey: window.SKARGRID_LICENSE_KEY
});

console.log(`✅ Grid with ${largeData.length.toLocaleString()} records loaded!`);

Skeleton Loader PRO

Show loading placeholders while data loads.

Loading Animation

const grid = new Skargrid('table', {
    skeletonLoader: true
});

// Trigger loading
grid.showLoading();
setTimeout(() => grid.hideLoading(), 2000);

Frozen Columns PRO

Keep important columns visible while scrolling.

Fixed Columns Demo

columns: [
    { field: 'id', title: 'ID', frozen: true, width: 80 },
    { field: 'name', title: 'Name', frozen: true, width: 150 },
    // ... other columns
]

Density Control PRO

Adjust table density (compact, normal, comfortable).

Density Settings

Click the gear icon (⚙️) in the table toolbar to adjust density.

new Skargrid('table', {
    columnConfig: true,
    density: 'medium', // small, medium, large, xlarge
    persistColumnConfig: true
});

Inline Editing PRO

Edit cells directly in the table.

Double-click any cell to edit. Press Enter to save or Esc to cancel.

Editable Table

columns: [
    { 
        field: 'name', 
        title: 'Name', 
        editable: true,
        validate: (value) => value.length > 0
    }
],
onCellEdit: (event) => {
    console.log('Cell edited:', event);
}

Undo/Redo PRO

Undo and redo changes to table data.

Shortcuts: Ctrl+Z (Undo) • Ctrl+Y or Ctrl+Shift+Z (Redo)

Undo/Redo Demo

Edit any cell below, then use Ctrl+Z to undo changes.

new Skargrid('table', {
    inlineEditing: true,
    undoRedo: true // Enabled by default with inline editing
});

Charts Integration PRO

Visualize your data with built-in charts. Instantly generate bar or line charts from your grid data, grouped by any field.

PRO Feature: Enable charts: true and configure chartOptions to display interactive charts above your table.

Sales by Product (Bar Chart)

const salesData = [
    { region: 'North', product: 'Laptop', quantity: 120, revenue: 42000 },
    { region: 'North', product: 'Mouse', quantity: 300, revenue: 9000 },
    { region: 'South', product: 'Monitor', quantity: 80, revenue: 32000 },
    { region: 'South', product: 'Chair', quantity: 150, revenue: 14250 },
    { region: 'East', product: 'Tablet', quantity: 60, revenue: 18000 },
    { region: 'West', product: 'Desk', quantity: 40, revenue: 16000 }
];

const grid = new Skargrid('table-charts-integration', {
    data: salesData,
    columnFilters: true,
    pagination: true,
    sortable: true,
    searchable: true,
    exportXLSX: true,
    columnConfig: true,
    columns: [
        { field: 'region', title: 'Region' },
        { field: 'product', title: 'Product' },
        { field: 'quantity', title: 'Quantity' },
        { field: 'revenue', title: 'Revenue' }
    ],
    charts: true, // Enable charts integration
    chartOptions: {
        target: 'table-charts-integration',
        position: 'top',
        fields: ['quantity'],
        groupBy: 'product',
        type: 'bar',
        colors: ['#667eea', '#764ba2', '#f093fb', '#f5576c', '#4facfe', '#00f2fe'],
        width: '100%', 
        height: '500',
        title: 'Example Sales by Product',
        animate: true,
        onClickMode: 'filter',    
        showControls: true
    },
    licenseKey: 'YOUR_LICENSE_KEY'
});

Products Catalog

E-commerce product listing with filters.

Features: Frozen columns for SKU/Name • Stock level indicators • Discount badges • Rating stars • Footer aggregates for analytics • Full export capabilities

Product Inventory Management

A complete product catalog with 25+ items. Try filtering by category, sorting by price, or searching for specific products.

new Skargrid('table', {
    data: products,
    columns: [
        { field: 'sku', title: 'SKU', frozen: true },
        { field: 'name', title: 'Product', frozen: true },
        { 
            field: 'price', 
            title: 'Price',
            render: (value, row) => {
                const discounted = row.discount > 0 
                    ? value * (1 - row.discount/100) 
                    : value;
                if (row.discount > 0) {
                    return `
                        $${value.toFixed(2)}
                        
                            $${discounted.toFixed(2)}
                        
                    `;
                }
                return `$${value.toFixed(2)}`;
            },
            footerAggregate: { type: 'avg' }
        }
    ],
    showFooter: true,
    exportCSV: true,
    exportXLSX: true,
    columnConfig: true,
    licenseKey: 'YOUR_LICENSE_KEY'
});

Sales Dashboard PRO

Real-time sales data with aggregates.

PRO Features: Revenue aggregates in footer • Inline editing for quick updates • Undo/Redo support • Status filters • Frozen order number column • Full data export

Sales Orders Dashboard

Track sales orders with automatic revenue calculations. Edit quantities or amounts inline, filter by region/status, and export reports.

new Skargrid('table-sales', {
    data: salesData,
    columns: [
        { field: 'id', title: 'Order #', frozen: true },
        { field: 'customer', title: 'Customer' },
        { 
            field: 'amount', 
            title: 'Amount',
            render: (value) => `$${value.toLocaleString()}`,
            footerAggregate: {
                type: 'sum',
                label: 'Total Revenue',
                format: (v) => `$${v.toLocaleString()}`
            }
        },
        { 
            field: 'status', 
            title: 'Status',
            filterable: true,
            filterType: 'select',
            render: (value) => {
                const colors = {
                    'Completed': 'success',
                    'Pending': 'warning',
                    'Shipped': 'info'
                };
                return `${value}`;
            }
        }
    ],
    showFooter: true,
    inlineEditing: true,
    undoRedo: true,
    exportCSV: true,
    exportXLSX: true,
    licenseKey: 'YOUR_LICENSE_KEY'
});

Employee Directory PRO

Complete employee management system.

Enterprise Features: Avatar rendering • Department filtering • Performance ratings with stars • Salary/age averages in footer • Inline profile editing • Column customization • Persistent user preferences

Company Employee Registry

Full employee management system with 15+ entries. Edit employee data inline, track performance metrics, analyze salary averages, and filter by department or location.

new Skargrid('table-employees', {
    data: employees,
    columns: [
        { 
            field: 'name', 
            title: 'Employee',
            frozen: true,
            render: (value, row) => `
                <div style="display: flex; gap: 0.5rem;">
                    <div style="width: 36px; height: 36px; 
                                border-radius: 50%; 
                                background: linear-gradient(135deg, 
                                #667eea 0%, #764ba2 100%); 
                                display: flex; 
                                align-items: center; 
                                justify-content: center; 
                                color: white; 
                                font-weight: bold;">
                        \${value.split(' ').map(n => n[0]).join('')}
                    </div>
                    <div>
                        <div style="font-weight: 600;">\${value}</div>
                        <div style="font-size: 0.8rem; color: #6c757d;">
                            \${row.position}
                        </div>
                    </div>
                </div>
            `,
            editable: true
        },
        { 
            field: 'salary', 
            title: 'Salary',
            render: (value) => `$\${value.toLocaleString()}`,
            editable: true,
            inputType: 'number',
            footerAggregate: {
                type: 'avg',
                label: 'Average',
                format: (v) => `$\${Math.round(v).toLocaleString()}`
            }
        },
        { 
            field: 'performance', 
            title: 'Performance',
            render: (value) => {
                const stars = '★'.repeat(Math.floor(value)) + 
                             '☆'.repeat(5 - Math.floor(value));
                return `<span>\${stars}</span> \${value.toFixed(1)}`;
            },
            footerAggregate: {
                type: 'avg',
                label: 'Avg',
                format: (v) => `\${v.toFixed(2)} ★`
            }
        }
    ],
    showFooter: true,
    inlineEditing: true,
    undoRedo: true,
    columnConfig: true,
    persistColumnConfig: true,
    exportCSV: true,
    exportXLSX: true,
    licenseKey: 'YOUR_LICENSE_KEY',
    onCellEdit: (event) => {
        console.log('Employee updated:', event);
        // API call to save changes
    }
});