Documentation

Grid.js Integration

Grid.js Integration

UltraViolet Pro includes Grid.js, a powerful and lightweight table library that provides advanced data grid functionality with sorting, filtering, pagination, and more.

Overview

Grid.js is a framework-agnostic table library built with TypeScript. It offers:

  • Lightweight: Minimal bundle size with maximum functionality
  • Framework Agnostic: Works with any JavaScript framework or vanilla JS
  • TypeScript Support: Built with TypeScript for better development experience
  • Extensible: Plugin system for custom functionality
  • Responsive: Mobile-friendly design out of the box

Basic Usage

HTML Setup

<!-- Include Grid.js -->
<script src="https://cdn.jsdelivr.net/npm/gridjs@6.0.6/dist/gridjs.umd.js"></script>
<link href="https://cdn.jsdelivr.net/npm/gridjs@6.0.6/dist/mermaid.min.css" rel="stylesheet" />

<!-- Create container -->
<div id="wrapper"></div>

JavaScript Initialization

const grid = new gridjs.Grid({
  columns: ["Name", "Email", "Phone Number", "Position"],
  data: [
    ["John", "john@example.com", "(353) 01 222 3333", "Software Engineer"],
    ["Mark", "mark@gmail.com", "(01) 22 888 4444", "Data Scientist"],
    ["Eoin", "eoin@gmail.com", "0097 22 654 00033", "Web Developer"]
  ]
}).render(document.getElementById("wrapper"));

Advanced Configuration

With Search and Pagination

const grid = new gridjs.Grid({
  columns: ["Name", "Email", "Phone Number", "Position"],
  data: [
    ["John", "john@example.com", "(353) 01 222 3333", "Software Engineer"],
    ["Mark", "mark@gmail.com", "(01) 22 888 4444", "Data Scientist"],
    ["Eoin", "eoin@gmail.com", "0097 22 654 00033", "Web Developer"]
  ],
  search: true,
  pagination: {
    limit: 5
  },
  sort: true,
  resizable: true,
  fixedHeader: true,
  height: '400px'
}).render(document.getElementById("wrapper"));

Custom Cell Renderers

const grid = new gridjs.Grid({
  columns: [
    "Name",
    "Email", 
    "Status",
    {
      name: "Actions",
      formatter: (cell, row) => {
        return gridjs.html(`
          <button class="btn btn-sm btn-primary me-2" onclick="editUser(${row.cells[0].data})">Edit</button>
          <button class="btn btn-sm btn-danger" onclick="deleteUser(${row.cells[0].data})">Delete</button>
        `);
      }
    }
  ],
  data: [
    ["John", "john@example.com", "Active"],
    ["Mark", "mark@gmail.com", "Inactive"],
    ["Eoin", "eoin@gmail.com", "Active"]
  ]
}).render(document.getElementById("wrapper"));

Server-Side Data

const grid = new gridjs.Grid({
  columns: ["Name", "Email", "Position"],
  server: {
    url: '/api/users',
    then: data => data.users,
    total: data => data.total
  },
  search: {
    server: {
      url: (prev, keyword) => `${prev}?search=${keyword}`
    }
  },
  pagination: {
    server: {
      url: (prev, page, limit) => `${prev}?page=${page}&limit=${limit}`
    }
  }
}).render(document.getElementById("wrapper"));

Styling and Theming

Custom CSS Classes

const grid = new gridjs.Grid({
  columns: ["Name", "Email", "Position"],
  data: [
    ["John", "john@example.com", "Software Engineer"],
    ["Mark", "mark@gmail.com", "Data Scientist"]
  ],
  className: {
    table: 'table table-striped table-bordered',
    thead: 'table-dark',
    tbody: 'table-hover'
  }
}).render(document.getElementById("wrapper"));

Bootstrap Integration

const grid = new gridjs.Grid({
  columns: ["Name", "Email", "Position"],
  data: [
    ["John", "john@example.com", "Software Engineer"],
    ["Mark", "mark@gmail.com", "Data Scientist"]
  ],
  className: {
    container: 'table-responsive',
    table: 'table table-striped table-bordered',
    thead: 'table-dark',
    tbody: 'table-hover',
    th: 'text-center',
    td: 'text-center'
  },
  style: {
    container: 'margin-top: 20px;',
    table: 'margin-bottom: 0;'
  }
}).render(document.getElementById("wrapper"));

