Alexandre
Alexandre
FFilament
Created by Alexandre on 9/10/2024 in #❓┊help
TextInputColumn (date) submit too fast
Hi all 👋 I have a resource with an “expiry date” table. To go faster, I wanted to add a TextInputColumn to my table so that I could just change the date without having to go through a modal or an edit page. So I did the following:
Tables\Columns\TextInputColumn::make('expiration_date')
->label('Expiration date')
->placeholder('-')
->type('date')
->toggleable()
->rules(['nullable', 'date'])
->sortable(),
Tables\Columns\TextInputColumn::make('expiration_date')
->label('Expiration date')
->placeholder('-')
->type('date')
->toggleable()
->rules(['nullable', 'date'])
->sortable(),
It works, on my table I now have a text field with a calendar available. The problem is that as soon as I start to change a date (if I type a number in the field, for example, or select a day in the calendar) the value is updated directly in the DB, which is a bit annoying because I haven't necessarily finished editing (let's say I want to type day 20, the value is updated as soon as I type 2). Is there a method I can add to avoid this? Thanks in advance.
9 replies
FFilament
Created by Alexandre on 9/3/2024 in #❓┊help
Incremental itemLabel for repeater
Hello everyone. 👋 I know this question has already been asked several times, but I haven't found any answers... Basically my question is simple: I'm creating a form with a repeater (questions). In this repeater, I've a second one (answers). And I want to put an itemLabel in this second repeater with an incremental number (Answer 1, Answer 2, Answer 3, etc.).
Repeater::make('questions')
->itemLabel(function () {
static $position = 1;
return 'Question n°'.$position++;
})
->schema([
textInput::make('title')
->required(),
Select::make('need_id')
->options(Need::all()->pluck('name', 'id'))
->required(),
Repeater::make('answers')
->itemLabel(function ($component, array $state, callable $get) {
$answers = $get('answers');
$answerKeys = array_keys($answers);

/*And now, I don't know what to do. How to get the current index of actual answer but without uuid ?*/

return 'Réponse n°';
})
->hiddenLabel()
->schema([
TextInput::make('title')
->required(),
TextInput::make('ratio')
->numeric()
->suffix('%')
->default('20')
->required()
])
->minItems(5)
->maxItems(5)
->addActionLabel('Ajouter une réponse')
->required()
])
->minItems(2)
->maxItems(4)
->addActionLabel('Ajouter une question')
->collapsible()
Repeater::make('questions')
->itemLabel(function () {
static $position = 1;
return 'Question n°'.$position++;
})
->schema([
textInput::make('title')
->required(),
Select::make('need_id')
->options(Need::all()->pluck('name', 'id'))
->required(),
Repeater::make('answers')
->itemLabel(function ($component, array $state, callable $get) {
$answers = $get('answers');
$answerKeys = array_keys($answers);

/*And now, I don't know what to do. How to get the current index of actual answer but without uuid ?*/

return 'Réponse n°';
})
->hiddenLabel()
->schema([
TextInput::make('title')
->required(),
TextInput::make('ratio')
->numeric()
->suffix('%')
->default('20')
->required()
])
->minItems(5)
->maxItems(5)
->addActionLabel('Ajouter une réponse')
->required()
])
->minItems(2)
->maxItems(4)
->addActionLabel('Ajouter une question')
->collapsible()
Thanks for you help 😅
7 replies
FFilament
Created by Alexandre on 8/14/2024 in #❓┊help
Create resource not found
No description
5 replies
FFilament
Created by Alexandre on 7/17/2024 in #❓┊help
afterStateUpdated not work on custom field
Hi 👋, I've created a new “TypeCylinder” field in my form. It works fine, except that I can't get the afterStateUpdated() method to work, as it never seems to be called... Any idea why? Here the input on the form :
CylinderType::make('content.cylinder_type.value')
->options(array(
__('users/requests.field.1') => __('users/requests.field.1'),
__('users/requests.field.2') => __('users/requests.field.2'),
__('users/requests.field.3') => __('users/requests.field.3')
))
->hiddenLabel()
->afterStateUpdated(function (
Set $set, $state
) {
dd("Don't work :( ");
})
->columnSpanFull()
CylinderType::make('content.cylinder_type.value')
->options(array(
__('users/requests.field.1') => __('users/requests.field.1'),
__('users/requests.field.2') => __('users/requests.field.2'),
__('users/requests.field.3') => __('users/requests.field.3')
))
->hiddenLabel()
->afterStateUpdated(function (
Set $set, $state
) {
dd("Don't work :( ");
})
->columnSpanFull()
The field class (CylinderType.php) :
namespace App\Forms\Components;

