Filament Plugins

Purchase

Table

The Record Finder will be provided as a form component that you can use in any of your forms:

php
use RalphJSmit\Filament\RecordFinder\Forms\Components\RecordFinder;

RecordFinder::make('product_id')
    ->label('Product')

The Record Finder component will show a button to choose/select records. Clicking the button will open a full modal or slide-over with a table.

Specifying table query

You can provide a query to the table using the ->tableQuery() (or alias ->query()) method. The method accepts a query, a Relation or a closure that returns a query or a Relation. For example:

php
RecordFinder::make('product_id')
    ->tableQuery(Product::query())
    ->query(Filament::getTenant()->products()) // Alias `query()` for convenience...

Of course, you can provide any constraints to your query that you want:

php
RecordFinder::make('post_id')
    ->query(fn (User $record) => Post::query()->whereBelongsTo($record))

Relationships

You can integrate the RecordFinder also very easily into a relationship using the ->relationship() method. This will automatically adjust the query to the relationship and save the selected record(s) to the relationship. For example:

php
RecordFinder::make('product_id')
    ->relationship(name: 'products')

If you want to integrate with a BelongsToMany relationship, you can use the ->multiple() method in combination with ->relationship():

php
RecordFinder::make('products')
    ->multiple()
    ->relationship()

When using ->disabled() with ->multiple() and ->relationship(), ensure that ->disabled() is called before ->relationship(). This ensures that the dehydrated() call from within relationship() is not overridden by the call from disabled(). This works the same as with the regular Select component:

php
RecordFinder::make('products')
    ->multiple()
    ->disabled()
    ->relationship()

Attaching pivot table

You can also attach pivot data if you want:

php
RecordFinder::make('products')
    ->multiple()
    ->relationship()
    ->pivotData(function (Forms\Get $get) {
        return [...];
    })

If you're building a form inside your Livewire component, make sure you have set up the form's model. Otherwise, the RecordFinder doesn't know which model to use to retrieve the relationship from.

The ->relationship() support is identical to the native Filament Select implementation. Don't be afraid to just simply replace Select by RecordFinder, remove the option label method calls (if present) and you should be good to go!

Excluding the current record

When working with recursive relationships, you will likely want to remove the current record from the set of results. This can easily be done using the ignoreRecord argument to the ->relationship() method:

php
RecordFinder::make('parent_id')
    ->relationship('parent', ignoreRecord: true)

Customizing the relationship query

You may customize the database query that retrieves options using the modifyQueryUsing parameter of the ->relationship() method:

php
RecordFinder::make('products')
    ->multiple()
    ->relationship('products', function (Builder $query) {
        return $query->whereBelongsTo(Filament::getTenant())->withTrashed();
    })

Customizing the table

The table shown inside the Record Finder modal is fully customizable — you can configure its columns, filters, groups, actions and pagination.

Columns

You can provide columns to the table using the ->tableColumns() (or alias ->table()) method:

php
use Filament\Tables;

RecordFinder::make('product_id')
    ->tableStandalone() // Ensure table configuration starts empty...
    ->tableColumns([
        Tables\Columns\TextColumn::make('tenant.name'),
        Tables\Columns\TextColumn::make('name')
            ->description(fn (Product $product) => $product->description),
    ])
    // Alias `table()` for convenience...
    ->table([...])

Note regarding closures: the package supports using closures everywhere as you are normally used to. This means that you can just use closures to inject the current $record, the current $column, the current $livewire or any other parameter that Filament provides. The only limitation is that you cannot reference the variable $this or static (in the sense of static::someMethod()) inside your closures. However, this has never been recommended practice and you wouldn't normally ever need to use $this, since all relevant parameters can be injected by Filament as a closure parameter. If you want to force yourself not to use these, you can make a habit of writing every closure as a static function or static fn () => ....

Getting columns from the resource

By default, if you do not provide any columns to the ->table() method, the Record Finder will automatically check which Eloquent model the table query is querying. If that model has a resource in the current panel, then the Record Finder will automatically use the table configuration from that particular resource.

Said differently, if you do not provide a custom table configuration (like columns, groups and filters), the Record Finder will automatically take these from how you configured them on your resource. This has the benefit that in most cases the table in the selection modal will look identical to the resource in your app. For users this can be a great UX, since they are already familiar with the table from the resource and most of the time there is no real reason to deviate from that in the record finder. It is also beneficial for you as a developer, because you don't need to repeat common configuration like columns, groups and filters.

The only exception is that all types of actions are not automatically taken from the resource. If you want to add any of these, use the ->tableHeaderActions(), ->tableActions() or ->tableEmptyStateActions().

If you want to disable this behaviour, you can use the ->tableStandalone() (or alias ->standalone()) method. This will ensure you'll start with a fresh table:

php
RecordFinder::make('product_id')
    ->tableStandalone()
    ->standalone() // Alias for convenience...
    ->tableColumns([
        TextColumn::make('name'),
        // ...
    ])
    // ...

Filters

You can add table filters by using the ->tableFilters() method. This allows you to easily add functionality to filter records from the table. For example:

php
RecordFinder::make('product_id')
    ->tableFilters([
        Tables\Filters\TernaryFilter::make('is_public'),
    ])

Groups

You can provide table groups using the ->tableGroups() method.

php
RecordFinder::make('product_id')
    ->tableGroups([
        'category.name',
        Tables\Grouping\Group::make('category.name'),
    ])

You can set the default group using the ->tableDefaultGroup() method:

php
RecordFinder::make('product_id')
    ->tableGroups(['category.name'])
    ->tableDefaultGroup('category.name')

You can hide the grouping settings using the ->tableGroupingSettingsHidden() method:

php
RecordFinder::make('product_id')
    ->tableGroups(['category.name'])
    ->tableDefaultGroup('category.name')
    ->tableGroupingSettingsHidden()

This works great if you want to always group a table by default on e.g. category and not allow the end user to change the grouping.

Actions

You can add actions to the table using the ->tableHeaderActions(), ->tableActions(), ->tableBulkActions() and ->tableEmptyStateActions() methods. This allows you to easily add functionality to create, edit or delete records from the table. For example:

php
use Filament\Tables;

RecordFinder::make('author_id')
    ->tableHeaderActions([
        Tables\Actions\Action::make('your_header_action')
    ])
    ->tableActions([
        Tables\Actions\Action::make('your_action'),
    ])
    ->tableBulkActions([
        Tables\Actions\BulkAction::make('your_bulk_action')
    ])
    ->tableEmptyStateActions([
        Tables\Actions\Action::make('your_empty_state_action'),
    ])

Pagination

You can set the available pagination page options by using the ->tablePaginationPageOptions() method:

php
RecordFinder::make('product_id')
    ->tablePaginationPageOptions([10, 25, 50, 100])

Modifying the underlying table

You can modify the underlying table object in the Record Finder by passing a closure to the modifyTableUsing() method and returning the modified table:

php
RecordFinder::make('product_id')
    ->tableGroups([
        'category.name'
    ])
    ->modifyTableUsing(function (Table\Table $table) {
        // Nice example: force a certain group to be applied always and disallow the user to select a group.
        $table->defaultGroup('category.name')->groupingSettingsHidden();
    })
© FilamentPlugins.com ✦ 2022 – 2026
PrivacyTerms & Conditions
All rights reserved.