diff --git a/resources/views/bootstrap-4/components/table/row.blade.php b/resources/views/bootstrap-4/components/table/row.blade.php
index 6a0f27458..9fa710eee 100644
--- a/resources/views/bootstrap-4/components/table/row.blade.php
+++ b/resources/views/bootstrap-4/components/table/row.blade.php
@@ -1,6 +1,6 @@
@props(['url' => null, 'target' => '_self', 'reordering' => false, 'customAttributes' => []])
-@if (!$reordering && $attributes->has('wire:sortable.item'))
+@if (!$reordering && (method_exists($attributes, 'has') ? $attributes->has('wire:sortable.item') : array_key_exists('wire:sortable.item', $attributes->getAttributes())))
@php
$attributes = $attributes->filter(fn ($value, $key) => $key !== 'wire:sortable.item');
@endphp
diff --git a/resources/views/bootstrap-4/includes/filter-pills.blade.php b/resources/views/bootstrap-4/includes/filter-pills.blade.php
index 4e748b4a4..020ad9775 100644
--- a/resources/views/bootstrap-4/includes/filter-pills.blade.php
+++ b/resources/views/bootstrap-4/includes/filter-pills.blade.php
@@ -9,7 +9,7 @@
wire:key="filter-pill-{{ $key }}"
class="badge badge-pill badge-info d-inline-flex align-items-center"
>
- {{ $filterNames[$key] ?? collect($this->columns())->pluck('text', 'column')->get($key, ucwords(strtr($key, ['_' => ' ', '-' => ' ']))) }}:
+ {{ $filterNames[$key] ?? collect($this->columns())->pluck('text', 'column')->get($key, isset($customFilters[$key]) && property_exists($customFilters[$key], 'name') ? $customFilters[$key]->name : ucwords(strtr($key, ['_' => ' ', '-' => ' ']))) }}:
@if(isset($customFilters[$key]) && method_exists($customFilters[$key], 'options'))
@if(is_array($value))
@foreach($value as $selectedValue)
diff --git a/resources/views/bootstrap-5/components/table/row.blade.php b/resources/views/bootstrap-5/components/table/row.blade.php
index 6a0f27458..9fa710eee 100644
--- a/resources/views/bootstrap-5/components/table/row.blade.php
+++ b/resources/views/bootstrap-5/components/table/row.blade.php
@@ -1,6 +1,6 @@
@props(['url' => null, 'target' => '_self', 'reordering' => false, 'customAttributes' => []])
-@if (!$reordering && $attributes->has('wire:sortable.item'))
+@if (!$reordering && (method_exists($attributes, 'has') ? $attributes->has('wire:sortable.item') : array_key_exists('wire:sortable.item', $attributes->getAttributes())))
@php
$attributes = $attributes->filter(fn ($value, $key) => $key !== 'wire:sortable.item');
@endphp
diff --git a/resources/views/bootstrap-5/includes/filter-pills.blade.php b/resources/views/bootstrap-5/includes/filter-pills.blade.php
index 6c8c30ea3..dc4cf08d7 100644
--- a/resources/views/bootstrap-5/includes/filter-pills.blade.php
+++ b/resources/views/bootstrap-5/includes/filter-pills.blade.php
@@ -9,7 +9,7 @@
wire:key="filter-pill-{{ $key }}"
class="badge rounded-pill bg-info d-inline-flex align-items-center"
>
- {{ $filterNames[$key] ?? collect($this->columns())->pluck('text', 'column')->get($key, ucwords(strtr($key, ['_' => ' ', '-' => ' ']))) }}:
+ {{ $filterNames[$key] ?? collect($this->columns())->pluck('text', 'column')->get($key, isset($customFilters[$key]) && property_exists($customFilters[$key], 'name') ? $customFilters[$key]->name : ucwords(strtr($key, ['_' => ' ', '-' => ' ']))) }}:
@if(isset($customFilters[$key]) && method_exists($customFilters[$key], 'options'))
@if(is_array($value))
@foreach($value as $selectedValue)
diff --git a/resources/views/tailwind/components/table/row.blade.php b/resources/views/tailwind/components/table/row.blade.php
index c6cf88265..f22f7e99d 100644
--- a/resources/views/tailwind/components/table/row.blade.php
+++ b/resources/views/tailwind/components/table/row.blade.php
@@ -1,13 +1,13 @@
@props(['url' => null, 'target' => '_self', 'reordering' => false, 'customAttributes' => []])
-@if (!$reordering && $attributes->has('wire:sortable.item'))
+@if (!$reordering && (method_exists($attributes, 'has') ? $attributes->has('wire:sortable.item') : array_key_exists('wire:sortable.item', $attributes->getAttributes())))
@php
$attributes = $attributes->filter(fn ($value, $key) => $key !== 'wire:sortable.item');
@endphp
@endif
merge($customAttributes)->class(['cursor-pointer' => $url]) }}
+ {{ $attributes->merge($customAttributes)->merge(['class' => $url ? 'cursor-pointer' : '']) }}
@if ($url)
onclick="window.open('{{ $url }}', '{{ $target }}')"
diff --git a/resources/views/tailwind/includes/filter-pills.blade.php b/resources/views/tailwind/includes/filter-pills.blade.php
index 2491d9437..3919030b2 100644
--- a/resources/views/tailwind/includes/filter-pills.blade.php
+++ b/resources/views/tailwind/includes/filter-pills.blade.php
@@ -9,7 +9,7 @@
wire:key="filter-pill-{{ $key }}"
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium leading-4 bg-indigo-100 text-indigo-800 capitalize dark:bg-indigo-200 dark:text-indigo-900"
>
- {{ $filterNames[$key] ?? collect($this->columns())->pluck('text', 'column')->get($key, ucwords(strtr($key, ['_' => ' ', '-' => ' ']))) }}:
+ {{ $filterNames[$key] ?? collect($this->columns())->pluck('text', 'column')->get($key, isset($customFilters[$key]) && property_exists($customFilters[$key], 'name') ? $customFilters[$key]->name : ucwords(strtr($key, ['_' => ' ', '-' => ' ']))) }}:
@if(isset($customFilters[$key]) && method_exists($customFilters[$key], 'options'))
@if(is_array($value))
@foreach($value as $selectedValue)
diff --git a/tests/DataTableComponentTest.php b/tests/DataTableComponentTest.php
index 470d6875d..4dfca67b3 100644
--- a/tests/DataTableComponentTest.php
+++ b/tests/DataTableComponentTest.php
@@ -3,7 +3,9 @@
namespace Rappasoft\LaravelLivewireTables\Tests;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
+use Illuminate\Encryption\Encrypter;
use Illuminate\Support\Collection;
+use Livewire\Livewire;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\PetsAltQueryTable;
use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\PetsTable;
@@ -115,6 +117,42 @@ public function search_filter_alt_query_relation()
$this->assertEquals(2, $this->tableAltQuery->rows->total());
}
+ /** @test */
+ public function custom_filter()
+ {
+ $this->table->filters['species.name'] = 1;
+
+ $this->assertTrue($this->table->getRowsProperty()->where('name', 'Cartman')->isNotEmpty());
+ $this->assertTrue($this->table->getRowsProperty()->where('name', 'Tux')->isNotEmpty());
+ $this->assertFalse($this->table->getRowsProperty()->where('May', 'Tux')->isNotEmpty());
+ $this->assertFalse($this->table->getRowsProperty()->where('Ben', 'Tux')->isNotEmpty());
+ $this->assertFalse($this->table->getRowsProperty()->where('Chico', 'Tux')->isNotEmpty());
+ }
+
+ /** @test */
+ public function custom_filters_pills_label_use_column_name_when_possible()
+ {
+ config()->set('app.key', Encrypter::generateKey(config('app.cipher')));
+
+ Livewire::test(PetsTable::class)
+ ->set('filters', [
+ 'species.name' => 1,
+ ])
+ ->assertSeeTextInOrder(['Applied Filters:', 'Species:', 'Cat', 'Filters']);
+ }
+
+ /** @test */
+ public function custom_filters_pills_label_use_filter_name_when_is_not_bound_to_a_column()
+ {
+ config()->set('app.key', Encrypter::generateKey(config('app.cipher')));
+
+ Livewire::test(PetsTable::class)
+ ->set('filters', [
+ 'breed_id' => 1,
+ ])
+ ->assertSeeTextInOrder(['Applied Filters:', 'Filter Breed:', 'American Shorthair', 'Filters']);
+ }
+
/** @test */
public function bulk_actions_defined_through_function()
{
diff --git a/tests/Http/Livewire/PetsTable.php b/tests/Http/Livewire/PetsTable.php
index 707290505..564494475 100644
--- a/tests/Http/Livewire/PetsTable.php
+++ b/tests/Http/Livewire/PetsTable.php
@@ -6,9 +6,30 @@
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Tests\Models\Pet;
use Rappasoft\LaravelLivewireTables\Views\Column;
+use Rappasoft\LaravelLivewireTables\Views\Filter;
class PetsTable extends DataTableComponent
{
+ public function filters(): array
+ {
+ return [
+ 'species.name' => Filter::make('Filter Species')->select([
+ '' => 'All',
+ 1 => 'Cat',
+ 2 => 'Dog',
+ 3 => 'Horse',
+ 4 => 'Bird',
+ ]),
+ 'breed_id' => Filter::make('Filter Breed')->select([
+ '' => 'All',
+ 1 => 'American Shorthair',
+ 2 => 'Maine Coon',
+ 3 => 'Persian',
+ 4 => 'Norwegian Forest',
+ ]),
+ ];
+ }
+
public function bulkActions(): array
{
return ['count' => 'Count selected'];
@@ -17,11 +38,13 @@ public function bulkActions(): array
/**
* @return Builder
*/
- public function query() : Builder
+ public function query(): Builder
{
return Pet::query()
->with('species')
- ->with('breed');
+ ->with('breed')
+ ->when($this->getFilter('species.name'), fn (Builder $query, $specimen_id) => $query->where('species_id', $specimen_id))
+ ->when($this->getFilter('breed_id'), fn (Builder $query, $breed_id) => $query->where('breed_id', $breed_id));
}
public function columns(): array