Skip to content

Commit 851201f

Browse files
committed
Merge branch 'LowerRockLabs-MultiSelectDropdownFilter' into develop
2 parents 7fbb93b + 037747c commit 851201f

File tree

9 files changed

+282
-12
lines changed

9 files changed

+282
-12
lines changed

docs/filters/creating-filters.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,15 @@ public function filters(): array
6161
25 => 'Type Y',
6262
26 => 'Type Z',
6363
],
64-
]),
64+
])
65+
->setFirstOption('All Tags'),
6566
];
6667
}
6768
```
69+
To set a defualt "All" option at the start of the dropdown, you can do so by utilising the
70+
```
71+
->SetFirstOption('NAME')
72+
```
6873

6974
## Multi-select Filters
7075

@@ -89,6 +94,30 @@ public function filters(): array
8994
}
9095
```
9196

97+
## Multi-select dropdown Filters
98+
99+
Multi-select dropdown filters are a simple dropdown list. The user can select multiple options from the list. There is also an 'All' option that will select all values
100+
101+
```php
102+
use Rappasoft\LaravelLivewireTables\Views\Filters\SelectFilter;
103+
104+
public function filters(): array
105+
{
106+
return [
107+
SelectFilter::make('Tags')
108+
->options(
109+
Tag::query()
110+
->orderBy('name')
111+
->get()
112+
->keyBy('id')
113+
->map(fn($tag) => $tag->name)
114+
->toArray()
115+
)
116+
->setFirstOption('All Tags'),
117+
];
118+
}
119+
```
120+
92121
## Date Filters
93122

94123
Date filters are HTML date elements.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
@php
2+
$theme = $component->getTheme();
3+
@endphp
4+
5+
@if ($theme === 'tailwind')
6+
<div class="rounded-md shadow-sm">
7+
<select multiple
8+
wire:model.stop="{{ $component->getTableName() }}.filters.{{ $filter->getKey() }}"
9+
wire:key="{{ $component->getTableName() }}-filter-{{ $filter->getKey() }}"
10+
id="{{ $component->getTableName() }}-filter-{{ $filter->getKey() }}"
11+
class="block w-full transition duration-150 ease-in-out border-gray-300 rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 dark:bg-gray-800 dark:text-white dark:border-gray-600"
12+
>
13+
@if ($filter->getFirstOption() != "")
14+
<option @if($filter->isEmpty($this)) selected @endif value="all">{{ $filter->getFirstOption()}}</option>
15+
@endif
16+
@foreach($filter->getOptions() as $key => $value)
17+
@if (is_iterable($value))
18+
<optgroup label="{{ $key }}">
19+
@foreach ($value as $optionKey => $optionValue)
20+
<option value="{{ $optionKey }}">{{ $optionValue }}</option>
21+
@endforeach
22+
</optgroup>
23+
@else
24+
<option value="{{ $key }}">{{ $value }}</option>
25+
@endif
26+
@endforeach
27+
</select>
28+
</div>
29+
@elseif ($theme === 'bootstrap-4' || $theme === 'bootstrap-5')
30+
<select multiple
31+
wire:model.stop="{{ $component->getTableName() }}.filters.{{ $filter->getKey() }}"
32+
wire:key="{{ $component->getTableName() }}-filter-{{ $filter->getKey() }}"
33+
id="{{ $component->getTableName() }}-filter-{{ $filter->getKey() }}"
34+
class="{{ $theme === 'bootstrap-4' ? 'form-control' : 'form-select' }}"
35+
>
36+
@if ($filter->getFirstOption() != "")
37+
<option @if($filter->isEmpty($this)) selected @endif value="all">{{ $filter->getFirstOption()}}</option>
38+
@endif
39+
@foreach($filter->getOptions() as $key => $value)
40+
@if (is_iterable($value))
41+
<optgroup label="{{ $key }}">
42+
@foreach ($value as $optionKey => $optionValue)
43+
<option value="{{ $optionKey }}">{{ $optionValue }}</option>
44+
@endforeach
45+
</optgroup>
46+
@else
47+
<option value="{{ $key }}">{{ $value }}</option>
48+
@endif
49+
@endforeach
50+
</select>
51+
@endif

src/Traits/Helpers/FilterHelpers.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Support\Collection;
66
use Rappasoft\LaravelLivewireTables\Views\Filter;
7+
use Rappasoft\LaravelLivewireTables\Views\Filters\MultiSelectDropdownFilter;
78
use Rappasoft\LaravelLivewireTables\Views\Filters\MultiSelectFilter;
89

