Skip to content

Commit

Permalink
Select filters can select multiple values (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
ramonrietdijk committed Oct 15, 2023
1 parent 6e72ca1 commit 5fb99ee
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 3 deletions.
13 changes: 13 additions & 0 deletions docs/usage/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,25 @@ protected function filters(): array

Currently, there are 3 different filter types available.

### Boolean Filter

Booleans can be filtered using the `BooleanFilter`.

```php
BooleanFilter::make(__('Published'), 'published'),
```

### Date Filter

If you are working with dates, a `DateFilter` should be used. This filter will give you a `from` and `to` date to filter
your records with.

```php
DateFilter::make(__('Created At'), 'created_at'),
```

### Select Filter

When a filter can only accept a list of values, you may be interested in the `SelectFilter`. With this filter you can
specify the options that can be used. You will get a dropdown of options to choose from to filter your records.

Expand All @@ -42,6 +48,13 @@ SelectFilter::make(__('Category'), 'category_id')
]),
```

By calling the `multiple` method on the filter, it will accept multiple values at a time.

```php
SelectFilter::make(__('Category'), 'category_id')
->multiple(),
```

## Relations

If you wish to filter data from a related model, you can prefix the column with the name of the relations. Always use
Expand Down
11 changes: 9 additions & 2 deletions resources/views/filters/select.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
{{ $filter->label() }}
</span>
<select class="w-full border border-neutral-200 rounded-md shadow-sm outline-none bg-white text-black focus:border-blue-300 mr-auto px-3 py-2 font-normal transition ease-in-out dark:bg-neutral-900 dark:border-neutral-700 dark:focus:border-blue-600 dark:text-white"
wire:model.live="filters.{{ $filter->code() }}">
<option value="">&mdash;</option>
wire:model.live="filters.{{ $filter->code() }}"

@if($filter->isMultiple())
multiple
@endif
>
@if(! $filter->isMultiple())
<option value="">&mdash;</option>
@endif
@foreach($filter->getOptions() as $value => $label)
<option value="{{ $value }}">{{ $label }}</option>
@endforeach
Expand Down
20 changes: 20 additions & 0 deletions src/Concerns/CanBeMultiple.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace RamonRietdijk\LivewireTables\Concerns;

trait CanBeMultiple
{
protected bool $multiple = false;

public function multiple(bool $multiple = true): static
{
$this->multiple = $multiple;

return $this;
}

public function isMultiple(): bool
{
return $this->multiple;
}
}
6 changes: 5 additions & 1 deletion src/Filters/Concerns/HasFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ public function filterUsingCallback(): ?Closure
public function filter(Builder $builder, mixed $value): void
{
$builder->when(! blank($value), function (Builder $builder) use ($value): void {
$builder->where($this->qualify($builder), '=', $value);
if (is_array($value)) {
$builder->whereIn($this->qualify($builder), $value);
} else {
$builder->where($this->qualify($builder), '=', $value);
}
});
}

Expand Down
2 changes: 2 additions & 0 deletions src/Filters/SelectFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace RamonRietdijk\LivewireTables\Filters;

use RamonRietdijk\LivewireTables\Concerns\CanBeMultiple;
use RamonRietdijk\LivewireTables\Concerns\HasOptions;

class SelectFilter extends BaseFilter
{
use CanBeMultiple;
use HasOptions;

protected string $view = 'livewire-table::filters.select';
Expand Down
21 changes: 21 additions & 0 deletions tests/Unit/Concerns/CanBeMultipleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace RamonRietdijk\LivewireTables\Tests\Unit\Concerns;

use RamonRietdijk\LivewireTables\Filters\SelectFilter;
use RamonRietdijk\LivewireTables\Tests\TestCase;

class CanBeMultipleTest extends TestCase
{
/** @test */
public function it_can_be_multiple(): void
{
$filter = SelectFilter::make('Name', 'name');

$this->assertFalse($filter->isMultiple());

$filter->multiple(true);

$this->assertTrue($filter->isMultiple());
}
}
17 changes: 17 additions & 0 deletions tests/Unit/Filters/Concerns/HasFilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,23 @@ public function it_can_filter(): void
$this->assertEquals(1, $builder->count());
}

/** @test */
public function it_can_filter_with_arrays(): void
{
User::factory()->create(['name' => 'John Doe']);
User::factory()->create(['name' => 'Jane Doe']);
User::factory()->create(['name' => 'Richard Doe']);

$filter = SelectFilter::make('Name', 'name')->multiple();

/** @var Builder<Model> $builder */
$builder = User::query();

$filter->filter($builder, ['John Doe', 'Jane Doe']);

$this->assertEquals(2, $builder->count());
}

/** @test */
public function it_can_apply_filtering(): void
{
Expand Down

0 comments on commit 5fb99ee

Please sign in to comment.