#create records view. How add another custom button
55 messages · Page 1 of 1 (latest)
You'd need to overwrite the action (or use ->after()) and add an action via ->modalFooterActions()
Can you please share the documentation links for overwrite the action or ->after(). I am not sure which one it is
and you meant extraModalFooterActions, right? https://filamentphp.com/docs/3.x/actions/modals#adding-an-extra-modal-action-button-to-the-footer
Im going to need more help with this. Where do you write this code? In the resource file or one of the page files?
https://filamentphp.com/docs/3.x/actions/modals#adding-an-extra-modal-action-button-to-the-footer
The CreateAction is a in getHeaderActions on the ListPage
Actually. I dont get how this should work.
See screenshot. With or without that code block, I see the same view, with the same "create another" button
On your CreateProducts.php you can add the function
protected function getFormActions(): array
{
return [];
}
https://filamentphp.com/docs/3.x/panels/resources/creating-records#custom-actions
Here the show how to extend the default buttons
How do I keep the cancel button?
I think $this->getCancelFormAction(),
Sorry, thought it's a CreatAction not a page
I finally got something like this
/*
$this->data
array:4 [
"name" => "xxxx"
"category_id" => "1"
"thumbnail" => array:1 [▶]
"variants_outline" => "yyyy"
]
*/
protected function getFormActions(): array
{
return [
Actions\Action::make('Generate Variants')->action('generateVariants'),
Actions\Action::make('Save product')->action('save'),
$this->getCancelFormAction(),
];
}
public function generateVariants(): void
{
print_r($this->data);
}
Now in my generateVariants method, if one of the fields doesnt match a certain format, how can I return validation error?
I think that is just a validation on your form itself right?
What do you mean by "my form"?
Currently in the ProductResource
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Textarea::make('name')
->required()
->columnSpanFull(),
Forms\Components\Select::make('category_id')
->required()
->relationship('category', 'name'),
Forms\Components\FileUpload::make('thumbnail')
->required()
->image(),
Forms\Components\Textarea::make('variants_outline')
->hint('Please outline your product variations in the following format: size:small,large,extra_large;color:red,blue . If the product have no variations, then leave this empty.')
->regex('/[A-Za-z0-9_]+:[A-Za-z0-9_]+(,[A-Za-z0-9_]+)+(;[A-Za-z0-9_]+:[A-Za-z0-9_]+(,[A-Za-z0-9_]+)+)+/i') // Todo: decide to have regex here or in CreateProduct
->columnSpanFull(),
]);
if that answers your q
I bothers me that the handler function generateVariants(): void returns void. So this approach is a dead end if I want validation?
Can you tell a bit what you are exactly trying to acchieve with the function?
You know in a typical eCommerce website, when shopkeeper enters a new product (with variants) in the backoffice,
he enters the product name, desc...
then he write out the product variant's attributes and values,
then he clicks Generate Product Variants button,
then after the backend generates all the variants, the shopkeeper can go in and fill in all the skus, prices, images, ... for all the variants,
then he clicks save, and then the product and its variants are saved to the DB
That's my intention ^
Too much customization for Filament to handle?
Maybe I have to consider using beforeCreate and afterCreate again.
Shopkeeper can generate the variants and save product and variants in the create phase.
Then shopkeeper can then fill in the variant info in the edit phase.
So unless someone have a better idea, that's my plan B
You should use $this->form->getState() and not access $this->data directly.
Have a look at the default save method and copy what you need
That's a limitation you set yourself, right? Because the method was not defined before
True. It doesnt have to be void
Good idea
Good idea. But where is this method?
Should I dig for it in the vendors folder?
Actually I cant find it.
The closest I found is this, which isnt much
protected function getCreateFormAction(): Action
{
return Action::make('create')
->label(__('filament-panels::resources/pages/create-record.form.actions.create.label'))
->submit('create')
->keyBindings(['mod+s']);
}
When you have a good editor or IDE you usually can do a "Symbol search". Open the create page and search for the create method.
It's on the Filament\Resources\Pages\CreateRecord.
Thank you, that really helped
A follow up Q pls. How can you do something like this?
Textarea::make('variants_outline')
->live(debounce: 500)
CreatePage
protected function getCreateFormAction(): Action
{
return parent::getCreateFormAction()
->disabled(fn () => blank($this->data['variants_outline']));
}
Very helpful. Thank you. But getCreateFormAction gets the default save button (wouldnt it?). The "Generate variants" button in my screenshot is a custom button (and event handler function) that I wrote, like this
protected function getFormActions(): array
{
return [
Actions\Action::make('Generate Variants')->action('generateVariants'),
...
];
}
public function generateVariants()
{
}
Shouldn’t it be $this->generateVarients()? Unless the method is a registered action it won’t be available by name. So it needs to be an actual callback.
Not sure if I understood you correctly. But you mean I should disable the "Generate Variant" button in the public function generateVariants() method?
But how do I get a handle on the "Generate Variant" button? I cant use parent::getCreateFormAction() to grab the button
Well, your code doesn’t show anything about the default create action? So not sure I can answer your question. Seems like you are trying to chain onto the create action when an observer / job would make more sense.
But you can override the default save action if you choose to do so. Just make sure you also handle the save logic implicitly.
I am not using getCreateFormAction. Im not planning to use getCreateFormAction, because what Im planning to do is very custom. Both of the first 2 buttons are custom.
This idea looks nice, I just wish to know how to apply it to my case
Heya. My question is quite simple.
In case you misunderstood my question to be something more complicated, I'll ask another way:
If this is how you disable the default save button getCreateFormAction()->disabled(true), then how can you disable a custom button?
You provide a callback function to the ->disabled() method.
The code you have been sharing doesn’t align to the questions you are asking. So it’s difficult for us to give you an answer.
Ok. I hope this helps
generateVariants isn't registered as an action so you can't call it by name.
->action($this->generateVariants())
So $this->action($this->generateVariants()) this is the only way to "get a handle" on my custom generate variants button?
did I understand you right?
Did you try it? Does it even work?
Actually no. I looked at my code again. There is no place to put such codes. Im open to other ideas
protected function getFormActions(): array
{
return [
Actions\Action::make('Generate Variants')->action(
self::generateVariants();
),
...
];
}
public static function generateVariants()
{
}
I think like this?
This is just a syntax change
But on a positive note, I finally figured out where and how to disable custom buttons
protected function getFormActions(): array
{
return [
Actions\Action::make('Generate Variants')->action('generateVariants')->disabled(true),
Thank you. I finally figured out how to apply this. It worked
In CreateProduct page, I did
protected function getFormActions(): array
{
return [
Actions\Action::make('Generate Variants')->action('generateVariants')->disabled(fn () => blank($this->data['variants_outline'])),
In the ProductResource I did
class ProductResource extends Resource
{
protected static ?string $model = Product::class;
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Textarea::make('variants_outline')
->live(debounce: 500),