Skip to content

Commit 3e18b27

Browse files
authored
BETA: Livewire Custom Filter (Array) (rappasoft#2025)
* Initial Commit * Add blade for Livewire Component Array Filter - not live --------- Co-authored-by: lrljoe <[email protected]>
1 parent 542e797 commit 3e18b27

File tree

8 files changed

+193
-39
lines changed

8 files changed

+193
-39
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<div wire:key="filterComponents.{{ $filter->getKey() }}-wrapper">
2+
<x-livewire-tables::tools.filter-label :$filter :$filterLayout :$tableName :$isTailwind :$isBootstrap4 :$isBootstrap5 :$isBootstrap />
3+
<livewire:dynamic-component :is="$livewireComponent" :tableComponent="get_class($this)" :filterKey="$filter->getKey()" :$tableName :key="'filterComponents-'.$filter->getKey()" wire:model="filterComponents.{{ $filter->getKey() }}" />
4+
</div>
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<div wire:key="filterComponents.{{ $filter->getKey() }}-wrapper">
22
<x-livewire-tables::tools.filter-label :$filter :$filterLayout :$tableName :$isTailwind :$isBootstrap4 :$isBootstrap5 :$isBootstrap />
3-
4-
<livewire:dynamic-component :is="$livewireComponent" :filterKey="$filter->getKey()" :key="'filterComponents-'.$filter->getKey()" wire:model.live="filterComponents.{{ $filter->getKey() }}" />
3+
<livewire:dynamic-component :is="$livewireComponent" :tableComponent="get_class($this)" :filterKey="$filter->getKey()" :$tableName :key="'filterComponents-'.$filter->getKey()" wire:model.live="filterComponents.{{ $filter->getKey() }}" />
54
</div>

src/Traits/Helpers/FilterHelpers.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,4 +345,14 @@ public function showFilterPillsSection(): bool
345345
{
346346
return $this->filtersAreEnabled() && $this->filterPillsAreEnabled() && $this->hasAppliedVisibleFiltersForPills();
347347
}
348+
349+
#[On('livewireArrayFilterUpdateValues')]
350+
public function updateLivewireArrayFilterValues(string $filterKey, string $tableName, array $values): void
351+
{
352+
if ($this->tableName == $tableName) {
353+
$filter = $this->getFilterByKey($filterKey);
354+
$filter->options($values);
355+
}
356+
357+
}
348358
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Views\Filters;
4+
5+
use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
6+
use Rappasoft\LaravelLivewireTables\Views\Filter;
7+
use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables;
8+
use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HasOptions,IsArrayFilter, IsLivewireComponentFilter};
9+
10+
class LivewireComponentArrayFilter extends Filter
11+
{
12+
use HasWireables;
13+
use IsArrayFilter;
14+
use HasOptions;
15+
use IsLivewireComponentFilter;
16+
17+
public string $wireMethod = 'blur';
18+
19+
protected string $view = 'livewire-tables::components.tools.filters.livewire-component-array-filter';
20+
21+
public function validate(array $value): array|bool
22+
{
23+
24+
return $value;
25+
}
26+
27+
public function isEmpty(array $value = []): bool
28+
{
29+
return empty($value);
30+
}
31+
32+
/**
33+
* Gets the Default Value for this Filter via the Component
34+
*/
35+
public function getFilterDefaultValue(): ?string
36+
{
37+
return $this->filterDefaultValue ?? null;
38+
}
39+
40+
public function getFilterPillValue($value): array|string|bool|null
41+
{
42+
$values = [];
43+
foreach ($value as $key => $item) {
44+
45+
$found = $this->getCustomFilterPillValue($item) ?? ($this->options[$item] ?? $item);
46+
if ($found) {
47+
$values[] = $found;
48+
}
49+
}
50+
51+
return $values;
52+
}
53+
54+
public function getKeys(): array
55+
{
56+
return array_keys($this->options ?? []);
57+
}
58+
}

src/Views/Filters/LivewireComponentFilter.php

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
66
use Rappasoft\LaravelLivewireTables\Views\Filter;
77
use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables;
8+
use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\IsLivewireComponentFilter;
89

