Daniel Plomp
Daniel Plomp
FFilament
Created by Daniel Plomp on 3/22/2024 in #❓┊help
Update two fields after select value changes
I have a Select field which updates the value of a TextArea. The TextArea also updates a second TextArea with it's own value. How can I trigger this event of the first TextArea, when I select a value in my Select?
4 replies
FFilament
Created by Daniel Plomp on 12/22/2023 in #❓┊help
Refresh/Reload Repeater after record create
I have a Page model that has a MorphMany relation with a Url model. I use the saved event when I save a Page model, so that it creates an Url model. This all works okay. Using this mechanism I can create multiple Urls for my Pages and set a primary one. The problem I have is that when I create a Page, validation is fired. So in the database all is created as it should, but then in my Form it show me the Url field which is required. If I close the EditForm, and reopen the record that is previously created, I see that the Repeater has a value. This is the code:
private static function getSectionModelUrls()
{
return Section::make()
->hidden(fn (?Page $record) => $record === null)
->collapsible()
->collapsed()
->heading('Primaire URL en additionele URL\'s')
->schema([
Repeater::make('modelUrls')
->orderColumn('order')
->relationship('modelUrls')
->schema([
TextInput::make('url')
->label(__('strings.fields.slug'))
->required(),
Toggle::make('is_primary')
->label('Primary')
->default(false),
]),
]);
}
private static function getSectionModelUrls()
{
return Section::make()
->hidden(fn (?Page $record) => $record === null)
->collapsible()
->collapsed()
->heading('Primaire URL en additionele URL\'s')
->schema([
Repeater::make('modelUrls')
->orderColumn('order')
->relationship('modelUrls')
->schema([
TextInput::make('url')
->label(__('strings.fields.slug'))
->required(),
Toggle::make('is_primary')
->label('Primary')
->default(false),
]),
]);
}
I thought that hiding the section initially would solve the problem, but when clicking Save in my form, it kind of refreshed the page and shows the section, with a validation error on the Url field. I would like to save the record and then see the repeater appear with the fields that are already in the database.
1 replies
FFilament
Created by Daniel Plomp on 12/14/2023 in #❓┊help
Self-Healing URL's
I use this package to implement 'self-healing urls': https://github.com/lukeraymonddowning/self-healing-urls It functions great and fulfills my website's requirements. One modification I made was to use an alternative ID instead of Laravel's default primaryKey. To accomplish this, I implemented an override:
public function getRouteKeyName(): string
{
return 'public_id';
}
public function getRouteKeyName(): string
{
return 'public_id';
}
In the frontend, everything functions perfectly. The system effectively resolves my models in both directions and automatically corrects URLs. However, I encounter issues in the backend. Although the new URL is visible in my table, clicking on it results in a 404 error. Consequently, navigation to pages such as the edit page is unsuccessful. I am not sure about the next steps to address this issue. My assumption was that Filament adheres to the routing system, but it seems the package might be operating differently. Maybe someone has an idea on to resolve this?
11 replies
FFilament
Created by Daniel Plomp on 12/5/2023 in #❓┊help
Weird issue with navigating through Filament
I have some weird issue with navigation in my Filament application. I sometimes have to click 3 times, before a Resource is loaded, or to save an action. It just loads the page where I'm at, and after 3 times it navigates to the page I wanted to go. Hope that makes sense. But I don't understand what is the issue. There are no console errors and no errors in the log?
7 replies
FFilament
Created by Daniel Plomp on 12/5/2023 in #❓┊help
Create User in Filament and sent verification email
I don't understand what I should be doing to automatically sent a verification email, when I create a User in Filament. I have a simple UserResource that let's me create users. I have implemented the MustVerifyEmail interface on my User model and also setup Mail capabilities. My Laravel project is using JetStream. Also, when trying to reset the password for the current user, through Filament, it says doesn't sent an email to do so. Only if I reset my password from the Laravel Jetstream page, it sent an email. Am I forgetting something? This is in my AdminPanelProvider:
return $panel
->default()
->maxContentWidth('screen-2xl')
->id('admin')
->path('admin')
->login()
->emailVerification()
->profile()
->passwordReset()
return $panel
->default()
->maxContentWidth('screen-2xl')
->id('admin')
->path('admin')
->login()
->emailVerification()
->profile()
->passwordReset()
7 replies
FFilament
Created by Daniel Plomp on 12/1/2023 in #❓┊help
Update TextInput based on Select value
I have two fields:
Select::make('job_salary_type')
->columnSpanFull()
->label(__('strings.fields.job_salary_type'))
->live()
->default(0)
->options([
0 => __('strings.strings.unknown'),
1 => __('strings.strings.monthly'),
2 => __('strings.strings.yearly'),
]),

TextInput::make('job_salary_avg')
->hidden(function ($get) {
return $get('job_salary_type') === 0;
})
->numeric()
->prefix('€')
->label(__('strings.fields.job_salary_avg'))
->helperText(function ($get) {
$helperText = __(
'strings.strings.average_salary',
['type' => __('strings.strings.per_month')]
);
if ($get('job_salary_type') === 2) {
$helperText = __(
'strings.strings.average_salary',
['type' => __('strings.strings.per_year')]
);
}

return $helperText;
}),
Select::make('job_salary_type')
->columnSpanFull()
->label(__('strings.fields.job_salary_type'))
->live()
->default(0)
->options([
0 => __('strings.strings.unknown'),
1 => __('strings.strings.monthly'),
2 => __('strings.strings.yearly'),
]),

TextInput::make('job_salary_avg')
->hidden(function ($get) {
return $get('job_salary_type') === 0;
})
->numeric()
->prefix('€')
->label(__('strings.fields.job_salary_avg'))
->helperText(function ($get) {
$helperText = __(
'strings.strings.average_salary',
['type' => __('strings.strings.per_month')]
);
if ($get('job_salary_type') === 2) {
$helperText = __(
'strings.strings.average_salary',
['type' => __('strings.strings.per_year')]
);
}

return $helperText;
}),
I would expect that the field would hide if I select option 0 in my Select component. This is not happening. Any ideas what I'm missing here?
4 replies
FFilament
Created by Daniel Plomp on 11/21/2023 in #❓┊help
Unique() validation with multiple columns
I have a polymorphic relationship between e.g. a Client and Addresses. I want to be able to add multiple addresses for a Client. There is however a unique constraint on the table that looks like this:
$table->unique(['address_type_id', 'addressable_id', 'addressable_type'], 'unique_addressable');
$table->unique(['address_type_id', 'addressable_id', 'addressable_type'], 'unique_addressable');
This is doing exactly what it should do, but it causes some troubles in the Filament Panel. If I add an address the first time, it is no problem. If I want to add a new address with the same address_type_id I get this error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
Which is also something I would expect. Only it returns in a 500 error. What I want is to get a nice validation error somewhere on my form, presumably with the AddressType Select field. I tried to use this rule:
->unique(ignoreRecord: true)
->unique(ignoreRecord: true)
Then I get a nice validation message below my Select field, but it also triggers when I just update an existing record. Next, I tried this rule:
->unique(ignoreRecord: true, modifyRuleUsing: function (Unique $rule, $state) {
return $rule
->where('addressable_type', Address::class)
->where('address_type_id', $state);
})
->unique(ignoreRecord: true, modifyRuleUsing: function (Unique $rule, $state) {
return $rule
->where('addressable_type', Address::class)
->where('address_type_id', $state);
})
This allows me to update and save my existing record, but still when trying to add a new record with the same Address Type, it gives me this error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
So, I want to know how I can the right validation message inside my form, instead of a 500 error. Not sure if this could work because with new records you only know when inserting them into the database if the fields are unique. How would this work in Filament?
4 replies
FFilament
Created by Daniel Plomp on 10/26/2023 in #❓┊help
Create and Edit from RelationManager without modal
This is probably a question that might be answered somewhere, but I can't find it. I want to create and edit records from a relationmanager, without opening a modal. Just the normal create and edit pages. For both actions I need the parent record to be sent with it. Is this possible?
6 replies
FFilament
Created by Daniel Plomp on 10/18/2023 in #❓┊help
Close modal manually
I have an action that runs some custom code and then saves the record. I want to validate the form first, before executing the code. If the validation fails, I want the modal to close. Right now, it doesn't. Can I trigger this manually?
protected function getHeaderActions(): array
{
return [
\Filament\Actions\Action::make('finish')
->icon('heroicon-o-check-circle')
->label(__('strings.strings.actions.mark_as_resolved'))
->requiresConfirmation()
->color('success')
->action(function ($record, $livewire) {

$livewire->validate(); // This validates the form correctly
//$livewire->dispatchBrowserEvent('close-modal'); ??

$record->status = 'published';
$record->publish_at = now();
$record->staging_vacancy->update(['status' => StagingVacancy::STATUS_REVIEW_FINALIZED]);
$record->save();

$this->redirect(StagingVacancyResource::getUrl());

}),

];
}
protected function getHeaderActions(): array
{
return [
\Filament\Actions\Action::make('finish')
->icon('heroicon-o-check-circle')
->label(__('strings.strings.actions.mark_as_resolved'))
->requiresConfirmation()
->color('success')
->action(function ($record, $livewire) {

$livewire->validate(); // This validates the form correctly
//$livewire->dispatchBrowserEvent('close-modal'); ??

$record->status = 'published';
$record->publish_at = now();
$record->staging_vacancy->update(['status' => StagingVacancy::STATUS_REVIEW_FINALIZED]);
$record->save();

$this->redirect(StagingVacancyResource::getUrl());

}),

];
}
2 replies
FFilament
Created by Daniel Plomp on 9/15/2023 in #❓┊help
Get old state
I have two components in a Form. I can copy the value over from one component to the other. Now I want to have an action to undo this. I tried the following:
->hintAction(
Action::make('undoJobTitle')
->label('Herstel oude waarde')
->icon('heroicon-m-clipboard')
->action(function ($component, $livewire, $state, $set) {

dd($component->getLivewire()->getOldFormState($component->getStatePath()));

})
->hintAction(
Action::make('undoJobTitle')
->label('Herstel oude waarde')
->icon('heroicon-m-clipboard')
->action(function ($component, $livewire, $state, $set) {

dd($component->getLivewire()->getOldFormState($component->getStatePath()));

})
Also, this:
dd($component->getOldState());
dd($component->getOldState());
Both return null after I changed the value of the field. Not sure if I'm doing it right. Maybe I have to save the form first, but that is not what I want. Any ideas?
5 replies
FFilament
Created by Daniel Plomp on 9/14/2023 in #❓┊help
Custom page for resource
Would it be possible to create a custom Resource Page with the same functionality as the EditPage with its own route? I’m trying to have two different ’layouts’ for the EditPage: one for the normal editing of a record and one for e.g. comparing a record with other values. Like a diff. Is something like this possible?
6 replies
FFilament
Created by Daniel Plomp on 8/29/2023 in #❓┊help
Select Component inside helper class is not updated
I have a Select Component for a Form that is inside a helper class. This Select Component is depending on some other values from the Form itself. If I put the Select Component on the Form, use live() on the other components, all works. As soon I move the Select Component to a helper class, it doesn't update anymore. I then first have to save the Form and reload the page.
Select::make('client_id')
->live()
->helperText('De organisatie die deze vacature plaatst')
->options(...)
->searchable()
->preload(),
Select::make('client_id')
->live()
->helperText('De organisatie die deze vacature plaatst')
->options(...)
->searchable()
->preload(),
Updated Select:
Forms\Components\Group::make(fn (Get $get) => [
TemplateHelper::getTemplates($get('client_id'), null, 'null'),
]),
Forms\Components\Group::make(fn (Get $get) => [
TemplateHelper::getTemplates($get('client_id'), null, 'null'),
]),
If I use the Select Component right away, all works fine. Is this by design, or do I forget something?
8 replies
FFilament
Created by Daniel Plomp on 8/25/2023 in #❓┊help
FileUpload inside Builder with SpatieMediaLibrary and AWS S3
I have some issues with the uploading files in combination with the Form Builder. When I use the SpatieMediaLibrary component in my Form, it uploads the image to AWS S3. Only the filename is not being stored inside my Builders Json:
array:3 [▼ // app/Http/Controllers/ClientController.php:34
0 => array:2 [▶]
1 => array:2 [▶]
2 => array:2 [▼
"data" => []
"type" => "image"
]
]
array:3 [▼ // app/Http/Controllers/ClientController.php:34
0 => array:2 [▶]
1 => array:2 [▶]
2 => array:2 [▼
"data" => []
"type" => "image"
]
]
If I use the normal FileUpload component, the data array is filled with the filename. Not sure if I'm missing something?
1 replies
FFilament
Created by Daniel Plomp on 8/22/2023 in #❓┊help
Enable/Disable button dynamically (based on Job Status)
I have created an Action inside my ListPage Header (headerActions). This action is firing a Batch Job. What I really would like is some way to disable the button (and show a loading indicator icon) during the time this job runs. When it is finished, it should be enabled again. Not sure how to achieve this. I can of course check if the job runs and prevent users from starting another one, but it would be nice to make it visible. I tried something with the ->disabled(fn () => $this->checkIfJobIsRunning), but how can I make this dynamic?
/**
* @return bool
* Simple version
*/
protected function checkIfJobIsRunning(): bool
{
$batchName = 'URL check';
$batch = DB::table('job_batches')->where('name', $batchName)->first();

return $batch && ! $batch->cancelled && ! $batch->finished_at;
}
/**
* @return bool
* Simple version
*/
protected function checkIfJobIsRunning(): bool
{
$batchName = 'URL check';
$batch = DB::table('job_batches')->where('name', $batchName)->first();

return $batch && ! $batch->cancelled && ! $batch->finished_at;
}

Any ideas?
54 replies
FFilament
Created by Daniel Plomp on 8/18/2023 in #❓┊help
Custom Page with a Table Resource?
I'd like to know if it is possible to create a custom page which also holds a Table Resource? I want to have some custom actions above a Table and some text.
10 replies
FFilament
Created by Daniel Plomp on 8/16/2023 in #❓┊help
Show modal with infolist or form when clicking on a `suffixAction`
Is it possible to show a modal with an infolist or a form when clicking on a suffixAction? Is there any example for this? Also, I want to see if there is a possibility to just navigate to the Edit Form when clicking on a button in the suffixAction
3 replies
FFilament
Created by Daniel Plomp on 8/14/2023 in #❓┊help
Validate a field inside a modal
I'd like to know if there is a way to validate a field inside a modal window. (which is of course called from an action). I have a Select field that has to be filled in, before executing the action. How can I achieve this? This is my code so far:
Action::make('generate')
->link()
->slideOver()
->icon('heroicon-o-sparkles')
->modalWidth('3xl')
->modalHeading('Generate')
->modalSubmitActionLabel('Save')
->closeModalByClickingAway(false)
->form([
Select::make('prompt')
->label('Prompt')
->required()
->reactive()
->searchable()
->preload()
->options(Prompt::all()->pluck('name', 'id')),

RichEditor::make('job_description_original')
->disableAllToolbarButtons()
->label('Origineel')
->default(fn ($livewire) => $livewire->data['job_description']),
Actions::make([
Action::make('generate_alternative')
->label('Generate')
->action(function ($get, $set, $record, $livewire) {

// MAKE SURE THERE IS A PROMPT SELECTED?

$result = GenerateSummary::make()->handle(
$get('prompt'),
$record->job_title,
$get('job_description_original')
);

$set('job_description_alt', $result);
}),
]),
RichEditor::make('job_description_alt')
->disableAllToolbarButtons()
->hiddenLabel(),
])
->action(function (array $data, $set): void {
$set('job_description', $data['job_description_alt']);
}),
Action::make('generate')
->link()
->slideOver()
->icon('heroicon-o-sparkles')
->modalWidth('3xl')
->modalHeading('Generate')
->modalSubmitActionLabel('Save')
->closeModalByClickingAway(false)
->form([
Select::make('prompt')
->label('Prompt')
->required()
->reactive()
->searchable()
->preload()
->options(Prompt::all()->pluck('name', 'id')),

RichEditor::make('job_description_original')
->disableAllToolbarButtons()
->label('Origineel')
->default(fn ($livewire) => $livewire->data['job_description']),
Actions::make([
Action::make('generate_alternative')
->label('Generate')
->action(function ($get, $set, $record, $livewire) {

// MAKE SURE THERE IS A PROMPT SELECTED?

$result = GenerateSummary::make()->handle(
$get('prompt'),
$record->job_title,
$get('job_description_original')
);

$set('job_description_alt', $result);
}),
]),
RichEditor::make('job_description_alt')
->disableAllToolbarButtons()
->hiddenLabel(),
])
->action(function (array $data, $set): void {
$set('job_description', $data['job_description_alt']);
}),
14 replies
FFilament
Created by Daniel Plomp on 8/12/2023 in #❓┊help
Get value of field within an action
I have a field which uses a hintAction. This action opens a modal window and I want to prefill the field with the value of the component that triggers the action. I though of using fillForm but I don't see how to use e.g. a $get within that function. The documenation shows an example with $this->record but that doesn't work. This is the code:
->form([
RichEditor::make('job_description_original')
->disableAllToolbarButtons()
->label('Origineel')
->afterStateHydrated(function ($get) {
dd($get('job_description')); // returns null?
})
->disabled(),
->form([
RichEditor::make('job_description_original')
->disableAllToolbarButtons()
->label('Origineel')
->afterStateHydrated(function ($get) {
dd($get('job_description')); // returns null?
})
->disabled(),
I also tried to use the default function, which works, but I don't want the default to be the $record value, but the actual value inside the component:
->default(fn ($record) => $record->job_description), // works, but only with $record, not with $get
->default(fn ($record) => $record->job_description), // works, but only with $record, not with $get
What is the best practice in this case?
4 replies
FFilament
Created by Daniel Plomp on 8/11/2023 in #❓┊help
Change the EditAction on a RelationManager
I currently have a relationmanager which uses the static table function from it's resource like this:
public function table(Table $table): Table
{
return VacancyResource::table($table);
}
public function table(Table $table): Table
{
return VacancyResource::table($table);
}
Is it possible to change the EditAction so that when I click on Edit it will navigate to the Edit Page instead of opening a modal window?
7 replies
FFilament
Created by Daniel Plomp on 8/10/2023 in #❓┊help
Translate labels in TextColumn->badge()
I used to have this code in V2:
Tables\Columns\BadgeColumn::make('status')
->getStateUsing(function (Model $record): string {
return $record->status;
})
->label(__('strings.fields.status'))
->icons([
'heroicon-o-x-mark',
'heroicon-o-document' => 'draft',
'heroicon-o-clock' => 'reviewing',
'heroicon-o-check-circle' => 'published',
])
->colors([
'secondary' => 'draft',
'warning' => 'reviewing',
'success' => 'published',
])
->enum([
'draft' => __('strings.statuses.draft'),
'reviewing' => __('strings.statuses.reviewing'),
'published' => __('strings.statuses.published'),
]),
Tables\Columns\BadgeColumn::make('status')
->getStateUsing(function (Model $record): string {
return $record->status;
})
->label(__('strings.fields.status'))
->icons([
'heroicon-o-x-mark',
'heroicon-o-document' => 'draft',
'heroicon-o-clock' => 'reviewing',
'heroicon-o-check-circle' => 'published',
])
->colors([
'secondary' => 'draft',
'warning' => 'reviewing',
'success' => 'published',
])
->enum([
'draft' => __('strings.statuses.draft'),
'reviewing' => __('strings.statuses.reviewing'),
'published' => __('strings.statuses.published'),
]),
Now that the BadgeColumn is deprecated, how can I translate labels as in the example above? There is no enum() method anymore. This is my updated code:
Tables\Columns\TextColumn::make('status')
->label(__('strings.fields.status'))
->badge()
->color(fn (string $state): string => match ($state) {
'draft' => 'secondary',
'reviewing' => 'warning',
'published' => 'success',
})
->icons(['heroicon-o-x-mark',
'heroicon-o-document' => 'draft',
'heroicon-o-clock' => 'reviewing',
'heroicon-o-check-circle' => 'published']),
Tables\Columns\TextColumn::make('status')
->label(__('strings.fields.status'))
->badge()
->color(fn (string $state): string => match ($state) {
'draft' => 'secondary',
'reviewing' => 'warning',
'published' => 'success',
})
->icons(['heroicon-o-x-mark',
'heroicon-o-document' => 'draft',
'heroicon-o-clock' => 'reviewing',
'heroicon-o-check-circle' => 'published']),
5 replies