Browse Source

working on column search

ttreasure 4 tháng trước cách đây
mục cha
commit
9c642cfc40

+ 33 - 3
app/Http/Controllers/DataTablesController.php

@@ -60,6 +60,39 @@ class DataTablesController extends Controller
             }
         }
 
+        //Apply search filters
+
+
+        $searchTerms = $request->input('searchTerms', []                   );
+        $columnHeaders = json_decode($datatableConfig->column_headers, true);
+        $columnConfig = json_decode($datatableConfig->columns_config, true);
+
+        foreach ($searchTerms as $index => $value) {
+            $columnHeader = $columnHeaders[$index];
+            $config = $columnConfig[$index];
+            $columnName = $config['name'];
+            $searchType = $columnHeader['searchtype'];
+
+            if ($searchType === 'date' && is_array($value)) {
+                if (!empty($value['start'])) {
+                    $query->whereDate($columnName, '>=', $value[$index]['start']);
+                }
+                if (!empty($value['end'])) {
+                    $query->whereDate($columnName, '<=', $value[$index]['end']);
+                }
+            } elseif (!empty($value)) {
+                switch ($searchType) {
+                    case 'text':
+                        $query->where($columnName, 'like', '%' . $value[$index] . '%');
+                        break;
+                    case 'number':
+                        $query->where($columnName, '=', (int) $value[$index]);
+                        break;
+                }
+            }
+        }
+
+
         // Apply sorting
         $sorting = $request->order[0] ?? json_decode($datatableConfig->default_sorting, true)[0];
 
@@ -67,8 +100,5 @@ class DataTablesController extends Controller
 
         // Pass query to DataTables
         return DataTables::of($query)->make(true);
-
-
     }
-
 }

+ 6 - 0
app/Livewire/ShowReports.php

@@ -12,6 +12,7 @@ class ShowReports extends Component
     public $datatableName;
     public $datatableColumnsConfig;
     public $datatableHeadersConfig;
+    public array $searchTerms = [];
 
     public function mount($datatableName)
     {
@@ -29,7 +30,12 @@ class ShowReports extends Component
         $this->datatableColumnsConfig = json_decode($datatableConfigQuery->columns_config, true);
         $this->datatableHeadersConfig = json_decode($datatableConfigQuery->column_headers, true);
     }