910
class LivewireComponentFilter extends Filter
1011
{
1112
use HasWireables;
13+
use IsLivewireComponentFilter;
1214

1315
public string $wireMethod = 'blur';
1416

1517
protected string $view = 'livewire-tables::components.tools.filters.livewire-component-filter';
1618

17-
public string $livewireComponent = '';
18-
1919
public function validate(string $value): string|bool
2020
{
2121
return $value;
@@ -33,38 +33,4 @@ public function getFilterDefaultValue(): ?string
3333
{
3434
return $this->filterDefaultValue ?? null;
3535
}
36-
37-
public function setLivewireComponent(string $livewireComponent): self
38-
{
39-
40-
$class = '\\'.config('livewire.class_namespace').'\\'.collect(str($livewireComponent)->explode('.'))->map(fn ($segment) => (string) str($segment)->studly())->join('\\');
41-
42-
if (! class_exists($class)) {
43-
throw new DataTableConfigurationException('You must specify a valid path to your Livewire Component Filter.');
44-
}
45-
46-
if (! is_subclass_of($class, \Livewire\Component::class)) {
47-
throw new DataTableConfigurationException('Your Livewire Component Filter MUST Extend Livewire\Component.');
48-
}
49-
50-
$this->livewireComponent = $livewireComponent;
51-
52-
return $this;
53-
}
54-
55-
public function getLivewireComponent(): string
56-
{
57-
return $this->livewireComponent ?? '';
58-
}
59-
60-
public function render(): string|\Illuminate\Contracts\Foundation\Application|\Illuminate\View\View|\Illuminate\View\Factory
61-
{
62-
if ($this->livewireComponent == '') {
63-
throw new DataTableConfigurationException('You must specify a valid path to your Livewire Component Filter.');
64-
}
65-
66-
return view($this->getViewPath(), $this->getFilterDisplayData())->with([
67-
'livewireComponent' => $this->livewireComponent,
68-
]);
69-
}
7036
}

src/Views/Traits/Filters/HasOptions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function options(array $options = []): self
3333

3434
public function getOptions(): array
3535
{
36-
return $this->options ?? $this->options = config($this->optionsPath, []);
36+
return $this->options ?? $this->options = (property_exists($this, 'optionsPath') ? config($this->optionsPath, []) : []);
3737
}
3838

3939
public function getKeys(): array
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Views\Traits\Filters;
4+
5+
use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
6+
7+
trait IsLivewireComponentFilter
8+
{
9+
public string $livewireComponent = '';
10+
11+
public function setLivewireComponent(string $livewireComponent): self
12+
{
13+
14+
$class = '\\'.config('livewire.class_namespace').'\\'.collect(str($livewireComponent)->explode('.'))->map(fn ($segment) => (string) str($segment)->studly())->join('\\');
15+
16+
if (! class_exists($class)) {
17+
throw new DataTableConfigurationException('You must specify a valid path to your Livewire Component Filter.');
18+
}
19+
20+
if (! is_subclass_of($class, \Livewire\Component::class)) {
21+
throw new DataTableConfigurationException('Your Livewire Component Filter MUST Extend Livewire\Component.');
22+
}
23+
24+
$this->livewireComponent = $livewireComponent;
25+
26+
return $this;
27+
}
28+
29+
public function getLivewireComponent(): string
30+
{
31+
return $this->livewireComponent ?? '';
32+
}
33+
34+
public function render(): string|\Illuminate\Contracts\Foundation\Application|\Illuminate\View\View|\Illuminate\View\Factory
35+
{
36+
if ($this->livewireComponent == '') {
37+
throw new DataTableConfigurationException('You must specify a valid path to your Livewire Component Filter.');
38+
}
39+
40+
return view($this->getViewPath(), $this->getFilterDisplayData())->with([
41+
'livewireComponent' => $this->livewireComponent,
42+
]);
43+
}
44+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
namespace Rappasoft\LaravelLivewireTables\Views\Traits;
4+
5+
use Livewire\Attributes\{Modelable,On,Renderless};
6+
7+
trait IsExternalArrayFilter
8+
{
9+
#[Modelable]
10+
public array $value = [];
11+
12+
public string $filterKey = '';
13+
14+
public string $tableName = '';
15+
16+
public string $tableComponent = '';
17+
18+
protected bool $needsUpdating = false;
19+
20+
protected array $returnValues = [];
21+
22+
public array $selectedItems = [];
23+
24+
public array $selectOptions = [];
25+
26+
#[On('filter-was-set')]
27+
public function setFilterValues(string $tableName, string $filterKey, array $value): void
28+
{
29+
if ($tableName == $this->tableName && $filterKey == $this->filterKey && $this->selectedItems != $value) {
30+
$this->selectedItems = $value;
31+
$this->needsUpdating = false;
32+
33+
}
34+
}
35+
36+
protected function clearFilter() {}
37+
38+
#[Renderless]
39+
public function updatedSelectedItems(string $value): void
40+
{
41+
if (! $this->needsUpdating) {
42+
$this->needsUpdating = true;
43+
44+
}
45+
}
46+
47+
#[Renderless]
48+
protected function sendUpdateDispatch(array $returnValues): void
49+
{
50+
if ($this->needsUpdating) {
51+
if (! empty($returnValues)) {
52+
$this->value = array_keys($returnValues);
53+
} else {
54+
$this->value = [];
55+
}
56+
$this->dispatch('livewireArrayFilterUpdateValues', tableName: $this->tableName, filterKey: $this->filterKey, values: $returnValues)->to($this->tableComponent);
57+
58+
}
59+
}
60+
61+
#[Renderless]
62+
public function renderingIsExternalArrayFilter(): void
63+
{
64+
$returnValues = [];
65+
66+
if ($this->needsUpdating == true && ! empty($this->selectedItems)) {
67+
foreach ($this->selectedItems as $selectedItem) {
68+
$returnValues[$selectedItem] = $this->selectOptions[$selectedItem] ?? 'Unknown';
69+
}
70+
$this->sendUpdateDispatch($returnValues);
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)