910
trait FilterHelpers
@@ -91,7 +92,7 @@ public function selectAllFilterOptions(string $filterKey): void
9192
{
9293
$filter = $this->getFilterByKey($filterKey);
9394

94-
if (! $filter instanceof MultiSelectFilter) {
95+
if (! $filter instanceof MultiSelectFilter && ! $filter instanceof MultiSelectDropdownFilter) {
9596
return;
9697
}
9798

@@ -175,7 +176,7 @@ public function resetFilter($filter): void
175176
if (! $filter instanceof Filter) {
176177
$filter = $this->getFilterByKey($filter);
177178
}
178-
179+
179180
$this->setFilter($filter->getKey(), $filter->getDefaultValue());
180181
}
181182

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Views\Filters;
4+
5+
use Rappasoft\LaravelLivewireTables\DataTableComponent;
6+
use Rappasoft\LaravelLivewireTables\Views\Filter;
7+
8+
class MultiSelectDropdownFilter extends Filter
9+
{
10+
protected array $options = [];
11+
protected string $firstOption = "";
12+
13+
public function options(array $options = []): MultiSelectDropdownFilter
14+
{
15+
$this->options = $options;
16+
17+
return $this;
18+
}
19+
20+
public function getOptions(): array
21+
{
22+
return $this->options;
23+
}
24+
25+
public function setFirstOption(string $firstOption): MultiSelectDropdownFilter
26+
{
27+
$this->firstOption = $firstOption;
28+
29+
return $this;
30+
}
31+
32+
public function getFirstOption(): string
33+
{
34+
return $this->firstOption;
35+
}
36+
37+
public function getKeys(): array
38+
{
39+
return collect($this->getOptions())
40+
->keys()
41+
->map(fn ($value) => (string)$value)
42+
->filter(fn ($value) => strlen($value))
43+
->values()
44+
->toArray();
45+
}
46+
47+
public function validate($value)
48+
{
49+
if (is_array($value)) {
50+
foreach ($value as $index => $val) {
51+
// Remove the bad value
52+
if (! in_array($val, $this->getKeys())) {
53+
unset($value[$index]);
54+
}
55+
}
56+
}
57+
58+
return $value;
59+
}
60+
61+
public function getDefaultValue()
62+
{
63+
return [];
64+
}
65+
66+
public function getFilterPillValue($value): ?string
67+
{
68+
$values = [];
69+
70+
foreach ($value as $item) {
71+
$found = $this->getCustomFilterPillValue($item) ?? $this->getOptions()[$item] ?? null;
72+
73+
if ($found) {
74+
$values[] = $found;
75+
}
76+
}
77+
78+
return implode(', ', $values);
79+
}
80+
81+
public function isEmpty($value): bool
82+
{
83+
if (! is_array($value)) {
84+
return true;
85+
} elseif (in_array("all", $value)) {
86+
return true;
87+
}
88+
89+
return false;
90+
}
91+
92+
public function render(DataTableComponent $component)
93+
{
94+
return view('livewire-tables::components.tools.filters.multi-select-dropdown', [
95+
'component' => $component,
96+
'filter' => $this,
97+
]);
98+
}
99+
}

tests/Http/Livewire/PetsTable.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
use Rappasoft\LaravelLivewireTables\DataTableComponent;
77
use Rappasoft\LaravelLivewireTables\Tests\Models\Breed;
88
use Rappasoft\LaravelLivewireTables\Tests\Models\Pet;
9+
use Rappasoft\LaravelLivewireTables\Tests\Models\Species;
910
use Rappasoft\LaravelLivewireTables\Views\Column;
11+
use Rappasoft\LaravelLivewireTables\Views\Filters\MultiSelectDropdownFilter;
1012
use Rappasoft\LaravelLivewireTables\Views\Filters\MultiSelectFilter;
1113

1214
class PetsTable extends DataTableComponent
@@ -56,6 +58,18 @@ public function filters(): array
5658
->filter(function (Builder $builder, array $values) {
5759
return $builder->whereIn('breed_id', $values);
5860
}),
61+
MultiSelectDropdownFilter::make('Species')
62+
->options(
63+
Species::query()
64+
->orderBy('name')
65+
->get()
66+
->keyBy('id')
67+
->map(fn ($species) => $species->name)
68+
->toArray()
69+
)
70+
->filter(function (Builder $builder, array $values) {
71+
return $builder->whereIn('species_id', $values);
72+
}),
5973
];
6074
}
6175
}

tests/Traits/Configuration/FilterConfigurationTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,27 @@ public function filters_layout_can_be_set(): void
100100

101101
$this->basicTable->setFilterLayout('popover');
102102
}
103+
104+
/** @test */
105+
/* Not present in this branch
106+
public function filters_layout_popover_default_can_be_set(): void
107+
{
108+
$this->assertFalse($this->basicTable->filterSlideDownDefaultVisible);
109+
110+
$this->basicTable->setFilterSlideDownDefaultStatusEnabled();
111+
112+
$this->assertTrue($this->basicTable->filterSlideDownDefaultVisible);
113+
114+
$this->basicTable->setFilterSlideDownDefaultStatusDisabled();
115+
116+
$this->assertFalse($this->basicTable->filterSlideDownDefaultVisible);
117+
118+
$this->basicTable->setFilterSlideDownDefaultStatus(true);
119+
120+
$this->assertTrue($this->basicTable->filterSlideDownDefaultVisible);
121+
122+
$this->basicTable->setFilterSlideDownDefaultStatus(false);
123+
124+
$this->assertFalse($this->basicTable->filterSlideDownDefaultVisible);
125+
}*/
103126
}

0 commit comments

Comments
 (0)