rappasoft / laravel-livewire-tables

A dynamic table component for Laravel Livewire
https://rappasoft.com/docs/laravel-livewire-tables/v2/introduction
MIT License
1.74k stars 329 forks source link

Filter with value "0" clears out the filter. #265

Closed shawnholman closed 3 years ago

shawnholman commented 3 years ago

Hey! There is a bug when selecting filters. Whenever creating a filter with options where one option's value is "0" selecting that filter will cause the "All" selection to be used.

public function filters(): array
    {
        return [
            'deaf_blind_project_exiting_status' =>
                Filter::make('Status')
                    ->select([
                        '' => 'Any',
                        0 => 'Option 1',
                        1 => 'Option 2',
                        2 => 'Option 3',
                    ]),
        ];
    }

The following code will create a filter with four options: Any, Option 1, Option 2, and Option 3. Selecting 'Option 1', gives the same filtering results as just selecting "Any".

rappasoft commented 3 years ago

Can recreate. Will try to fix.

shawnholman commented 3 years ago

Thank you! This has been a really useful project for me. I really appreciate the recent updates that you have done. Keep up the great work!

rappasoft commented 3 years ago

This is apparently more complicated than anticipated since zero in PHP pretty much becomes false in any check. I have to modify the way filters work in general to support numeric keys or string keys that are numbers. @bdelamatre worked on a lot of filters maybe he has a better way.

I do have it working on this new branch: https://github.com/rappasoft/laravel-livewire-tables/commit/18ef6084ee4b890b5654ba3b13c7af216d065b92

However using ->when() in the eloquent query still returns false if $this->getFilter('') returns 0 or "0" as a key. Which is a problem because essentially the 0 key will never get called because it just thinks it's false.

If we explicitly check it works:

public function query(): Builder
{
    $query = User::with('attributes', 'parent')
        ->when($this->getFilter('email'), fn ($query, $email) => $email === 'yes' ? $query->whereNotNull('email') : $query->whereNull('email'));

    if ($this->hasFilter('verified')) { // 0 will not return false
        if ($this->getFilter('verified') === '1') {
            $query = $query->whereNotNull('email_verified_at');
        } else {
            $query = $query->whereNull('email_verified_at');
        }
    }

    return $query;
}

Which might be what we have to do and I'll just document it.

rappasoft commented 3 years ago

Fixed in latest release.