5 Angajamente 9ddf7898a5 ... 4ea4f0a3a9

Autor SHA1 Permisiunea de a trimite mesaje. Dacă este dezactivată, utilizatorul nu va putea trimite nici un fel de mesaj Data
  ttreasure 4ea4f0a3a9 Changed the way dropdown filters work so that they populate based on other filters that are already applied. 4 luni în urmă
  ttreasure f9988a24e2 Fixed issue where report was blank if a dropdown filter was removed. Also cleaned up code. 4 luni în urmă
  ttreasure 448099ca1f Basics of dropdown filters working 4 luni în urmă
  ttreasure 2491a6b3c8 Added Date filter columns 4 luni în urmă
  ttreasure 9c642cfc40 working on column search 4 luni în urmă

+ 59 - 4
app/Http/Controllers/DataTablesController.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Http\Request;
 use Yajra\DataTables\Facades\DataTables;
@@ -60,15 +61,69 @@ class DataTablesController extends Controller
             }
         }
 
+
+
+
+
+
+
+        $columnHeaders = json_decode($datatableConfig->column_headers, true);
+        $columnConfig = json_decode($datatableConfig->columns_config, true);
+
+
+        //Apply search filters
+        $searchTerms = $request->input('searchTerms', []);
+        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[$index]['start'])) {
+                    $query->whereDate($columnName, '>=', $value[$index]['start']);
+                }
+                if (!empty($value[$index]['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;
+                        case 'dropdown':
+                            if($value[$index] != '') {
+                                $query->where($columnName, '=', $value[$index]);
+                            }
+                            break;
+                }
+            }
+        }
+
+        //Get Data for Dropdown header columns
+        $dropdownData = new Collection();
+        foreach ($columnHeaders as $index => $columnHeader) {
+            if($columnHeader['searchtype'] === 'dropdown')
+            {
+                $ddColumnConfig = $columnConfig[$index];
+                $columnSnapshot = (clone $query)
+                    ->select($ddColumnConfig['name'])
+                    ->distinct()->orderBy($ddColumnConfig['name'])
+                    ->pluck($ddColumnConfig['name']);
+
+                $dropdownData[$index] = $columnSnapshot;
+
+            }
+        }
+
         // Apply sorting
         $sorting = $request->order[0] ?? json_decode($datatableConfig->default_sorting, true)[0];
 
         $query->orderBy($sorting['name'], $sorting['dir']);
 
         // Pass query to DataTables
-        return DataTables::of($query)->make(true);
-
-
+        return DataTables::of($query)->with(['dropdowndata' => $dropdownData, 'searchterms' => $searchTerms])->make(true);
     }
-
 }

+ 1 - 0
app/Livewire/ShowReports.php

@@ -13,6 +13,7 @@ class ShowReports extends Component
     public $datatableColumnsConfig;
     public $datatableHeadersConfig;
 
+
     public function mount($datatableName)
     {
         // Receive the dynamic datatable name during initialization

+ 121 - 28
resources/js/datatables.js

@@ -18,39 +18,132 @@ import 'datatables.net-responsive-dt';
 window.$ = window.jQuery = $;
 window.JSZip = JSZip;
 // Initialize DataTable
-document.addEventListener('livewire:init', function () {
+let dataTableInstance;
+var searchTerms ={};
+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
+    var dataTableHeadersConfig = JSON.parse(document.getElementById('datatable-config').dataset.datatableHeadersConfig);
+    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 data:', json);
+                //populate any dropdown headers
+                //console.log(dataTableHeadersConfig);
+                dataTableHeadersConfig.forEach(function(headerConfig, index){
+
+                    if(headerConfig.searchtype == "dropdown")
+                    {
+                        //console.log('Tyson here');
+                        var dropdown = $('#'+headerConfig.header.replace(' ', '-')+'FilterDropdown');
+                        //console.log(dropdown);
+                        dropdown.empty().append($('<option>',{
+                            value: '',
+                            text: '-- Not  Filtered  --'
+                        }));
+                        json.dropdowndata[index].forEach(function (option) {
+                            var selected = false;
+                            if(json.searchterms && json.searchterms[index]){
+                                    Object.keys(searchTerms[index]).forEach(function (key){
+                                        var searchValue = searchTerms[index][key]
+                                        console.log('value: '+searchValue)
+                                        if(option === searchValue)
+                                        {
+                                            selected = true;
+                                        }})}
+
+                                        dropdown.append($('<option>',{
+                                            value: option,
+                                            text: option
+                                        }).prop('selected', selected))});
+                              }});
+
+
+                            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 = searchTerms || {};
+            }
+        },
+        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();
+
 
     });
+let inner = {};
+function getFilterInput(searchTerm, index, searchType, extra){
+
+
+    switch (searchType) {
+        case "text":
+        case "number":
+            inner[index] = searchTerm;
+            break;
+        case "date":
+            if($.isEmptyObject(inner[index])) {
+                inner[index] = {"start": "", "end": ""};
+            }
+            if (extra === "start") {
+                inner[index].start = searchTerm;
+            }
+            else if (extra ===  "end") {
+                inner[index].end = searchTerm;
+            }
+            break;
+        case "dropdown":
+            inner[index] = searchTerm;
+            break;
+    }
+    searchTerms[index] =  inner;
+    console.log(searchTerms[index]);
+    dataTableInstance.ajax.reload();
+
+
+
+
+
+}
+
+window.getFilterInput = getFilterInput;
+
+
 
 
 

+ 24 - 3
resources/views/livewire/show-reports.blade.php

@@ -2,7 +2,8 @@
 <div>
     <div id="datatable-config"
          data-datatable-name="{{ $datatableName }}"
-         data-datatable-columns-config='@json($datatableColumnsConfig)'>
+         data-datatable-columns-config='@json($datatableColumnsConfig)'
+         data-datatable-headers-config='@json($datatableHeadersConfig)'>
     </div>
 
     <table id="{{$datatableName}}-table" class="bg-white border border-gray-300">
@@ -14,8 +15,28 @@
         </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="{{str_replace(" ", "-", $headerConfig['header'])}}Filter"  oninput="getFilterInput(this.value, {{$index}},'text', null)" placeholder="{{$headerConfig['header']}} Search" />
+                            @break
+                        @case("date")
+                            <input type="date" id="{{str_replace(" ", "-", $headerConfig['header'])}}FilterStartDate" onchange="getFilterInput(this.value, {{$index}},'date', 'start')" placeholder="{{$headerConfig['header']}} Start Date" />
+                            -
+                            <input type="date" id="{{str_replace(" ", "-", $headerConfig['header'])}}FilterEndDate" onchange="getFilterInput(this.value, {{$index}},'date', 'end')" placeholder="{{$headerConfig['header']}} End Date" />
+                            @break
+                        @case("dropdown")
+                            <select id="{{str_replace(" ", "-", $headerConfig['header'])}}FilterDropdown" onchange="getFilterInput(this.value, {{$index}},'dropdown', null)">
+
+                            </select>
+                            @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']);