Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як створити власне поле форми Filament і правильно прив'язати його стан?

Власне поле потрібне, коли жоден вбудований компонент не підходить: вибір точки на карті, редактор розкладу, інтеграція сторонньої JS-бібліотеки.

php artisan make:filament-form-field LocationPicker

Клас поля:

use Closure;
use Filament\Forms\Components\Field;

class LocationPicker extends Field
{
    protected string $view = 'filament.forms.components.location-picker';

    protected float | Closure | null $zoom = null;

    public function zoom(float | Closure | null $zoom): static
    {
        $this->zoom = $zoom;

        return $this;
    }

    public function getZoom(): ?float
    {
        return $this->evaluate($this->zoom);   // підтримка замикань з утилітами
    }
}

Шаблон поля:

<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
    <div
        x-data="{ state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$getStatePath()}')") }} }"
        x-init="initMap($refs.map, state, {{ $getZoom() ?? 10 }})"
    >
        <div x-ref="map" class="h-64"></div>
    </div>
</x-dynamic-component>

Ключові моменти:

  • $getStatePath() - шлях до властивості Livewire, де живе значення поля (data.location). Саме через нього поле читає й пише стан;
  • $applyStateBindingModifiers() - щоб поле поважало live(), live(onBlur: true) тощо, як вбудовані. Без цього ->live() на вашому полі нічого не змінить;
  • $getFieldWrapperView() - стандартна обгортка з підписом, підказкою й помилками валідації;
  • $this->evaluate() в гетері - дозволяє передавати не лише значення, а й замикання з Get, $record, $operation.

Чого не робити:

  • поле - не Livewire-компонент. Публічні властивості й методи класу поля в Blade недоступні як wire:model чи wire:click. Потрібну конфігурацію віддають через гетери ($getZoom());
  • щоб викликати PHP-метод поля з JavaScript, його позначають атрибутом #[ExposedLivewireMethod] і викликають через $wire.callSchemaComponentMethod(). Без атрибута метод викликати не можна - це захист від виконання довільних методів;
  • важкі JS-бібліотеки не варто підключати глобально на кожну сторінку панелі - Filament уміє асинхронно завантажувати Alpine-компоненти через систему ресурсів, лише там, де поле є.

Валідація працює як для будь-якого поля: ->required(), ->rules([...]) на рівні PHP.

Докладніше в документації: Власні поля

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання