Skip to content

Commit

Permalink
BETA: Livewire Custom Filter (Array) (#2025)
Browse files Browse the repository at this point in the history
* Initial Commit

* Add blade for Livewire Component Array Filter - not live

---------

Co-authored-by: lrljoe <lrljoe@users.noreply.github.com>
  • Loading branch information
lrljoe and lrljoe authored Oct 30, 2024
1 parent 542e797 commit 3e18b27
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div wire:key="filterComponents.{{ $filter->getKey() }}-wrapper">
<x-livewire-tables::tools.filter-label :$filter :$filterLayout :$tableName :$isTailwind :$isBootstrap4 :$isBootstrap5 :$isBootstrap />
<livewire:dynamic-component :is="$livewireComponent" :tableComponent="get_class($this)" :filterKey="$filter->getKey()" :$tableName :key="'filterComponents-'.$filter->getKey()" wire:model="filterComponents.{{ $filter->getKey() }}" />
</div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<div wire:key="filterComponents.{{ $filter->getKey() }}-wrapper">
<x-livewire-tables::tools.filter-label :$filter :$filterLayout :$tableName :$isTailwind :$isBootstrap4 :$isBootstrap5 :$isBootstrap />

<livewire:dynamic-component :is="$livewireComponent" :filterKey="$filter->getKey()" :key="'filterComponents-'.$filter->getKey()" wire:model.live="filterComponents.{{ $filter->getKey() }}" />
<livewire:dynamic-component :is="$livewireComponent" :tableComponent="get_class($this)" :filterKey="$filter->getKey()" :$tableName :key="'filterComponents-'.$filter->getKey()" wire:model.live="filterComponents.{{ $filter->getKey() }}" />
</div>
10 changes: 10 additions & 0 deletions src/Traits/Helpers/FilterHelpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -345,4 +345,14 @@ public function showFilterPillsSection(): bool
{
return $this->filtersAreEnabled() && $this->filterPillsAreEnabled() && $this->hasAppliedVisibleFiltersForPills();
}

#[On('livewireArrayFilterUpdateValues')]
public function updateLivewireArrayFilterValues(string $filterKey, string $tableName, array $values): void
{
if ($this->tableName == $tableName) {
$filter = $this->getFilterByKey($filterKey);
$filter->options($values);
}

}
}
58 changes: 58 additions & 0 deletions src/Views/Filters/LivewireComponentArrayFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Filters;

use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
use Rappasoft\LaravelLivewireTables\Views\Filter;
use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables;
use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HasOptions,IsArrayFilter, IsLivewireComponentFilter};

class LivewireComponentArrayFilter extends Filter
{
use HasWireables;
use IsArrayFilter;
use HasOptions;
use IsLivewireComponentFilter;

public string $wireMethod = 'blur';

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

public function validate(array $value): array|bool
{

return $value;
}

public function isEmpty(array $value = []): bool
{
return empty($value);
}

/**
* Gets the Default Value for this Filter via the Component
*/
public function getFilterDefaultValue(): ?string
{
return $this->filterDefaultValue ?? null;
}

public function getFilterPillValue($value): array|string|bool|null
{
$values = [];
foreach ($value as $key => $item) {

$found = $this->getCustomFilterPillValue($item) ?? ($this->options[$item] ?? $item);
if ($found) {
$values[] = $found;
}
}

return $values;
}

public function getKeys(): array
{
return array_keys($this->options ?? []);
}
}
38 changes: 2 additions & 36 deletions src/Views/Filters/LivewireComponentFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;
use Rappasoft\LaravelLivewireTables\Views\Filter;
use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables;
use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\IsLivewireComponentFilter;

