How to call function inside custom form field
I'm new in writing a custom form field. I watched the laracast from Dan but I want to trigger some custom functions inside the Field Class. I tried a regular wire:click with naming the method but I get the following response:
Unable to call component method. Public method [$example] not found on component
This is my example form field:
namespace App\Forms\Components;
use Filament\Forms\Components\Field;
class CloudFileSelect extends Field
{
protected string $view = 'forms.components.cloud-file-select';
public function example()
{
dd('example');
}
}
And this is the view:
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
<div class="z-10" x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }">
<button class="button hover:cursor-pointer" type="button" wire:click="example()">Open Example</button>
</div>
</x-dynamic-component>
I would be happy if someone can help me or give me a good source with a comprehensive example for writing my own field.45 Replies
what's the purpose of this button? Don't think you can have button in a form like that
Form Fields aren't Livewire components. You can't use
wire:click
here.
You would need to define example()
method on the Page itselfok - thanks for the feedback - How about event listeners. How I can implement a alpine listener to a custom form field?
The same as you would define any Alpine listener?
ok.. like I said its my first custom form field and I dont find that much inside the docs or web
You can also register actions and listeners in the setUp() method of the field.
what this button would do? maybe there are better alternatives like hint action
Do you have a code example for me (link)? Where I also can found other methods that are possible? 🙂
Have a look at the Builder and Repeater components in core. You can register the action in setup then use the action directly in the view.
with extraItemActions?
Tiptap editor plugin and Curator plugin use this approach too.
No, in the setup method ->registerActions()
Those are just examples of how you can do it. Don’t try to copy them exactly. 🙂
I'll see how far I get with the tips. Thank you 🙂
@awcodes short question, when I add a listner like that:
@script
<script>
$wire.on('post-created', () => {
//
});
</script>
@endscript
and I dispatch for example post-created, the dont react inside the custom form field
Where/how do you dispatch that event?
inside a livewire component
Can you share some code?
sure:
$this->dispatch('cl-selected', $data)
@script
<script>
$wire.on('cl-selected', (data) => {
console.log('triggered');
console.log(data);
});
</script>
@endscript
This a bit low context. Can you share more of the component? Also please use code formatting.
Thats the custom form field
The dispatch is from a livewirecomponent outside the form
can you answer what in the form this button will do? i assume it's somewhere in the middle of the form?
also, instead of one backtick for code highlight use three backtick and a language for syntax highlight
the button open a livewire modal component that shows a file list
but where it is placed? for me it seems a basic action button could be used instead
Yes, it can also be an action, but for now it is more important to understand why the event listener does not work
how did you register the listener? can you show that code? normally when you register a listern for a field you also provide the callback function there, not in the blade view.
also this real should be an action. you are way over complicating it.
do you mean as a listener inside the setUp?
yes.
since field's aren't livewire components you have to do it differently
But they also listn to regular dispatch events?
well, based on your code, the event you are dispatching doesn't have the same name as the event you are listening for.
based on my experience, the stack approach does work well in this case, since it's always getting re-rendered everytime a livewire call is made.
I tryed
Perhaps I will briefly explain what exactly is to be communicated via the event. There is a file manager, or rather a file selection as a Livewire component, which returns the selected file as an event. Now the files should be listed in a filament form when you select a file for the area. The Button opens the Modal Livewire component
ok. so that's a form event,
$wire.dispatchFormEvent('cl-selected', '{{ $getStatePath() }}')
an action will make this a thousand times easierBut the modal selection is not part of the form - so a bit confused now :S
ok, so when I use the action for the custom component, how I can add an Item to the state, or work with the dispatch() data?
you don't have to dispatch anything
is there anything outside the docs maybe where I can take a look on?
ok sure - the dispatch comes form the livewire component. But how I listen for that inside the form component?
I removed the button and add a Action instead.
in the view.blade.php
thats fine.. but now how to communicate between the livewire component thats outside of the form with the form component
form is on create or edit page so you should listen on those pages. where are you listening for the events?
you can use arguments in the action to pass the data around.
ok ok I think I may have expressed myself incorrectly.
I have integrated a listener in the custom form field. The file selection is outside the form, which is why I work with the listener. But the listener not react after I dispatch the event inside the regular livewire component that shows up. Thats the listener I've add inside the custom form component.
like i said earlier, using stacks like that is probably not going to work in this use case, because it won't push to the stack during rerender.
but inside the setUp() should it work?
yes, but it's a form event, not a native livewire event doing it that way
Does this mean that regular native events cannot be used in form fields?
but your dispatch is inside the form field, the dispatch I mean comes from a regular livewire component
As an example, I have the Livewire component in which the form is also and another one that represents a modal with a file listing. The event comes from the file listing component.
i'd have to see the code to the whole thing to help further. I still think you're over complicating the whole thing.