Export Functionality

CSV Export

const grid = new gridjs.Grid({
  columns: ["Name", "Email", "Position"],
  data: [
    ["John", "john@example.com", "Software Engineer"],
    ["Mark", "mark@gmail.com", "Data Scientist"]
  ],
  plugins: [gridjs.plugin.excel()]
}).render(document.getElementById("wrapper"));

Custom Export Button

<button id="exportBtn" class="btn btn-success">Export to CSV</button>
<div id="wrapper"></div>
const grid = new gridjs.Grid({
  columns: ["Name", "Email", "Position"],
  data: [
    ["John", "john@example.com", "Software Engineer"],
    ["Mark", "mark@gmail.com", "Data Scientist"]
  ]
}).render(document.getElementById("wrapper"));

document.getElementById("exportBtn").addEventListener("click", () => {
  grid.export("csv", "users.csv");
});

Event Handling

Row Click Events

const grid = new gridjs.Grid({
  columns: ["Name", "Email", "Position"],
  data: [
    ["John", "john@example.com", "Software Engineer"],
    ["Mark", "mark@gmail.com", "Data Scientist"]
  ],
  onRowClick: (row) => {
    console.log("Row clicked:", row);
    // Handle row click
  }
}).render(document.getElementById("wrapper"));

Cell Click Events

const grid = new gridjs.Grid({
  columns: [
    "Name",
    "Email",
    {
      name: "Position",
      formatter: (cell) => {
        return gridjs.html(`<span class="clickable-cell">${cell}</span>`);
      }
    }
  ],
  data: [
    ["John", "john@example.com", "Software Engineer"],
    ["Mark", "mark@gmail.com", "Data Scientist"]
  ]
}).render(document.getElementById("wrapper"));

// Add click listener after render
document.addEventListener("click", (e) => {
  if (e.target.classList.contains("clickable-cell")) {
    console.log("Cell clicked:", e.target.textContent);
  }
});

Integration with Laravel

Controller Method

class UserController extends Controller
{
    public function index(Request $request)
    {
        $query = User::query();

        // Handle search
        if ($request->has('search')) {
            $search = $request->get('search');
            $query->where(function($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhere('position', 'like', "%{$search}%");
            });
        }

        // Handle pagination
        $page = $request->get('page', 1);
        $limit = $request->get('limit', 10);
        $offset = ($page - 1) * $limit;

        $users = $query->offset($offset)->limit($limit)->get();
        $total = $query->count();

        return response()->json([
            'users' => $users,
            'total' => $total
        ]);
    }
}

Frontend Integration

const grid = new gridjs.Grid({
  columns: ["Name", "Email", "Position"],
  server: {
    url: '/api/users',
    then: data => data.users.map(user => [user.name, user.email, user.position]),
    total: data => data.total
  },
  search: {
    server: {
      url: (prev, keyword) => `${prev}?search=${keyword}`
    }
  },
  pagination: {
    server: {
      url: (prev, page, limit) => `${prev}?page=${page}&limit=${limit}`
    }
  }
}).render(document.getElementById("wrapper"));

Best Practices

  1. Performance: Use server-side processing for large datasets
  2. Responsive Design: Always wrap Grid.js in responsive containers
  3. Accessibility: Include proper ARIA labels and keyboard navigation
  4. Error Handling: Implement proper error handling for server requests
  5. Loading States: Show loading indicators during data fetching
  6. Memory Management: Destroy grid instances when components are unmounted

Troubleshooting

Common Issues

  1. Styling Conflicts: Ensure Bootstrap CSS is loaded before Grid.js CSS
  2. JavaScript Errors: Check browser console for initialization errors
  3. Data Loading: Verify API endpoints return data in expected format
  4. Search Issues: Ensure search parameters are properly handled on server-side

Debug Mode

const grid = new gridjs.Grid({
  columns: ["Name", "Email", "Position"],
  data: [
    ["John", "john@example.com", "Software Engineer"]
  ],
  debug: true // Enable debug mode
}).render(document.getElementById("wrapper"));

Examples in UltraViolet

Grid.js is used in several places throughout UltraViolet:

  • Tables Overview: Demonstrates basic Grid.js functionality
  • JS Grid Page: Advanced examples with custom renderers
  • User Management: Server-side data with search and pagination
  • Reports: Export functionality for data tables

For more examples, check the resources/views/admin/tables/ directory.