control modal from blade file

I have a page where different types of users' information needs to be saved. There is only one action button that opens a modal containing a form that collects the users info, and save that into an array temporarily. as soon as the array has got an item, there is my custom view that renders the data along with two buttons (update, and delete). the delete function takes the index of the current item, and then removes the item from the array in case it is clicked.
<x-filament::button type="button" color="danger" wire:click="deleteItem({{ $index }})">
Delete
</x-filament::button>
<x-filament::button type="button" color="danger" wire:click="deleteItem({{ $index }})">
Delete
</x-filament::button>
Now the real questions comes here! here is the update button
<x-filament::button wire:click="openModal({{ $index }})">
Update
</x-filament::button>
<x-filament::button wire:click="openModal({{ $index }})">
Update
</x-filament::button>
I would like to have a modal to open when this button is clicked. The modal should contain a form with some pre-filled data passed to it. how can I implement the openModal function to open the modal and pass the needed data to it, so the modal can fill its form with the corresponding data. I am new to filament, so if I am doing it wrong, let me know about the correct way of doing it.
4 Replies
Dan Harrin
Dan Harrin14mo ago
to fill the form, you would use $this->formName->fill([]) in openModal() then you would dispatch the browser event to open the modal but without more specific details about your modal and form i dont think i can help further
Karim Bakhsh
Karim Bakhsh14mo ago
let me give details. I have these public variables
public Collection $bill_items;

public array $formData;
public bool $modalOpen;
public array $editData;
public Collection $bill_items;

public array $formData;
public bool $modalOpen;
public array $editData;
And in mount function I have written this
public function mount(): void
{
$this->bill_items = collect();
$this->modalOpen = false;
}
public function mount(): void
{
$this->bill_items = collect();
$this->modalOpen = false;
}
And I have my getActions function like this
return [
Action::make('Create Medical Bill')
->action(function (array $data): void {
$this->bill_items->push($data);
$this->calculatePayments();
})
->disabled(fn () => $this->bill_items->count() >= 3)
->form([
Forms\Components\Card::make([
Input::medicalBillType('type', $this->bill_items->pluck('type')->toArray())->reactive(),
Input::decimalInput('fee')->required(),

Forms\Components\DatePicker::make('date_of_care')
->visible(fn (\Closure $get) => $get('type') === 'physication')
->required(),

Forms\Components\Textarea::make('description')->rows(2)->cols(20)
->nullable()->maxLength(250)->columnSpanFull(),

Input::fileUpload('attachments')->directory(fn (\Closure $get) => $get('type'))->columnSpanFull(),
])->columns(2),
]),
];
return [
Action::make('Create Medical Bill')
->action(function (array $data): void {
$this->bill_items->push($data);
$this->calculatePayments();
})
->disabled(fn () => $this->bill_items->count() >= 3)
->form([
Forms\Components\Card::make([
Input::medicalBillType('type', $this->bill_items->pluck('type')->toArray())->reactive(),
Input::decimalInput('fee')->required(),

Forms\Components\DatePicker::make('date_of_care')
->visible(fn (\Closure $get) => $get('type') === 'physication')
->required(),

Forms\Components\Textarea::make('description')->rows(2)->cols(20)
->nullable()->maxLength(250)->columnSpanFull(),

Input::fileUpload('attachments')->directory(fn (\Closure $get) => $get('type'))->columnSpanFull(),
])->columns(2),
]),
];
I have already specified a custom view
protected static string $view = 'filament.resources.medical-bill-resource.pages.create-medical';
protected static string $view = 'filament.resources.medical-bill-resource.pages.create-medical';
In my blade file at the very first part I have this part where it shows the content of the bill_item variable along with a delete and an update button.
<x-filament::card>
<div>
<table class="w-full">
<tbody>
@foreach($bill_items as $index => $bill_item)
<tr>
<td class="whitespace-nowrap py-2 pl-4 pr-3 text-sm sm:pl-0">{{$bill_item['type']}}</td>
<td class="whitespace-nowrap px-2 py-2 text-sm">{{$bill_item['fee']}} AFN</td>
<td class="whitespace-nowrap px-2 py-2 text-sm">
@if(array_key_exists("date_of_care", $bill_item))
{{$bill_item['date_of_care']}}
@endif
</td>
<td class="whitespace-nowrap px-2 py-2 text-sm">{{$bill_item['description']}}</td>
<td class="whitespace-nowrap px-2 py-2 text-sm">
@foreach($bill_item['attachments'] as $file)
<div> {{$file}} </div>
@endforeach
</td>
<td class="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm sm:pr-0">
<x-filament::button x-on:click="$dispatch('open-modal', {id: 'custom-modal-handle'})">
{{-- <x-filament::button wire:click="editBillItem({{ $index }})"> --}}
Update
</x-filament::button>