use Filament\Forms\Components\Concerns\HasOptions;
use Filament\Forms\Components\Field;

class CylinderType extends Field
{
use HasOptions;
protected string $view = 'forms.components.cylinder-type';
}
namespace App\Forms\Components;

use Filament\Forms\Components\Concerns\HasOptions;
use Filament\Forms\Components\Field;

class CylinderType extends Field
{
use HasOptions;
protected string $view = 'forms.components.cylinder-type';
}
14 replies
FFilament
Created by Alexandre on 6/13/2024 in #❓┊help
Component not found on select with native(false) and searchable()
Hi all ! I have a wizard form for my resource (create and edit) but I have a small problem on a specific Select field once the native and/or searchable is activated. Livewire Entangle Error: Livewire property ['data.products.xxx.content.key_brand'] cannot be found on component: ['app.filament.resources.request-resource.pages.create-request'] I'm not sure why, but it ONLY does it for me on this field. I have other selects in my form with native(false) and searchable() that don't have this problem. If I leave one of the 2 methods, I get the error. If I remove the 2 methods: no error. Here the field (content.key_brand) :
return Step::make('step_2')
->schema([
Repeater::make('products')
...
->schema([
Select::make('content.type')->options([...])->live(),
// Product details
Section::make('product_details')
->schema(fn(array $state) => $state['content']['type'] === 'Clé' ? [
Select::make('content.key_brand')
->options(KeyBrands::class)
->required()
->native(false)
->searchable(),
])
])
])
return Step::make('step_2')
->schema([
Repeater::make('products')
...
->schema([
Select::make('content.type')->options([...])->live(),
// Product details
Section::make('product_details')
->schema(fn(array $state) => $state['content']['type'] === 'Clé' ? [
Select::make('content.key_brand')
->options(KeyBrands::class)
->required()
->native(false)
->searchable(),
])
])
])
On the CreateRequest.php, I've this method :
protected function getSteps(): array
{

return [
RequestForm::getStep1RequestFormForAdmin(),
RequestForm::getStep2RequestForm() //here is the method to get the Step,
RequestForm::getStep3RequestForm(),
];
}
protected function getSteps(): array
{

return [
RequestForm::getStep1RequestFormForAdmin(),
RequestForm::getStep2RequestForm() //here is the method to get the Step,
RequestForm::getStep3RequestForm(),
];
}
My CreateRequest.php implements the HasWizard trait. Do you know where the problem might be coming from? Don't hesitate if you need any further information 😇
6 replies
FFilament
Created by Alexandre on 6/10/2024 in #❓┊help
Change the default "save and create another" label in modal form
Hello all 👋, I have a resource (MarketingMessage) for which I removed the default pages CreateMarketingMessage.php and EditMarketingMessage.php to have Modals instead. So, in my resource's getPages() method, I have just one value in the return array:
public static function getPages(): array
{
return [
index' => Pages\ListMarketingMessages::route('/'),
];
}
public static function getPages(): array
{
return [
index' => Pages\ListMarketingMessages::route('/'),
];
}
Everything works fine, but I wanted to know which method I should use (and where) to change the default label of “Create & add another”. Because in French, I have to change the translation to use a feminine form. I saw that there was a getCreateAnotherFormAction() method to use in CreateMarketingMessage.php, but since I don't use that page, it's no good. Can anyone help me? I couldn't find a reference in the documentation. Thanks in advance 😇
10 replies
FFilament
Created by Alexandre on 5/27/2024 in #❓┊help
Wizard Form display a modal after submit instead a redirect
Hello all ! I made a 5-step Wizard form that works well. I used the mutateFormDataBeforeCreate() and handleRecordCreation() methods in the Creation Class. Furthermore, I also used the ->submitAction() method to render a custom button. Everything works fine for creation and when the form is submitted and everything works, I'm redirected to the resource view page. My question is: instead of redirecting to the resource page, is it possible to display a modal with informative text and a custom link instead? I don't see anything in the Wizard class that would allow me to use a modal. Do you know if this is possible? And if so, could you give me some advice? Thanks in advance!
5 replies
FFilament
Created by Alexandre on 5/22/2024 in #❓┊help
Conditional validation on field in a repeater
Hi all, I have some difficulties to run validation on fields in repeater fields... So, let me explain, my repeater is a "product". This product contains product-related fields (so far, so good). In this product, I want conditional fields. For example, we have a "key number" field which is required by default. However, this field should no longer be required if the user has checked the "lost card" field. Here are the fields concerned in the repeater:
Checkbox::make('no_card')
->label(...)
->nullable()
->live()
->columnSpanFull(),
Checkbox::make('no_card')
->label(...)
->nullable()
->live()
->columnSpanFull(),
And the second field :
TextInput::make('key_number')
->label(...)
->prefixIcon('heroicon-m-hashtag')
->requiredWithout('no_card'),
TextInput::make('key_number')
->label(...)
->prefixIcon('heroicon-m-hashtag')
->requiredWithout('no_card'),
When I submit the form, it's like the validation passed even if the checkbox is not checked. I tried also with requiredIf like that :
->requiredIf('no_card', false)
->requiredIf('no_card', false)
Did I miss something to use requiredWithout validation rule with a checkbox? Because with a textInput it's work... Thanks 🙂
2 replies
FFilament
Created by Alexandre on 5/22/2024 in #❓┊help
$get() in Wizard Form is null
Hi all ! I have the same problem as this topic : https://discord.com/channels/883083792112300104/1159576155746213918/1159576155746213918 In my case, I've a Select form in the first step where the user choose a building (or can create new one) :
Wizard::make([
Step::make('step_1')
->label(...)
->schema([
Select::make('building')
->label(...)
->options(..)
->native(false)
->searchable()
->allowHtml()
->required()
->createOptionForm(...)
->createOptionModalHeading(...)
->createOptionUsing(...)
->live()
])
Wizard::make([
Step::make('step_1')
->label(...)
->schema([
Select::make('building')
->label(...)
->options(..)
->native(false)
->searchable()
->allowHtml()
->required()
->createOptionForm(...)
->createOptionModalHeading(...)
->createOptionUsing(...)
->live()
])
On step 2, I have another select in a repeater where I want to use the ID of the building field (step 1) to make a query search. So, I use Get $get for that :
Step::make('step_2')
->label(...)
->schema([
Repeater::make('products')
->label(...)
->schema([
Section::make('key')
->schema([
Select::make('card_number')
->getSearchResultsUsing(function (
string $search,
Get $get
): array {
dd($get('building')); //return null
})
->columnSpanFull(),
Step::make('step_2')
->label(...)
->schema([
Repeater::make('products')
->label(...)
->schema([
Section::make('key')
->schema([
Select::make('card_number')
->getSearchResultsUsing(function (
string $search,
Get $get
): array {
dd($get('building')); //return null
})
->columnSpanFull(),
The $get return null. If I do a $get of another field on the current step, it's work. Is there anything special I need to do to retrieve the field value in a repeater and form wizard? Thanks in advance 🙂
13 replies
FFilament
Created by Alexandre on 5/15/2024 in #❓┊help
Is it possible to format a new option created in a Select?
Hello all, In my form, I have a select field that will display a list of buildings where the option is formatted in a certain way: <strong>Building name</strong> - number, street | postal_code City (country) I use a method to get the buildings and populate my options :
$user = auth()->user();
if ($user->syndicate) {
$buildings = $user->syndicate->buildings()
->where('is_validated', true)
->get(['id', 'name', 'number', 'street', 'postal_code', 'city', 'country'])
->mapWithKeys(function ($building) {
$address = "<strong>{$building->name}</strong> - {$building->number}, {$building->street} | {$building->postal_code} {$building->city} ({$building->country})";
return [$building->id => $address];
})
->toArray();
} else {
$buildings = [];
}
$user = auth()->user();
if ($user->syndicate) {
$buildings = $user->syndicate->buildings()
->where('is_validated', true)
->get(['id', 'name', 'number', 'street', 'postal_code', 'city', 'country'])
->mapWithKeys(function ($building) {
$address = "<strong>{$building->name}</strong> - {$building->number}, {$building->street} | {$building->postal_code} {$building->city} ({$building->country})";
return [$building->id => $address];
})
->toArray();
} else {
$buildings = [];
}
I use createOptionForm() to give users the option of adding a new building to the Select and, in accordance with the documentation, I use createOptionUsing to create my building in the DB :
->createOptionUsing(function (array $data): int {
return auth()->user()->syndicate->buildings()->create($data)->getKey();
}),
->createOptionUsing(function (array $data): int {
return auth()->user()->syndicate->buildings()->create($data)->getKey();
}),
Everything works except that my select only displays the building ID in my select. Is it possible to format it too, like the others? If so, how? Thanks in advance for your help 😇
3 replies
FFilament
Created by Alexandre on 5/7/2024 in #❓┊help
Handle the creation process for a wizard form
I've created a form with a Wizard but it doesn't 100% reflect the structure of my DB. For example, I have a fairly complex repeater for creating products, and I'd like to store the field values in a Json in my “products” table. Where I'm stuck is that I have no idea how to intercept the form's submit in order to process the data myself and insert it into my DB. So I created a submit action button using this method: https://filamentphp.com/docs/3.x/forms/layout/wizard#rendering-a-submit-button-on-the-last-step And then what do I do to process the submit? I found this: https://filamentphp.com/docs/3.x/panels/resources/creating-records#customizing-the-creation-process in the documentation. I've added the method to my resource file, but it doesn't seem to be called when I click on the "submit" button. Is there a particular method to use when on a Wizard? I can't find much Thanks in advance 😇
8 replies
FFilament
Created by Alexandre on 5/3/2024 in #❓┊help
Header action on section to go back on a specific step on a Wizard Form
Hello, I was wondering if it was possible, in a Wizard Form, to have a button that would allow you to go back to a specific step? Let me explain: I have a 4-step form, and the last step is a "resume" where I'll display all the fields from each step in a specific section with placeholders. So I wanted to create a "Modify" action button in the header of each section, which would link to the form step containing the fields. Is there a way to do this? Thanks for help 🙂
10 replies
FFilament
Created by Alexandre on 4/10/2024 in #❓┊help
Help for Spatie Media File Upload in Relation Manager
Hello all 👋, I use Filament's Spatie Media Library plugin. I have my media table and a Model named "Company" where I would like to link files but not in the create page. So, I've created a RelationManager for my medias to be able to access the files in the company view, but I'm not sure how to manage adding files... If I place the prebuild createAction in the header array, the button doesn't appear. So I try to build a custom one. For now, I've this :
public function table(Table $table): Table
{
return $table
->recordTitleAttribute('name')
->columns([ // ])
->filters([ // ])
->headerActions([
Tables\Actions\Action::make('Add a media to this company')
->label(__('admin/medias.actions.add_media'))
->form([
Forms\Components\TextInput::make('name'),
Forms\Components\SpatieMediaLibraryFileUpload::make('attachment')
->collection('companies')
->acceptedFileTypes(['application/pdf', 'image/*'])
->required()
->reorderable()
->multiple(),
])
->action(function (array $data) {
dd($data); //$data returns an empty array...
$record = $this->ownerRecord;
$record->addMedia($data['attachment'])->toMediaCollection('companies');
}),
])
->actions([ // ])
->bulkActions([ // ]),
]);
}
public function table(Table $table): Table
{
return $table
->recordTitleAttribute('name')
->columns([ // ])
->filters([ // ])
->headerActions([
Tables\Actions\Action::make('Add a media to this company')
->label(__('admin/medias.actions.add_media'))
->form([
Forms\Components\TextInput::make('name'),
Forms\Components\SpatieMediaLibraryFileUpload::make('attachment')
->collection('companies')
->acceptedFileTypes(['application/pdf', 'image/*'])
->required()
->reorderable()
->multiple(),
])
->action(function (array $data) {
dd($data); //$data returns an empty array...
$record = $this->ownerRecord;
$record->addMedia($data['attachment'])->toMediaCollection('companies');
}),
])
->actions([ // ])
->bulkActions([ // ]),
]);
}
Do you know how I can do this or maybe there is a simpler way? Thanks in advance 🙂
2 replies
FFilament
Created by Alexandre on 4/9/2024 in #❓┊help
How to re-render a custom widget after click on a button?
Hello everyone, I'm still new to FilamentPHP and have created a custom widget on my admin panel that will display a welcome message to the user on first login. A button should allow him to hide the message once he's read it by updating the "show_welcome_message" boolean column. I'm not sure how to make the widget refresh after clicking the button. Could someone point me in the right direction? Thanks you 🙂 Here my code :
<?php

namespace App\Filament\Widgets;

use Filament\Widgets\Widget;


class WelcomeMessage extends Widget
{
protected static string $view = 'filament.widgets.welcome-message';
protected int|string|array $columnSpan = 'full';

protected $listeners = ['refreshComponent' => '$refresh'];

protected static ?int $sort = - 5;


public static function canView(): bool {
return auth()->user()->show_welcome_message;
}

public function markAsRead()
{
auth()->user()->update(['show_welcome_message' => false]);
$this->emit('refreshComponent'); // Doesn't work ofc because this->emit is not known here

}


}
<?php

namespace App\Filament\Widgets;

use Filament\Widgets\Widget;


class WelcomeMessage extends Widget
{
protected static string $view = 'filament.widgets.welcome-message';
protected int|string|array $columnSpan = 'full';

protected $listeners = ['refreshComponent' => '$refresh'];

protected static ?int $sort = - 5;


public static function canView(): bool {
return auth()->user()->show_welcome_message;
}

public function markAsRead()
{
auth()->user()->update(['show_welcome_message' => false]);
$this->emit('refreshComponent'); // Doesn't work ofc because this->emit is not known here

}


}
And the view :
<x-filament-widgets::widget>
<x-filament::section
icon="heroicon-m-academic-cap"
icon-color="primary"
>
<x-slot name="heading">
<div class="flex flex-row gap-2">
{{ __('users/welcome.title', ['name' => auth()->user()->getFilamentName()]) }}
</div>

</x-slot>
<div class="text-sm text-gray-700 dark:text-gray-200">
{{ __('users/welcome.message') }}
</div>
<footer class="fi-section-footer flex flex-row justify-end border-t border-gray-200 mt-4 pt-4 dark:border-white/10">
<x-filament::button
wire:click="markAsRead"
icon="heroicon-m-check"
>
{{ __('users/welcome.action') }}
</x-filament::button>
</footer>
</x-filament::section>
</x-filament-widgets::widget>
<x-filament-widgets::widget>
<x-filament::section
icon="heroicon-m-academic-cap"
icon-color="primary"
>
<x-slot name="heading">
<div class="flex flex-row gap-2">
{{ __('users/welcome.title', ['name' => auth()->user()->getFilamentName()]) }}
</div>

</x-slot>
<div class="text-sm text-gray-700 dark:text-gray-200">
{{ __('users/welcome.message') }}
</div>
<footer class="fi-section-footer flex flex-row justify-end border-t border-gray-200 mt-4 pt-4 dark:border-white/10">
<x-filament::button
wire:click="markAsRead"
icon="heroicon-m-check"
>
{{ __('users/welcome.action') }}
</x-filament::button>
</footer>
</x-filament::section>
</x-filament-widgets::widget>
1 replies
FFilament
Created by Alexandre on 3/27/2024 in #❓┊help
How to put the resource creation link in the navigation of the panel?
Hey folks 👋 I've created a panel for users and I have a RequestResource (with default pages). My resource registers well in the navigation (the page to display all Requests but I would also like a direct link to create a Request in my navigation. Is there an easy way to do this? I've tried adding navigation-related statics properties to the App\Filament\User\Resources\RequestResource\CreateRequest.php page (like $navigationIcon, $navigationGroup, etc.) but it doesn't seem to work. So I tried going through the UserPanelProdiver file and adding this method:
->navigationItems(
[
NavigationItem::make( 'create_request' )
->label( __( 'users/requests.navigation_create_label' ) )
->group( __( 'users/requests.navigation_group' ) )
->url( '/requests/create' )
->icon( 'heroicon-o-plus' ),
]
)
->navigationItems(
[
NavigationItem::make( 'create_request' )
->label( __( 'users/requests.navigation_create_label' ) )
->group( __( 'users/requests.navigation_group' ) )
->url( '/requests/create' )
->icon( 'heroicon-o-plus' ),
]
)
It works, but I don't know how to manage the active class 😅 Can anyone shed some light on this? Thanks in advance 😇
5 replies