Skip to content

Commit 2433c3b

Browse files
Feature/update filters and style (#18)
1 parent 2e12b73 commit 2433c3b

File tree

15 files changed

+190
-100
lines changed

15 files changed

+190
-100
lines changed
Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
1-
2-
<input type="text" wire:model="search"
3-
placeholder="{{ __('datatable::datatables.search') }}"
4-
class="border border-gray-300 rounded-lg px-4 py-2 text-sm w-64 focus:ring-2 focus:ring-blue-400 focus:outline-none transition">
5-
6-
<button wire:click="applySearch"
7-
class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg text-sm shadow-sm transition">
8-
{{ __('datatable::datatables.search') }}
9-
</button>
10-
11-
<button wire:click="resetSearch"
12-
class="bg-gray-300 hover:bg-gray-400 text-gray-700 px-4 py-2 rounded-lg text-sm shadow-sm transition">
13-
{{ __('datatable::datatables.reset') }}
14-
</button>
1+
<input type="text" wire:model.debounce.500ms="search"
2+
@keydown.enter="$dispatch('searchUpdated')"
3+
@blur="$dispatch('searchUpdated')"
4+
placeholder="{{ __('datatable::datatables.search') }}"
5+
class="border border-gray-300 rounded-lg px-4 py-2 text-sm w-96 focus:ring-2 focus:ring-blue-400 focus:outline-none transition">

resources/views/vendor/datatables/filters.blade.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<div x-data="{ open: @entangle('showFilters') }" class="relative">
22

33
<button @click="open = !open"
4-
class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-3 py-1 rounded-lg text-sm flex items-center gap-1 shadow-sm transition">
5-
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
4+
class="flex items-center gap-2 px-4 py-2 text-sm md:text-base font-medium text-gray-700 bg-gray-100 border border-gray-300 rounded-lg
5+
hover:bg-gray-200 focus:ring-2 focus:ring-blue-400 focus:outline-none transition-all duration-200 ease-in-out
6+
active:scale-95 sm:px-3 sm:py-1 sm:text-sm">
7+
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 sm:w-4 sm:h-4" viewBox="0 0 20 20" fill="currentColor">
68
<path fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 011 1v1.5l-4.5 5.5V15a1 1 0 01-1 1h-2a1 1 0 01-1-1v-3L3 6.5V5zm2 1v.378L9.5 12.5V15h1v-2.5l4.5-6.122V6H5z" clip-rule="evenodd"/>
79
</svg>
8-
{{ __('datatable::datatables.filters') }}
10+
<span class="hidden sm:inline">{{ __('datatable::datatables.filters') }}</span>
911
</button>
1012

1113
<div class="flex flex-wrap gap-2 mt-3">
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div class="flex items-center gap-2">
2-
<input type="checkbox" wire:model.defer="filters.{{ $filter['column'] }}.value"
2+
<input type="checkbox" wire:model.defer="filters.{{ $column }}.value"
33
class="h-4 w-4 text-blue-500 border-gray-300 rounded">
4-
<label class="text-sm font-medium text-gray-600">{{ ucfirst(str_replace('_', ' ', $filter['column'])) }}</label>
4+
<label class="text-sm font-medium text-gray-600">{{ ucfirst($filter['label']) }}</label>
55
</div>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div>
2-
<label class="text-sm font-medium text-gray-600">{{ ucfirst(str_replace('_', ' ', $filter['column'])) }}</label>
3-
<input type="date" wire:model.defer="filters.{{ $filter['column'] }}.value"
2+
<label class="text-sm font-medium text-gray-600">{{ ucfirst($filter['label']) }}</label>
3+
<input type="date" wire:model.defer="filters.{{ $column }}.value"
44
class="border border-gray-300 rounded px-3 py-1 text-sm w-48">
55
</div>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div>
2-
<label class="text-sm font-medium text-gray-600">{{ ucfirst(str_replace('_', ' ', $filter['column'])) }}</label>
3-
<input type="text" wire:model.defer="filters.{{ $filter['column'] }}.value"
2+
<label class="text-sm font-medium text-gray-600">{{ ucfirst($filter['label']) }}</label>
3+
<input type="text" wire:model.defer="filters.{{ $column }}.value"
44
class="border border-gray-300 rounded px-3 py-1 text-sm w-48">
55
</div>

resources/views/vendor/datatables/filters/types/radio.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<div>
2-
<label class="text-sm font-medium text-gray-600 block">{{ ucfirst(str_replace('_', ' ', $filter['column'])) }}</label>
2+
<label class="text-sm font-medium text-gray-600 block">{{ ucfirst($filter['label']) }}</label>
33
<div class="flex gap-2">
44
@foreach($filter['options'] as $key => $option)
55
<label class="flex items-center gap-1 text-sm">
6-
<input type="radio" wire:model.defer="filters.{{ $filter['column'] }}.value" value="{{ $key }}"
6+
<input type="radio" wire:model.defer="filters.{{ $column }}.value" value="{{ $key }}"
77
class="h-4 w-4 text-blue-500 border-gray-300 rounded">
88
{{ $option }}
99
</label>

resources/views/vendor/datatables/filters/types/select.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div>
2-
<label class="text-sm font-medium text-gray-600">{{ ucfirst(str_replace('_', ' ', $filter['column'])) }}</label>
3-
<select wire:model.defer="filters.{{ $filter['column'] }}.value"
2+
<label class="text-sm font-medium text-gray-600">{{ ucfirst($filter['label']) }}</label>
3+
<select wire:model.defer="filters.{{ $column }}.value"
44
class="border border-gray-300 rounded px-3 py-1 text-sm w-48">
55
<option value="">{{ __('datatable::datatables.select_option') }}</option>
66
@foreach($filter['options'] as $key => $option)

src/Factories/FilterFactory.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace Ginkelsoft\DataTables\Factories;
4+
5+
use Ginkelsoft\DataTables\Filters\DateFilter;
6+
use Ginkelsoft\DataTables\Filters\TextFilter;
7+
use Ginkelsoft\DataTables\Filters\SelectFilter;
8+
use Ginkelsoft\DataTables\Filters\CheckboxFilter;
9+
use Ginkelsoft\DataTables\Filters\RadioFilter;
10+
use Ginkelsoft\DataTables\Filter;
11+
12+
class FilterFactory
13+
{
14+
/**
15+
* Create a filter instance based on the type.
16+
*/
17+
public static function make(array $filter): Filter
18+
{
19+
return match ($filter['type']) {
20+
'input' => new TextFilter(
21+
$filter['column'],
22+
$filter['value'] ?? '',
23+
$filter['label'] ?? ''
24+
),
25+
'select' => new SelectFilter($filter['column'], $filter['value'] ?? '', $filter['options'] ?? [], $filter['label'] ?? ''),
26+
'checkbox' => new CheckboxFilter($filter['column'], $filter['value'] ?? false, $filter['label'] ?? ''),
27+
'radio' => new RadioFilter($filter['column'], $filter['value'] ?? false, $filter['options'] ?? [], $filter['label'] ?? ''),
28+
'date' => new DateFilter($filter['column'], $filter['value'] ?? null, $filter['label'] ?? ''),
29+
/*'date-between' => new DateBetweenFilter(
30+
$filter['column'],
31+
$filter['value']['from'] ?? null,
32+
$filter['value']['to'] ?? null
33+
),*/
34+
default => throw new \Exception("Unknown filter type: {$filter['type']}"),
35+
};
36+
}
37+
}

src/Filter.php

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ class Filter
1818
/** @var string The type of filter (e.g., input, select, checkbox, date-range) */
1919
public string $type;
2020

21-
/** @var mixed The filter value */
22-
public mixed $value;
21+
/** @var mixed The raw filter value */
22+
protected mixed $value;
2323

2424
/** @var array Options for select and radio button filters */
2525
public array $options;
2626

27+
public string $label;
28+
2729
/**
2830
* Filter constructor.
2931
*
@@ -32,12 +34,52 @@ class Filter
3234
* @param string $type The type of filter (default: 'input').
3335
* @param array $options Options for select, radio, or other multi-choice filters.
3436
*/
35-
public function __construct(string $column, mixed $value = '', string $type = 'input', array $options = [])
37+
public function __construct(string $column, mixed $value = '', string $type = 'input', array $options = [], string $label = '')
3638
{
39+
3740
$this->column = $column;
38-
$this->value = $value;
3941
$this->type = $type;
4042
$this->options = $options;
43+
$this->setValue($value);
44+
$this->label = $label ?: ucfirst(str_replace('_', ' ', $column));
45+
}
46+
47+
/**
48+
* Set the filter value.
49+
*
50+
* @param mixed $value
51+
* @return void
52+
*/
53+
public function setValue(mixed $value): void
54+
{
55+
$this->value = !is_string($value) ? json_decode($value, true) : $value;
56+
}
57+
58+
/**
59+
* Get the filter value.
60+
*
61+
* @return mixed
62+
*/
63+
public function getValue(): mixed
64+
{
65+
return $this->value;
66+
}
67+
68+
/**
69+
* Convert the filter to an array format.
70+
*
71+
* @return array
72+
*/
73+
public function toArray(): array
74+
{
75+
return [
76+
$this->column => [
77+
'type' => $this->type,
78+
'value' => $this->getValue(), // ✅ Correcte waarde
79+
'options' => $this->options,
80+
'label' => $this->label,
81+
]
82+
];
4183
}
4284

4385
/**
@@ -48,36 +90,6 @@ public function __construct(string $column, mixed $value = '', string $type = 'i
4890
*/
4991
public function apply(Builder $query): Builder
5092
{
51-
if (!empty($this->value)) {
52-
switch ($this->type) {
53-
case 'select':
54-
$query->where($this->column, $this->value);
55-
break;
56-
57-
case 'checkbox':
58-
$query->where($this->column, '=', (bool) $this->value);
59-
break;
60-
61-
case 'radio':
62-
$query->where($this->column, '=', $this->value);
63-
break;
64-
65-
case 'date-range':
66-
if (is_array($this->value)) {
67-
if (!empty($this->value['from'])) {
68-
$query->whereDate($this->column, '>=', $this->value['from']);
69-
}
70-
if (!empty($this->value['to'])) {
71-
$query->whereDate($this->column, '<=', $this->value['to']);
72-
}
73-
}
74-
break;
75-
76-
default:
77-
$query->where($this->column, 'like', "%{$this->value}%");
78-
break;
79-
}
80-
}
8193
return $query;
8294
}
8395
}
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010
*
1111
* A specialized filter for handling boolean (true/false) values using checkboxes.
1212
*/
13-
class BooleanFilter extends Filter
13+
class CheckboxFilter extends Filter
1414
{
1515
/**
1616
* BooleanFilter constructor.
1717
*
1818
* @param string $column The column to filter.
1919
* @param bool|null $value The boolean value to filter by (default: null).
2020
*/
21-
public function __construct(string $column, ?bool $value = null)
21+
public function __construct(string $column, ?bool $value = null, string $label = '')
2222
{
23-
parent::__construct($column, $value, 'checkbox');
23+
parent::__construct($column, $value, 'checkbox', [], $label);
2424
}
2525

2626
/**
@@ -31,7 +31,9 @@ public function __construct(string $column, ?bool $value = null)
3131
*/
3232
public function apply(Builder $query): Builder
3333
{
34-
if (!is_null($this->value)) {
34+
$value = $this->getValue();
35+
36+
if (!empty($value)) {
3537
$query->where($this->column, (bool) $this->value);
3638
}
3739

0 commit comments

Comments
 (0)