Text or TextInput fiedl can be dynamically populated?

In my filament project, I've created the student form which has details about fee_plan and entered some data as well. Now, I'm preparing a form for fee payment, here I can select students from dropdown field and when I select a student I want fee_plan to be automatically populated next to a student name as a text or uneditable textinput field. Is this possible to achieve? Thanks for your help in advance.
This is the code
Select::make('fee_plan_id')//states ->label('Student Fee Plan') ->options(function (Get $get){ $students = Student::find($get('student_id')); if(!$students){ return FeePlan::all()->pluck('name', 'id'); } dd($students->fee_plan->name); return $students->fee_plan->name; }),
31 Replies
Patrick Boivin
Patrick Boivin11mo ago
Can you share a screenshot of the page?
syed_eer
syed_eer11mo ago
@pboivin thanks for your reply. Sure, this is the screeshot.
No description
Patrick Boivin
Patrick Boivin11mo ago
I see, thank you! So this will not work:
return $students->fee_plan->name;
return $students->fee_plan->name;
because you're trying to build the list of options, it should return an array Do I understand correctly? - if the student doesn't have a fee plan, show all fee plans - otherwise, show only the fee plan for this student
syed_eer
syed_eer11mo ago
@pboivin well, partly you are right. I have now made the select feild hidden because that is dropdown, next to it is TextInput readonly feild.
No description
syed_eer
syed_eer11mo ago
from the above code the 2nd last line dd() gives me the correct value "Montly" when I select Student 'ABC'.
Patrick Boivin
Patrick Boivin11mo ago
Ok, I understand. Maybe this can give you an idea:
Select::make('student_id')
->options(...)
->live()
->afterStateUpdated(function ($state, $set) {
if ($state) {
$set('fee_plan_name', Student::find($state)->fee_plan->name);
} else {
$set('fee_plan_name', '');
}
})
Select::make('fee_plan_name')
->disabled(),
Select::make('student_id')
->options(...)
->live()
->afterStateUpdated(function ($state, $set) {
if ($state) {
$set('fee_plan_name', Student::find($state)->fee_plan->name);
} else {
$set('fee_plan_name', '');
}
})
Select::make('fee_plan_name')
->disabled(),
syed_eer
syed_eer11mo ago
Kindly correct me if I'm doing anything wrong, below is the code public static function form(Form $form): Form { return $form ->schema([ Section::make('Fee Payment Details') ->schema([ Select::make('student_id') ->label('Student Name') ->options(Student::all()->pluck('name', 'id')->toArray())->reactive()->live() ->afterStateUpdated(function ($state, $set) { if ($state) { $set('fee_plan_name', Student::find($state)->fee_plan->name); } else { $set('fee_plan_name', ''); } }), Select::make('fee_plan_name') ->disabled(), DatePicker::make('due_date'), DatePicker::make('payment_date'), TextInput::make('amount_due'), TextInput::make('amount_paid'), Select::make('status') ->options([ 'Paid' => 'Paid', 'Unpaid' => 'Unpaid', 'Overdue' => 'Overdue', ]), ])->columns(3) ]); } It is not displaying anything in the fee_plan
Patrick Boivin
Patrick Boivin11mo ago
Try this as a test:
->afterStateUpdated(function ($state, $set) {
$set('fee_plan_name', $state);
}),
->afterStateUpdated(function ($state, $set) {
$set('fee_plan_name', $state);
}),
Do you see anything in fee_plan_name ?
syed_eer
syed_eer11mo ago
I tried with this but nothing is getting displayed. However, when I dd($state); it gives me this result which is not correct as it gives student_id.
No description
Patrick Boivin
Patrick Boivin11mo ago
This should be the student_id, no?
syed_eer
syed_eer11mo ago
yeah! you are very much correct, that's my bad. It is student_id.
Patrick Boivin
Patrick Boivin11mo ago
So the issue is somewhere else... make sure you can get the right fee plan information from the value of student_id Also maybe fee_plan_name should be a TextInput instead of a Select?
syed_eer
syed_eer11mo ago
that would be good if I get the value in textinput. the Now, if I use ->options(Student::all()->pluck('name', 'fee_plan_id')->toArray())->reactive()->live() instead of this ->options(Student::all()->pluck('name', 'id')->toArray())->reactive()->live(). I'm getting the fee_plan_id from students table. OMG, I got it. thank you so very much @pboivin , with this code it works like a charm. Select::make('student_id') ->label('Student Name') ->options(Student::all()->pluck('name', 'fee_plan_id')->toArray())->reactive()->live() ->afterStateUpdated(function ($state, $set) { if ($state) { $set('fee_plan_name', FeePlan::find($state)->name); } else { $set('fee_plan_name', ''); } }), TextInput::make('fee_plan_name')->disabled(), Hey @pboivin you there, I've just noticed something strange in my project. Could you please check and let me know whats wrong with this code Select::make('student_id') ->label('Student Name') ->options(Student::all()->pluck('name', 'fee_plan_id')->toArray())->reactive()->live() ->afterStateUpdated(function ($state, $set) { if ($state) { $set('fee_plan_name', FeePlan::find($state)->name); } else { $set('fee_plan_name', ''); } }),
syed_eer
syed_eer11mo ago
because while inserting the student name in the select field I only see 4 students out of 7, even the search also doesn't work.
No description
No description
No description
Patrick Boivin
Patrick Boivin11mo ago
This is what's wrong: ->pluck('name', 'fee_plan_id') You're keying the values by fee_plan_id, but multiple students can have the same plan id
syed_eer
syed_eer11mo ago
ohh ic, this is the reason that I'm getting only the four of the students records which has got all four fee_plan_id (1,2,3,4) respectively. Thank you for your reply @pboivin , so would there be any solution for this?
cheesegrits
cheesegrits11mo ago
So is your model structure something like this? Student id name fee_plan_id Fee Plan id name Payment id student_id fee_plan_name
syed_eer
syed_eer11mo ago
@Hugh Messenger thank you for your reply, yes! you are right except for the last one in the Payments table, it's fee_plan_id.
No description
syed_eer
syed_eer11mo ago
I would be grateful if someone could help me with this issue.
Patrick Boivin
Patrick Boivin11mo ago
@syed_eer I can help, but I feel like you have all the pieces already. Where are you stuck at this point? You need to use student_id in the first Select, because you want to show the list of all students (can't use fee_plan_id as the key) So then, from the student_id, you need to get the Student record and get the fee plan name from that Something like we discussed earlier : https://discord.com/channels/883083792112300104/1148680167338823711/1148718879519031409
syed_eer
syed_eer11mo ago
@pboivin thank you so very much for your reply. Do you mean I have to make more than one select, first select will give student_id with this I can get fee_plan_id in the second select?
Patrick Boivin
Patrick Boivin11mo ago
I don't think you need a second select... you want to show the fee plan name in a disabled text input, right?
syed_eer
syed_eer11mo ago
yeah, that's right, I just need whenever the student name gets selected from the dropdown, the fee_plan_name changes accordingly (based on the fee_plan selected by this particular student in the students table).
Patrick Boivin
Patrick Boivin11mo ago
Ok, let's start by getting this first Select to work... can you see the list of all students in it?
syed_eer
syed_eer11mo ago
with your kind help, I think somehow I got this working, could you please check this code. Select::make('student_id') ->label('Student Name') ->options(Student::all()->pluck('name', 'id')->toArray())->reactive()->live() ->afterStateUpdated(function ($state, $set) { if ($state) { $fPId = Student::find($state)->fee_plan_id; $FPidMatch = FeePlan::where('id', $fPId)->get(); $stdFPname = $FPidMatch->pluck('name'); $set('fee_plan_name', $stdFPname); } else { $set('fee_plan_name', ''); } })->searchable(), TextInput::make('fee_plan_name')->disabled(),
Patrick Boivin
Patrick Boivin11mo ago
Interesting, that looks good. So using the relation on the student doesn't work? Student::find($state)->fee_plan->name ?
syed_eer
syed_eer11mo ago
wow, this also works, Select::make('student_id') ->label('Student Name') ->options(Student::all()->pluck('name', 'id')->toArray())->reactive()->live() ->afterStateUpdated(function ($state, $set) { if ($state) { $set('fee_plan_name', Student::find($state)->fee_plan->name); } else { $set('fee_plan_name', ''); } })->searchable(), TextInput::make('fee_plan_name')->disabled(),
Patrick Boivin
Patrick Boivin11mo ago
Very nice
syed_eer
syed_eer11mo ago
so what do you suggest? which one should I use?
Patrick Boivin
Patrick Boivin11mo ago
Pick the one that looks better to you, I think they are equivalent
syed_eer
syed_eer11mo ago
Sure! I will move forward and let you know. @pboivin, thank you so much for your kind help.