class LivewireComponentFilter extends Filter
{
use HasWireables;
use IsLivewireComponentFilter;

public string $wireMethod = 'blur';

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

public string $livewireComponent = '';

public function validate(string $value): string|bool
{
return $value;
Expand All @@ -33,38 +33,4 @@ public function getFilterDefaultValue(): ?string
{
return $this->filterDefaultValue ?? null;
}

public function setLivewireComponent(string $livewireComponent): self
{

$class = '\\'.config('livewire.class_namespace').'\\'.collect(str($livewireComponent)->explode('.'))->map(fn ($segment) => (string) str($segment)->studly())->join('\\');

if (! class_exists($class)) {
throw new DataTableConfigurationException('You must specify a valid path to your Livewire Component Filter.');
}

if (! is_subclass_of($class, \Livewire\Component::class)) {
throw new DataTableConfigurationException('Your Livewire Component Filter MUST Extend Livewire\Component.');
}

$this->livewireComponent = $livewireComponent;

return $this;
}

public function getLivewireComponent(): string
{
return $this->livewireComponent ?? '';
}

public function render(): string|\Illuminate\Contracts\Foundation\Application|\Illuminate\View\View|\Illuminate\View\Factory
{
if ($this->livewireComponent == '') {
throw new DataTableConfigurationException('You must specify a valid path to your Livewire Component Filter.');
}

return view($this->getViewPath(), $this->getFilterDisplayData())->with([
'livewireComponent' => $this->livewireComponent,
]);
}
}
2 changes: 1 addition & 1 deletion src/Views/Traits/Filters/HasOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function options(array $options = []): self

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

public function getKeys(): array
Expand Down
44 changes: 44 additions & 0 deletions src/Views/Traits/Filters/IsLivewireComponentFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Traits\Filters;

use Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException;

trait IsLivewireComponentFilter
{
public string $livewireComponent = '';

public function setLivewireComponent(string $livewireComponent): self
{

$class = '\\'.config('livewire.class_namespace').'\\'.collect(str($livewireComponent)->explode('.'))->map(fn ($segment) => (string) str($segment)->studly())->join('\\');

if (! class_exists($class)) {
throw new DataTableConfigurationException('You must specify a valid path to your Livewire Component Filter.');
}

if (! is_subclass_of($class, \Livewire\Component::class)) {
throw new DataTableConfigurationException('Your Livewire Component Filter MUST Extend Livewire\Component.');
}

$this->livewireComponent = $livewireComponent;

return $this;
}

public function getLivewireComponent(): string
{
return $this->livewireComponent ?? '';
}

public function render(): string|\Illuminate\Contracts\Foundation\Application|\Illuminate\View\View|\Illuminate\View\Factory
{
if ($this->livewireComponent == '') {
throw new DataTableConfigurationException('You must specify a valid path to your Livewire Component Filter.');
}

return view($this->getViewPath(), $this->getFilterDisplayData())->with([
'livewireComponent' => $this->livewireComponent,
]);
}
}
73 changes: 73 additions & 0 deletions src/Views/Traits/IsExternalArrayFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

namespace Rappasoft\LaravelLivewireTables\Views\Traits;

use Livewire\Attributes\{Modelable,On,Renderless};

trait IsExternalArrayFilter
{
#[Modelable]
public array $value = [];

public string $filterKey = '';

public string $tableName = '';

public string $tableComponent = '';

protected bool $needsUpdating = false;

protected array $returnValues = [];

public array $selectedItems = [];

public array $selectOptions = [];

#[On('filter-was-set')]
public function setFilterValues(string $tableName, string $filterKey, array $value): void
{
if ($tableName == $this->tableName && $filterKey == $this->filterKey && $this->selectedItems != $value) {
$this->selectedItems = $value;
$this->needsUpdating = false;

}
}

protected function clearFilter() {}

#[Renderless]
public function updatedSelectedItems(string $value): void
{
if (! $this->needsUpdating) {
$this->needsUpdating = true;

}
}

#[Renderless]
protected function sendUpdateDispatch(array $returnValues): void
{
if ($this->needsUpdating) {
if (! empty($returnValues)) {
$this->value = array_keys($returnValues);
} else {
$this->value = [];
}
$this->dispatch('livewireArrayFilterUpdateValues', tableName: $this->tableName, filterKey: $this->filterKey, values: $returnValues)->to($this->tableComponent);

}
}

#[Renderless]
public function renderingIsExternalArrayFilter(): void
{
$returnValues = [];

if ($this->needsUpdating == true && ! empty($this->selectedItems)) {
foreach ($this->selectedItems as $selectedItem) {
$returnValues[$selectedItem] = $this->selectOptions[$selectedItem] ?? 'Unknown';
}
$this->sendUpdateDispatch($returnValues);
}
}
}

0 comments on commit 3e18b27

Please sign in to comment.