Demo

Interactive Data Grid

This demo showcases the power of LemonadeJS data-grid plugin to create fully reactive, editable tables with built-in features like search, pagination, and real-time data binding.


live
<html>
<script src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/data-grid/dist/index.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/data-grid/dist/style.min.css" />

<div id="root"></div>

<script>
function DataGridDemo() {
    const self = this;

    // Sample data with more fields
    self.data = [
        { id: 1, name: "John Doe", email: "[email protected]", role: "Developer", department: "Engineering", salary: "$95,000", status: "Active", joined: "2022-03-15" },
        { id: 2, name: "Jane Smith", email: "[email protected]", role: "Designer", department: "Design", salary: "$85,000", status: "Active", joined: "2021-08-22" },
        { id: 3, name: "Bob Johnson", email: "[email protected]", role: "Manager", department: "Operations", salary: "$105,000", status: "Inactive", joined: "2020-01-10" },
        { id: 4, name: "Alice Williams", email: "[email protected]", role: "Developer", department: "Engineering", salary: "$92,000", status: "Active", joined: "2023-05-18" },
        { id: 5, name: "Charlie Brown", email: "[email protected]", role: "QA Engineer", department: "Quality", salary: "$78,000", status: "Active", joined: "2022-11-05" },
        { id: 6, name: "Diana Prince", email: "[email protected]", role: "Product Owner", department: "Product", salary: "$110,000", status: "Active", joined: "2021-02-14" },
        { id: 7, name: "Eve Martinez", email: "[email protected]", role: "Developer", department: "Engineering", salary: "$88,000", status: "Inactive", joined: "2023-09-30" },
        { id: 8, name: "Frank Castle", email: "[email protected]", role: "DevOps", department: "Engineering", salary: "$98,000", status: "Active", joined: "2022-07-12" },
        { id: 9, name: "Grace Lee", email: "[email protected]", role: "Designer", department: "Design", salary: "$82,000", status: "Active", joined: "2023-01-20" },
        { id: 10, name: "Henry Ford", email: "[email protected]", role: "Manager", department: "Sales", salary: "$115,000", status: "Active", joined: "2020-06-08" },
    ];

    // Enhanced grid configuration with custom rendering
    self.columns = [
        {
            name: 'id',
            title: 'ID',
            width: '60px',
            align: 'center'
        },
        {
            name: 'name',
            title: 'Name',
            width: '150px',
            align: 'center',
            render: function(value) {
                return '<strong>' + value + '</strong>';
            }
        },
        {
            name: 'email',
            title: 'Email',
            width: '200px',
            align: 'center'
        },
        {
            name: 'role',
            title: 'Role',
            width: '130px',
            align: 'center'
        },
        {
            name: 'department',
            title: 'Department',
            width: '120px',
            align: 'center'
        },
        {
            name: 'salary',
            title: 'Salary',
            width: '100px',
            align: 'center'
        },
        {
            name: 'status',
            title: 'Status',
            width: '100px',
            align: 'center',
            render: function(value) {
                const color = value === 'Active' ? '#22c55e' : '#ef4444';
                return '<span style="color: ' + color + '; font-weight: 600;">' + value + '</span>';
            }
        },
        {
            name: 'joined',
            title: 'Joined Date',
            width: '110px',
            align: 'center'
        }
    ];

    self.gridRef = null;
    self.updateTrigger = 0;

    self.onUpdate = function(instance, cell, x, y, value) {
        // Force reactivity by updating trigger
        self.updateTrigger++;
    };

    self.addEmployee = function() {
        const newId = self.data.length + 1;
        self.data = [...self.data, {
            id: newId,
            name: "New Employee",
            email: "[email protected]",
            role: "Developer",
            department: "Engineering",
            salary: "$80,000",
            status: "Active",
            joined: new Date().toISOString().split('T')[0]
        }];
        self.updateTrigger++;
    };

    self.removeSelected = function() {
        if (self.data.length > 0) {
            self.data = self.data.slice(0, -1);
            self.updateTrigger++;
        }
    };

    self.getActiveCount = function() {
        return self.data.filter(emp => emp.status === 'Active').length;
    };

    return `<div style="padding: 20px;">
        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
            <h3 style="margin: 0;">Employee Management System</h3>
            <div style="display: flex; gap: 10px;">
                <button onclick="self.addEmployee()" class="button primary">Add Employee</button>
                <button onclick="self.removeSelected()" class="button">Remove Last</button>
            </div>
        </div>
        <p style="margin: 0 0 16px 0; font-size: 13px; color: #64748b;"><em>💡 Tip: Double-click any cell to edit. Try changing the Status to "Active" or "Inactive"</em></p>

        <DataGrid
            :ref="self.gridRef"
            :data="self.data"
            :columns="self.columns"
            search="true"
            pagination="5"
            editable="true"
            resizable="true"
            :onupdate="self.onUpdate" />

        <div style="margin-top: 25px; padding: 20px; background: #f8fafc; border-radius: 8px; display: flex; gap: 30px;">
            <div>
                <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b;">Total Employees</h4>
                <p style="margin: 0; font-size: 24px; font-weight: 700; color: #1e293b;">{{self.updateTrigger >= 0 ? self.data.length : 0}}</p>
            </div>
            <div>
                <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b;">Active Employees</h4>
                <p style="margin: 0; font-size: 24px; font-weight: 700; color: #22c55e;">{{self.updateTrigger >= 0 ? self.getActiveCount() : 0}}</p>
            </div>
            <div>
                <h4 style="margin: 0 0 8px 0; font-size: 14px; color: #64748b;">Inactive Employees</h4>
                <p style="margin: 0; font-size: 24px; font-weight: 700; color: #ef4444;">{{self.updateTrigger >= 0 ? (self.data.length - self.getActiveCount()) : 0}}</p>
            </div>
        </div>
    </div>`;
}

lemonade.render(DataGridDemo, document.getElementById('root'));
</script>
</html>