<x-filament::button type="button" color="danger" wire:click="deleteBillItem({{ $index }})">
Delete
</x-filament::button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</x-filament::card>
<x-filament::card>
<div>
<table class="w-full">
<tbody>
@foreach($bill_items as $index => $bill_item)
<tr>
<td class="whitespace-nowrap py-2 pl-4 pr-3 text-sm sm:pl-0">{{$bill_item['type']}}</td>
<td class="whitespace-nowrap px-2 py-2 text-sm">{{$bill_item['fee']}} AFN</td>
<td class="whitespace-nowrap px-2 py-2 text-sm">
@if(array_key_exists("date_of_care", $bill_item))
{{$bill_item['date_of_care']}}
@endif
</td>
<td class="whitespace-nowrap px-2 py-2 text-sm">{{$bill_item['description']}}</td>
<td class="whitespace-nowrap px-2 py-2 text-sm">
@foreach($bill_item['attachments'] as $file)
<div> {{$file}} </div>
@endforeach
</td>
<td class="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm sm:pr-0">
<x-filament::button x-on:click="$dispatch('open-modal', {id: 'custom-modal-handle'})">
{{-- <x-filament::button wire:click="editBillItem({{ $index }})"> --}}
Update
</x-filament::button>

<x-filament::button type="button" color="danger" wire:click="deleteBillItem({{ $index }})">
Delete
</x-filament::button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</x-filament::card>
As soon as I click update button it shows this modal to me which is on the same blade file.
<x-filament::modal id="custom-modal-handle">
<x-slot name="header">
Edit Medical Bill
</x-slot>
<div>
<x-filament::form wire:submit.prevent="save">
<div class="flex flex-wrap items-center justify-end gap-4">
<x-filament::button type="submit">
Update
</x-filament::button>


</div>
</x-filament::form>
</div>
</x-filament::modal>
<x-filament::modal id="custom-modal-handle">
<x-slot name="header">
Edit Medical Bill
</x-slot>
<div>
<x-filament::form wire:submit.prevent="save">
<div class="flex flex-wrap items-center justify-end gap-4">
<x-filament::button type="submit">
Update
</x-filament::button>


</div>
</x-filament::form>
</div>
</x-filament::modal>
coming back to the question I have created a function that can be accessed in this blade file
public function editBillItem($index)
{
$this->modalOpen = true;
$this->editData = $this->bill_items[$index];
}
public function editBillItem($index)
{
$this->modalOpen = true;
$this->editData = $this->bill_items[$index];
}
I would like this function to open the modal for me, and shows a form inside itself for me with some prefilled data. @Dan Harrin thanks for the reach-out, anyways 🙂
Dan Harrin
Dan Harrin14mo ago
so what currently happens when you click the button
Karim Bakhsh
Karim Bakhsh14mo ago
It only opens the modal. But what I want is something different. Plus, the modal currently does not have anything in it, except for some hardcoded lines. Because there will be multiple items in bill_items, each of them will have an update button. When I click the update button, the editBillItem must be called to so that it pushes that specific item of the array in editData variable. So that I can prefill the form with that. This is the reason why I would like the modal to be opened while editBillItem function is called.