+    public function updatedSearchTerms($value)
+    {
+
+        $this->dispatch('search-terms-updated', $this->searchTerms);
 
+    }
     public function render()
     {
 

+ 66 - 28
resources/js/datatables.js

@@ -18,40 +18,78 @@ import 'datatables.net-responsive-dt';
 window.$ = window.jQuery = $;
 window.JSZip = JSZip;
 // Initialize DataTable
-document.addEventListener('livewire:init', function () {
+let dataTableInstance;
+var livewireSearchTerms ={};
+function initializeDataTable() {
     var dataTableName = document.getElementById('datatable-config').dataset.datatableName;
     var dataTableColumnsConfig = JSON.parse(document.getElementById('datatable-config').dataset.datatableColumnsConfig);
-        $('#'+dataTableName+'-table').DataTable({
-
-            responsive: true,
-            processing: true,
-            serverSide: true,
-            orderCellsTop: true, // Allows inputs in the header
-            fixedHeader: true,   // Optional: keeps header fixed while scrolling
-            ajax: {
-                url: '/api/report-data/' + dataTableName, // Dynamically construct the URL with the datatable name
-                type: 'GET', // HTTP method
-            },
-            columns: dataTableColumnsConfig,
-            dom: 'lBfrtip', // DataTables layout controls
-            buttons: [
-                { extend: 'copyHtml5', className: 'dt-button' },
-                { extend: 'csvHtml5', className: 'dt-button' },
-                { extend: 'excelHtml5', className: 'dt-button' },
-                { extend: 'pdfHtml5', className: 'dt-button' },
-                { extend: 'print', className: 'dt-button' },
-            ],
-            layout: {
-                topStart: 'buttons' // Buttons positioned at the top-left
+    if ($.fn.DataTable.isDataTable(`#${dataTableName}-table`)) {
+        dataTableInstance.destroy();
+        $(`#${dataTableName}-table tbody`).empty(); // Clear rows to prevent residue
+    }
+
+    dataTableInstance = $(`#${dataTableName}-table`).DataTable({
+        responsive: true,
+        retrieve: true,
+        searching: false,
+        processing: true,
+        serverSide: true,
+        orderCellsTop: true,
+        fixedHeader: true,
+        ajax: {
+            url: '/api/report-data/' + dataTableName,
+            type: 'POST',
+            dataSrc: function (json) {
+                console.log('Returned rows:', json.data);
+                return json.data;
             },
-            columnDefs: [
-                { responsivePriority: 1, targets: 0 }, // Prioritize visibility of employee name
-                { responsivePriority: 2, targets: -1 } // Secondary priority for office location
-            ]
-        });
+            data: function (d) {
+                d.searchTerms = livewireSearchTerms || {};
+            }
+        },
+        columns: dataTableColumnsConfig,
+        dom: 'lBfrtip',
+        buttons: [
+            { extend: 'copyHtml5', className: 'dt-button' },
+            { extend: 'csvHtml5', className: 'dt-button' },
+            { extend: 'excelHtml5', className: 'dt-button' },
+            { extend: 'pdfHtml5', className: 'dt-button' },
+            { extend: 'print', className: 'dt-button' },
+        ],
+        layout: {
+            topStart: 'buttons'
+        },
+        columnDefs: [
+            { responsivePriority: 1, targets: 0 },
+            { responsivePriority: 2, targets: -1 }
+        ]
+    });
+}
+document.addEventListener('livewire:init', function () {
+
+    console.log('Initializing DataTable');
+
+
+
+    initializeDataTable();
+
+    Livewire.on('search-terms-updated', (searchTerms) => {
+
+        livewireSearchTerms = searchTerms || {};
+        setTimeout(() => {
+            initializeDataTable();
+        }, 50); // Slight delay gives Livewire time to patch DOM
+
+
+
 
     });
 
+    });
+
+
+
+
 
 
 document.addEventListener('DOMContentLoaded', () => {

+ 17 - 2
resources/views/livewire/show-reports.blade.php

@@ -14,8 +14,23 @@
         </tr>
 
         <tr>
-            @foreach($datatableHeadersConfig as $headerConfig)
-                <th wire:key="{{$headerConfig['header']}}" class="border border-gray-300 px-4 py-2"><input type="text" id="nameFilter" placeholder="Search Name" /></th>
+            @foreach($datatableHeadersConfig as $index=>$headerConfig)
+                <th wire:key="{{$headerConfig['header']}}" class="border border-gray-300 px-4 py-2">
+                @if($headerConfig['searchable'] === true)
+
+                    @switch($headerConfig['searchtype'])
+                        @case("text")
+                            <input type="text" id="{{$headerConfig['header']}}Filter"  wire:model.live.debounce.250ms="searchTerms.{{ $index }}" placeholder="{{$headerConfig['header']}} Search" />
+                            @break
+                        @case("date")
+                            <input type="date" id="{{$headerConfig['header']}}FilterStartDate" wire:model.live="searchTerms.{{ $index }}.start" placeholder="{{$headerConfig['header']}} Start Date" />
+                            -
+                            <input type="date" id="{{$headerConfig['header']}}FilterEndDate" wire:model.live="searchTerms.{{ $index }}.end" placeholder="{{$headerConfig['header']}} End Date" />
+                            @break
+                    @endswitch
+
+                @endif
+                </th>
             @endforeach
         </tr>
         </thead>

+ 1 - 1
routes/api.php

@@ -11,4 +11,4 @@ Route::get('/user', function (Request $request) {
 
 
 
-Route::get('/report-data/{name}', [DataTablesController::class, 'dynamicDataTable']);
+Route::post('/report-data/{name}', [DataTablesController::class, 'dynamicDataTable']);