# DataTables Integration Guide

Complete guide on integrating DataTables into the index pages generated by the CRUD Generator.

## Features

This DataTables integration provides the following features for index pages:

- ✅ **Server-side AJAX Loading** - Data is loaded via a dedicated API endpoint
- ✅ **Sorting** - Click a column header to sort the data
- ✅ **Searching** - Global search across all columns
- ✅ **Pagination** - Automatic pagination with an option to change the number of rows per page
- ✅ **Responsive Actions** - Edit, View, and Delete buttons with consistent styling
- ✅ **Dark Mode Support** - Compatible with the existing dark theme

## How It Works

### 1. API Endpoint

Every CRUD generator creates an API endpoint for the data list:

```
GET /route-name/data/list
```

Named route: `{route-name}.list`

This endpoint returns a JSON response:

```json
{
  "data": [
    {
      "id": 1,
      "name": "Item Name",
      "created_at": "2026-06-26 10:30:45",
      "actions": {
        "show": "/route-name/1",
        "edit": "/route-name/1/edit",
        "delete": "/route-name/1"
      }
    },
    ...
  ]
}
```

### 2. Frontend Implementation

The index view template uses DataTables.js with the following configuration:

- **Ajax**: Fetches data from the `/route-name/data/list` endpoint
- **Columns**: Configured to display ID, Name, Created At, and Actions
- **Pagination**: Default 10 rows per page (customizable)
- **Sorting**: Default sorting by ID descending

### 3. Delete Action

The delete button uses the fetch API with:
- CSRF token validation
- DELETE HTTP method
- Confirmation dialog before deleting
- Auto-reload of the page after success

## Customization

### Changing the Displayed Columns

Edit the file `resources/views/app/{route-name}/index.blade.php` and modify the `@push('scripts')` section:

```javascript
columns: [
    { data: 'id', title: '{{ __("ID") }}' },
    { data: 'name', title: '{{ __("Name") }}' },
    { data: 'created_at', title: '{{ __("Created") }}' },
    // Add a new column here
    { data: 'status', title: '{{ __("Status") }}' },
    {
        data: 'actions',
        title: '{{ __("Actions") }}',
        orderable: false,
        searchable: false,
        render: function(data) { ... }
    }
]
```

### Changing the Number of Rows per Page

```javascript
pageLength: 10  // Change to the desired value (25, 50, 100, etc.)
```

### Adding a Column to the API Endpoint

Edit the controller file `app/Http/Controllers/{Model}Controller.php`, method `list()`:

```php
public function list(Request $request)
{
    $items = $this->modelService->getAll();

    return response()->json([
        'data' => $items->map(fn($item) => [
            'id' => $item->id,
            'name' => $item->name ?? '',
            'status' => $item->status ?? '',  // Add here
            'created_at' => $item->created_at?->format('Y-m-d H:i:s') ?? '',
            'actions' => [
                'show' => route('route.show', $item->id),
                'edit' => route('route.edit', $item->id),
                'delete' => route('route.destroy', $item->id),
            ]
        ])->toArray()
    ]);
}
```

### Styling Actions

Edit the blade template to change the action button styling:

```blade
<div class="flex gap-2 justify-end">
    <a href="${data.show}" class="text-blue-600 hover:text-blue-900 text-sm font-medium">
        {{ __('View') }}
    </a>
    <a href="${data.edit}" class="text-amber-600 hover:text-amber-900 text-sm font-medium">
        {{ __('Edit') }}
    </a>
    <button onclick="deleteItem('${data.delete}')" class="text-red-600 hover:text-red-900 text-sm font-medium">
        {{ __('Delete') }}
    </button>
</div>
```

## Server-Side Pagination (Advanced)

For very large datasets, the implementation above uses client-side pagination. For server-side pagination:

### 1. Update the Controller

```php
public function list(Request $request)
{
    $perPage = $request->get('length', 10);
    $start = $request->get('start', 0);
    $page = ($start / $perPage) + 1;

    $items = $this->modelService->getAll();
    $paginated = $items->paginate($perPage, ['*'], 'page', $page);

    return response()->json([
        'draw' => $request->get('draw'),
        'recordsTotal' => $paginated->total(),
        'recordsFiltered' => $paginated->total(),
        'data' => $paginated->items()->map(fn($item) => [
            // ... data mapping
        ])->toArray()
    ]);
}
```

### 2. Update the JavaScript

```javascript
const dataTable = new DataTable('#ROUTENAME-table', {
    ajax: {
        url: '{{ route("ROUTENAME.list") }}',
        type: 'GET',
        dataSrc: 'data'
    },
    // ... columns config
    serverSide: true,  // Enable server-side processing
    processing: true
});
```

## Styling & Theming

### DataTables CSS Overrides

Add custom CSS inside `@push('styles')` to override the default styling:

```blade
@push('styles')
    <link rel="stylesheet" href="https://cdn.datatables.net/2.1.8/css/dataTables.dataTables.min.css">
    <style>
        /* Custom DataTables styling */
        .dataTable tbody tr:hover {
            background-color: rgba(0, 84, 198, 0.05);
        }
        
        .dataTable_wrapper .dataTable_length select {
            padding: 0.25rem 0.5rem;
            border-radius: 0.25rem;
        }
    </style>
@endpush
```

### Dark Mode

Styling already supports dark mode via the existing Tailwind classes in the template.

## Performance Considerations

1. **Large Datasets**: For datasets > 10K records, implement server-side pagination
2. **Caching**: Consider caching the API endpoint response
3. **Searching**: For large datasets, implement server-side searching with LIKE queries
4. **Indexing**: Make sure database columns that are frequently searched and sorted have an index

## Troubleshooting

### DataTables not loading

1. Check the browser console for errors
2. Make sure the API endpoint returns valid JSON
3. Verify that the CSRF token exists in the meta tag

### Delete not working

1. Check the CSRF token in the meta tag
2. Verify that the DELETE route endpoint exists
3. Make sure the DELETE method in the route is correct

### Data not showing in the table

1. Check the network tab in browser dev tools
2. Verify that the API response structure matches the columns config
3. Check for JavaScript errors in the console

## References

- [DataTables Official Docs](https://datatables.net/)
- [DataTables API Reference](https://datatables.net/reference/api/)
- [Laravel CSRF Protection](https://laravel.com/docs/13.x/csrf)
