Own filters
A filter of your own extends Anvil\Collection\Filters\Filter: it
declares its inputs and their rules, turns them into a value, applies the
value to the query and renders the control.
php spark make:anvil-filter MinimumAmountnamespace App\Filters;
use Anvil\Collection\Filters\Filter;use Anvil\Data\Model;
final class MinimumAmount extends Filter{ public function rules(): array { return [$this->inputName() => ['permit_empty', 'is_natural']]; }
public function value(array $input): ?string { $value = self::input($input, $this->inputName());
return $value === '' ? null : $value; }
public function apply(Model $model, array|string $value): void { $model->where($this->qualifiedColumn($model) . ' >=', $value); }
protected function view(): string { return 'filters/minimum_amount'; }}<input type="number" min="0" class="form-control w-auto" name="<?= esc($filter->inputName(), 'attr') ?>" value="<?= esc((string) ($value ?? ''), 'attr') ?>" aria-label="<?= esc($filter->getLabel(), 'attr') ?>" placeholder="<?= esc($filter->getLabel(), 'attr') ?>" hx-post="<?= esc($endpoint, 'attr') ?>" hx-sync="closest form:replace" <?= $swap ?> hx-trigger="change">Methods
Section titled “Methods”| Method | Purpose |
|---|---|
rules() |
input name => validation rules. Only these inputs reach the filter; invalid input is rejected with 422 |
value(array $input) |
the active value from the validated input (a string or an array of strings), null when the filter is not set |
apply(Model $model, $value) |
adds the conditions to the query |
view() |
the view of the control: a full view name such as filters/minimum_amount |
toInput($value) |
inverse of value(): the inputs that lead to a value; needed for filters with several inputs or formatted values, so saved views can be applied |
Helpers of Filter: inputName('suffix') (filter_<name>_<suffix>),
qualifiedColumn($model) (table.column), self::input($input, $name)
(a trimmed string).
The view
Section titled “The view”It receives $filter, $value (the active value or null), $endpoint
and $swap. Every input must carry
hx-post="<?= esc($endpoint, 'attr') ?>" hx-sync="closest form:replace" <?= $swap ?> hx-trigger="change"so a change reloads the list. Escape every value; no inline styles or scripts.
- Use the query builder in
apply()with the validated value; never build SQL from input. - Keep
value()strict: returnnullfor anything that is not a valid value. - A value that is an array (ranges) must have string values; it is stored in saved views as it is.
More: Extending Anvil.