Filament Form Builder in the frontend
Good morning everyone.
I'm new to this discord server.
I created a backend for managing books.
Now I have to create the frontend which must present a form for searching for books. Is it possible to use the form builder components in the frontend? For example the select? You can help me? Thank you very much
53 Replies
Yes, In the "Installation" of form builder https://filamentphp.com/docs/3.x/forms/installation it's written "This guide is for using the Form Builder in a custom TALL Stack application (Tailwind, Alpine, Livewire, Laravel)."
Thanks @Vp I use the version 2.x. I have create a livewire component for book search. How do I use filament selects in the livewire view?
Oh, read this page.. I think you'll have an idea https://filamentphp.com/docs/2.x/forms/getting-started
Thank you! Is there a select with search in version 2.x?
Yes
->searchable() It doesn't work for me
See:
https://filamentphp.com/docs/2.x/forms/fields#select
It should if you have the datasets and it's built correctly.
With this code the select is populated correctly
protected function getFormSchema(): array
{
return [
Select::make('book_id')
->options(Genre::all()->pluck('name', 'id'))
->label('Genere')
];
}
With this code
protected function getFormSchema(): array
{
return [
Select::make('book_id')
->options(Genre::all()->pluck('name', 'id'))
->label('Genere')
->searchable()
];
}
I have thischange: ->options(Genre::all()->pluck('name', 'id'))
to
->options(fn() => Genre::all()->pluck('name', 'id'))
I would also dd on that Genre::all pluck and see what it returns as it looks empty there.
The problem remains π¦ Genre is not empty
in the browser console I have this error: selectFormComponent is not defined
This looks like you didn't install correctly. Did you follow this https://filamentphp.com/docs/2.x/forms/installation?
But in the backend it works fine
Yes, but check docs, it's written this "The form builder comes pre-installed inside the admin panel 2.x, but you must still follow the installation instructions below if you're using it in the rest of your app."
Ohh so the backend works fine and the frontend doesn't. That's clearly just not installed correctly.
ok, thank you very much! Tha last question...
Now i have this
How can I arrange the form on multiple columns?
In the backend I know how to do it, but here??
protected function getFormSchema(): array
{
return [
Select::make('genre_id')
->options(Genre::all()->pluck('name', 'id'))
->label('Genere')
->searchable()
->placeholder('Seleziona un genere'),
Select::make('era_id')
->options(Era::all()->pluck('name', 'id'))
->label('Epoca')
->searchable()
->placeholder('Seleziona un epoca'),
Select::make('place_id')
->options(Place::all()->pluck('name', 'id'))
->label('Luogo')
->searchable()
->placeholder('Seleziona un luogo'),
Select::make('author_id')
->options(Author::all()->pluck('name', 'id'))
->label('Autore')
->searchable()
->placeholder('Seleziona un autore'),
Select::make('specific_id')
->options(Specific::all()->pluck('name', 'id'))
->label('Tags')
->searchable()
->multiple()
->placeholder('Seleziona un tag'),
];
}
The Same.
Read the link I sent you.
Sorry but i don't understand... in this mode the form is invisible...
public static function form(Form $form): Form
{
return $form
->schema([
Select::make('genre_id')
->options(Genre::all()->pluck('name', 'id'))
->label('Genere')
->searchable()
->placeholder('Seleziona un genere'),
Select::make('era_id')
->options(Era::all()->pluck('name', 'id'))
->label('Epoca')
->searchable()
->placeholder('Seleziona un epoca'),
Select::make('place_id')
->options(Place::all()->pluck('name', 'id'))
->label('Luogo')
->searchable()
->placeholder('Seleziona un luogo'),
Select::make('author_id')
->options(Author::all()->pluck('name', 'id'))
->label('Autore')
->searchable()
->placeholder('Seleziona un autore'),
Select::make('specific_id')
->options(Specific::all()->pluck('name', 'id'))
->label('Tags')
->searchable()
->multiple()
->placeholder('Seleziona un tag'),
])->columns(2);
}
Do you click the link I sent you?
yes
It explains it, so for the shcema markup you need to use the Grid::make(2)->schema([]) field
Thank you so much
Sorry, I have another question... how do I view search results on another page?
I don't know what you mean sorry
do you mean view/edit individual results on a new page?
I'm researching a book. I would like to see the search results on a dedicated page, what can I do?
Sorry that's not possible, you see the results on the current page because that's the best UX and how Livewire generally works
Can't you pass an array to another Livewire component?
Of course you can, but you are saying you want the search results which would mean you need to override the search results from the table to redirect to a new page everytime it is searched.
Unless you haven't explained yourself properly?
I think I didn't explain myself well, sorry. In the frontend I have this:
on submit:
public function submit()
{
$bookQuery = Book::query();
if ($this->genre_id) {
$bookQuery->where('genre_id', $this->genre_id);
}
if ($this->era_id) {
$bookQuery->where('era_id', $this->era_id);
}
if ($this->place_id) {
$bookQuery->where('place_id', $this->place_id);
}
if ($this->author_id) {
$bookQuery->where('author_id', $this->author_id);
}
if (!empty($this->specific_id)) {
$bookQuery->join('book_specific', 'books.id', '=', 'book_specific.book_id')
->whereIn('book_specific.specific_id', $this->specific_id)
->groupBy(
'books.id',
'books.title',
'books.plot',
'books.author_id',
'books.era_id',
'books.genre_id',
'books.place_id',
'books.seo_title',
'books.seo_description',
'books.seo_keywords',
'books.created_at',
'books.updated_at',
'book_specific.id',
'book_specific.book_id',
'book_specific.specific_id',
'book_specific.created_at',
'book_specific.updated_at'
)
->havingRaw('COUNT(DISTINCT book_specific.specific_id) = ?', [count($this->specific_id)]);
}
$bookResult = $bookQuery->get();
if($bookResult->count() > 0) {
$this->emitTo('searchResult', 'bookSearchResult', $bookResult);
} else {
$this->emitTo('searchResult', 'bookSearchResult', 'Nessun libro trovato');
}
//reset filament form
$this->reset();
}
in the livewire searchResult component I have this:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class SearchResult extends Component
{
public $searchResult;
//listener bookSearchResult
protected $listeners = [
'bookSearchResult' => 'bookSearchResult',
];
public function bookSearchResult($searchResult)
{
$this->searchResult = $searchResult;
return view('livewire.search-result',
[
'searchResult' => $this->searchResult
]
);
}
// public function render()
// {
// return view('livewire.search-result',
// [
// 'searchResult' => $this->searchResult
// ]
// );
// }
}
but in the livewire.search-result view the $searchResult array is nullRight, so you are using a form to generate a search. Why not just use a table with this form above and render the table on search?
That form can be the search form too on top of the table and integrated as one
Because I would like to have a results page formatted like a "blog". In any case, then I must have the page of the single book
You can do that with the Table using https://filamentphp.com/docs/3.x/tables/layout#arranging-records-into-a-grid
But otherwise you can? Otherwise just build your own livewire results page
ok, but when the page loads you would immediately see the empty table, right?
Yes, that usually makes sense so they see the latest, then they can filter the results down.
ok, now I'll try to put the table
If you use the table and use the filter form, the docs explain very well the filter form
OK thank you. I hope I don't bother you again, but it's likely π
No problem
I already have the first problem...
App\Http\Livewire\BookSearch::getTableQuery(): Return value must be of type Filament\Forms\Components\Builder, Illuminate\Database\Eloquent\Builder returned
no, it's ok
use Filament\Forms\Components\Builder;
not
use Illuminate\Database\Eloquent\Builder;
One question... Can the outer border of the table be removed?
I currently have this
How do I open a book tab another page by clicking on a table row?
This is all in the docs, please read them. You can open ->url() but personally Iβd use an action with a modal slideOver if itβs just to book simply