Using Getters in forms

When using Get $get in forms, and you want to get the value of lets say a component that is AFTER the component that has the getter, it will return null. For example:
TextInput::make('author_name')
->label('Author')
->disabled()
->dehydrated()
->formatStateUsing(fn (Get $get) => dd($get('author_id')))
->required(),
Hidden::make('author_id')
->label('Author')
->default(fn () => Auth::id())
->required(),
TextInput::make('author_name')
->label('Author')
->disabled()
->dehydrated()
->formatStateUsing(fn (Get $get) => dd($get('author_id')))
->required(),
Hidden::make('author_id')
->label('Author')
->default(fn () => Auth::id())
->required(),
Is this intended? I assume the components in the form are processed linearly, but wouldnt it be better for the Getter to check all the components and not just the ones that "have already been processed"?
24 Replies
LeandroFerreira
does it work if you change Hidden to TextInput?
Matthew
MatthewOP2w ago
No, also null Its not a big issue, its a bit annoying 😅
awcodes
awcodes2w ago
What exactly are you trying to do? It’s not a good idea to use hidden fields for record id’s since they can be manipulated in the browser before form submission.
LeandroFerreira
hum, I think this is the question: this doesn't work
TextInput::make('author_name')
->formatStateUsing(fn (Get $get) => $get('author_id')),
TextInput::make('author_id')
->default(1),
TextInput::make('author_name')
->formatStateUsing(fn (Get $get) => $get('author_id')),
TextInput::make('author_id')
->default(1),
Maybe this is correct, the author_id isn't hydrated at this point using default, which is why it is null.. This will work
public function mount(): void
{
parent::mount();

$this->form->fill([
'author_id' => 1
]);
}
public function mount(): void
{
parent::mount();

$this->form->fill([
'author_id' => 1
]);
}
awcodes
awcodes2w ago
That's why i'm asking for the use case.
->formatStateUsing(fn ($state) => $state ?? Auth::user()->id)
->formatStateUsing(fn ($state) => $state ?? Auth::user()->id)
Takashi
Takashi2w ago
Well, I think this cause the TextInput::make('author_name') is attempting to format its state using the value of 'author_id'. However, 'author_id' is set with a default value of 1. If author_name depends on author_id, but there’s no mechanism to ensure author_id is updated before the state of author_name, this can result in incorrect or unexpected behavior. So, I think it would be better to be initialized first. TextInput::make(author_id)->default(1)
Matthew
MatthewOP2w ago
Well, I have an author_id column in my db, on the create record, I want to have the name of the currently auth user as the default value. The default value will be an int, but I want to show the name of the user I have done this like 100 times before, I have just completely forgotten
awcodes
awcodes2w ago
Sounds like it should just be a select with a relationship to the author.
Matthew
MatthewOP2w ago
Yeah I thought so too... I was just trying to think of a way to do it with a textinput
awcodes
awcodes2w ago
the problem with a text input is that it would require the user to know the id or the exact spelling of the user name when they select the author
LeandroFerreira
you mean, this?
Group::make([
TextInput::make('name')
->disabled()
->dehydrated(false)
->formatStateUsing(fn(?string $state) : string => $state ?? auth()->user()->name)
])
->relationship('author')
Group::make([
TextInput::make('name')
->disabled()
->dehydrated(false)
->formatStateUsing(fn(?string $state) : string => $state ?? auth()->user()->name)
])
->relationship('author')
Matthew
MatthewOP2w ago
Thanks, I will try this when I get home Should I make a author() relationship in the model?
public function author()
{
return BelongsTo(User::class, 'author_id');
}
public function author()
{
return BelongsTo(User::class, 'author_id');
}
LeandroFerreira
Yep @Matthew did it work?
Matthew
MatthewOP2w ago
Hey, no it didnt. Im getting that author_id doesnt have default value
public static function form(Form $form): Form
{
$userModel = app(FilamentLatex::class)->getUserModel();

return $form
->schema([
Section::make()
->schema([
TextInput::make('name')
->label('Document Title')
->required(),
DateTimePicker::make('deadline')
->required()
->native(false)
->placeholder('DD-MM-YYYY HH:MM')
->suffixIcon('heroicon-m-calendar')
->format('Y-m-d H:i:s')
->displayFormat('d-m-Y H:i'),
Group::make([
TextInput::make('author_id')
->disabled()
->dehydrated(false)
->formatStateUsing(fn (?string $state): string => $state ?? auth()->user()->name),
])->relationship('author'),
Select::make('collaborators_id')
->label('Collaborators')
->multiple()
->options(fn () => $userModel::all()->pluck('name', 'id'))
->searchable(),
])->columns(2),
]);
}
public static function form(Form $form): Form
{
$userModel = app(FilamentLatex::class)->getUserModel();

return $form
->schema([
Section::make()
->schema([
TextInput::make('name')
->label('Document Title')
->required(),
DateTimePicker::make('deadline')
->required()
->native(false)
->placeholder('DD-MM-YYYY HH:MM')
->suffixIcon('heroicon-m-calendar')
->format('Y-m-d H:i:s')
->displayFormat('d-m-Y H:i'),
Group::make([
TextInput::make('author_id')
->disabled()
->dehydrated(false)
->formatStateUsing(fn (?string $state): string => $state ?? auth()->user()->name),
])->relationship('author'),
Select::make('collaborators_id')
->label('Collaborators')
->multiple()
->options(fn () => $userModel::all()->pluck('name', 'id'))
->searchable(),
])->columns(2),
]);
}
toeknee
toeknee2w ago
I'd just do:
public static function form(Form $form): Form
{
$userModel = app(FilamentLatex::class)->getUserModel();

return $form
->schema([
Section::make()
->schema([
TextInput::make('name')
->label('Document Title')
->required(),
DateTimePicker::make('deadline')
->required()
->native(false)
->placeholder('DD-MM-YYYY HH:MM')
->suffixIcon('heroicon-m-calendar')
->format('Y-m-d H:i:s')
->displayFormat('d-m-Y H:i'),

Group::make([
TextInput::make('name')
->disabled()
->dehydrated(false)
->formatStateUsing(fn (?string $state): string => $state ?? auth()->user()->name),
])->relationship('author'),

Select::make('collaborators_id')
->label('Collaborators')
->multiple()
->options(fn () => $userModel::all()->pluck('name', 'id'))
->searchable(),
])
->mutateFormDataBeforeCreate(function (array $data): array {
$data['author_id'] = auth()->id();

return $data;
})
->columns(2),
]);
}
public static function form(Form $form): Form
{
$userModel = app(FilamentLatex::class)->getUserModel();

return $form
->schema([
Section::make()
->schema([
TextInput::make('name')
->label('Document Title')
->required(),
DateTimePicker::make('deadline')
->required()
->native(false)
->placeholder('DD-MM-YYYY HH:MM')
->suffixIcon('heroicon-m-calendar')
->format('Y-m-d H:i:s')
->displayFormat('d-m-Y H:i'),

Group::make([
TextInput::make('name')
->disabled()
->dehydrated(false)
->formatStateUsing(fn (?string $state): string => $state ?? auth()->user()->name),
])->relationship('author'),

Select::make('collaborators_id')
->label('Collaborators')
->multiple()
->options(fn () => $userModel::all()->pluck('name', 'id'))
->searchable(),
])
->mutateFormDataBeforeCreate(function (array $data): array {
$data['author_id'] = auth()->id();

return $data;
})
->columns(2),
]);
}
Assuming the author_id is on the same table as collaborators_id.
Takashi
Takashi2w ago
You have two TextInput::make('name') definitions, which may cause issues since form field names must be unique. Consider renaming the second TextInput to something descriptive like author_name:
toeknee
toeknee2w ago
No it won't because onces in a relationship and sub-keyed.
Takashi
Takashi2w ago
Well, in that case, I think it would be better to define relationship as follow. public function author() { return $this->belongsTo(User::class, 'author_id'); }
toeknee
toeknee2w ago
You mean exactly as he has done a few posts above....
Takashi
Takashi2w ago
Hmmm... How about this? I guess it would works by reordering component places. like this: Hidden::make('author_id') ->label('Author') ->default(fn () => Auth::id()) ->required(), TextInput::make('author_name') ->label('Author') ->disabled() ->dehydrated() ->formatStateUsing(fn (Get $get) => dd($get('author_id'))) ->required()
LeandroFerreira
I don't understand what you are trying to do.. maybe you could share a repo on github reproducing the issue and what you need.. this was mentioned at the first comment..
toeknee
toeknee2w ago
I think he is trying to help but it should be solved already now.
Matthew
MatthewOP2w ago
I thnk this got a whole lot more complicated than necessary. I will probably just stick with Select... I reallly appreciate your help though 🙂
toeknee
toeknee2w ago
Good shout!
Want results from more Discord servers?
Add your server