Get the titles of fields in indicators for filter with form (schema)

I have this code
Tables\Filters\Filter::make('state_district')
->form([
Forms\Components\Select::make('state_id')
->preload()
->options(State::pluck('name', 'id'))
->searchable(),

Forms\Components\Select::make('district_id')
->preload()
->relationship('district', 'name', fn($query, $get) => $query->where('state_id', $get('state_id')))
->searchable(),
])
->query(fn($query, array $data) => $query->when($data['state_id'], fn($query) => $query->where('state_id', $data['state_id']))
->when($data['district_id'], fn($query) => $query->where('district_id', $data['district_id'])))
->indicateUsing(fn($data) => State::find($data['state_id'])->name . ' - ' . District::find($data['district_id'])->name)
Tables\Filters\Filter::make('state_district')
->form([
Forms\Components\Select::make('state_id')
->preload()
->options(State::pluck('name', 'id'))
->searchable(),

Forms\Components\Select::make('district_id')
->preload()
->relationship('district', 'name', fn($query, $get) => $query->where('state_id', $get('state_id')))
->searchable(),
])
->query(fn($query, array $data) => $query->when($data['state_id'], fn($query) => $query->where('state_id', $data['state_id']))
->when($data['district_id'], fn($query) => $query->where('district_id', $data['district_id'])))
->indicateUsing(fn($data) => State::find($data['state_id'])->name . ' - ' . District::find($data['district_id'])->name)
a filter with a form (schema) and a custom query. Why can't I get the name directly in indicator from the form and have it appear in the indicators? Why should I make new queries just to get the names that are already chosen in the fields of the filter? can I make a PR for that?
2 Replies
Adam
Adam4mo ago
If you pass the Filter class to the indicateUsing method, you can access the form schema with getFormSchema. From here you can get the individual Select components and their list of options via getOptions. You can then get the option label/title by passing in the $data['state_id'] or $data['district_id']. Please see below:
Filter::make('state_district')
->indicateUsing(function(Filter $filter, array $data): string {
$formSchema = collect($filter->getFormSchema());
$stateOptions = $formSchema->first()->getOptions();
$districtOptions = $formSchema->last()->getOptions();

return $stateOptions[$data['state_id']] . ' - ' . $districtOptions[$data['district_id']];
});
Filter::make('state_district')
->indicateUsing(function(Filter $filter, array $data): string {
$formSchema = collect($filter->getFormSchema());
$stateOptions = $formSchema->first()->getOptions();
$districtOptions = $formSchema->last()->getOptions();

return $stateOptions[$data['state_id']] . ' - ' . $districtOptions[$data['district_id']];
});
This is a simple and crude example, but hopefully it gives you an idea. I did something similar but with a custom filter class instead.
Hasan Tahseen
Hasan TahseenOP4mo ago
Thanks. Your solution is good but doesn't work for the select field with the relationship method because the options will now load until the user search for it I manage to solve it using some alpine and livewire stuff its bad technique from me but I didn't find better one
->extraAttributes([
"@change" => "() => {
\$wire.set('stateFilterLabel', \$event.target.innerText, false);
}",
])
->afterUpdateResetField('tableDeferredFilters.state_district.district_id')
->searchable(),

Forms\Components\Select::make('district_id')
->label('الحي أو المنطقة')
->preload()
->extraAttributes([
"@change" => "() => {
\$wire.set('districtFilterLabel', \$event.target.innerText, false);
}",
])
->extraAttributes([
"@change" => "() => {
\$wire.set('stateFilterLabel', \$event.target.innerText, false);
}",
])
->afterUpdateResetField('tableDeferredFilters.state_district.district_id')
->searchable(),

Forms\Components\Select::make('district_id')
->label('الحي أو المنطقة')
->preload()
->extraAttributes([
"@change" => "() => {
\$wire.set('districtFilterLabel', \$event.target.innerText, false);
}",
])
this is the code with some properties in the page
->indicateUsing(function ($livewire) {
if (is_null($livewire->tableFilters['state_district']['state_id'])) {
$livewire->reset(['stateFilterLabel']);
}

if (is_null($livewire->tableFilters['state_district']['district_id'])) {
$livewire->reset(['districtFilterLabel']);
}

$stateFilterLabel = $livewire->stateFilterLabel;

$districtFilterLabel = $livewire->districtFilterLabel;

$indicator = '';

if ($stateFilterLabel) {
$indicator .= "المحافظة: {$stateFilterLabel}, ";
}
if ($districtFilterLabel) {
$indicator .= "المنطقة: {$districtFilterLabel}";
}

return $indicator;
})
->indicateUsing(function ($livewire) {
if (is_null($livewire->tableFilters['state_district']['state_id'])) {
$livewire->reset(['stateFilterLabel']);
}

if (is_null($livewire->tableFilters['state_district']['district_id'])) {
$livewire->reset(['districtFilterLabel']);
}

$stateFilterLabel = $livewire->stateFilterLabel;

$districtFilterLabel = $livewire->districtFilterLabel;

$indicator = '';

if ($stateFilterLabel) {
$indicator .= "المحافظة: {$stateFilterLabel}, ";
}
if ($districtFilterLabel) {
$indicator .= "المنطقة: {$districtFilterLabel}";
}

return $indicator;
})
and this

Did you find this page helpful?