filamentphp / filament

A collection of beautiful full-stack components for Laravel. The perfect starting point for your next app. Using Livewire, Alpine.js and Tailwind CSS.
https://filamentphp.com
MIT License
18.1k stars 2.83k forks source link

Adding an action to a Livewire component not working #8724

Closed mateusgalasso closed 12 months ago

mateusgalasso commented 1 year ago

Package

filament/filament

Package Version

v3.0.62

Laravel Version

v10.24.0

Livewire Version

v3.0.62

PHP Version

PHP 8.1.0

Problem description

I simply followed the steps in the documentation https://filamentphp.com/docs/3.x/actions/adding-an-action-to-a-livewire-component But the modal doesn't appear at all.

This is the result when I click on the action button { "components": [ { "snapshot": "{\"data\":{\"mountedActions\":[[],{\"s\":\"arr\"}],\"mountedActionsArguments\":[[],{\"s\":\"arr\"}],\"mountedActionsData\":[[],{\"s\":\"arr\"}],\"componentFileAttachments\":[[],{\"s\":\"arr\"}],\"mountedFormComponentActions\":[[],{\"s\":\"arr\"}],\"mountedFormComponentActionsArguments\":[[],{\"s\":\"arr\"}],\"mountedFormComponentActionsData\":[[],{\"s\":\"arr\"}],\"mountedFormComponentActionsComponents\":[[],{\"s\":\"arr\"}]},\"memo\":{\"id\":\"BmweDmbKEcsW4DAsbiY6\",\"name\":\"payment-action-modal\",\"path\":\"pos\",\"method\":\"GET\",\"children\":[],\"errors\":[],\"locale\":\"en\"},\"checksum\":\"da692d5f111a68b480b1c070bf3ee033ff862d05d3ea3c242df8cbaff4535329\"}", "effects": { "returns": [ null ], "html": "<div wire:id=\"BmweDmbKEcsW4DAsbiY6\">\n \n\n <button\n style=\"--c-400:var(--primary-400);--c-500:var(--primary-500);--c-600:var(--primary-600);\" class=\"fi-btn relative grid-flow-col items-center justify-center font-semibold outline-none transition duration-75 focus:ring-2 rounded-lg fi-color-custom fi-btn-color-primary fi-size-md fi-btn-size-md gap-1.5 px-3 py-2 text-sm inline-grid shadow-sm bg-custom-600 text-white hover:bg-custom-500 dark:bg-custom-500 dark:hover:bg-custom-400 focus:ring-custom-500\/50 dark:focus:ring-custom-400\/50 fi-ac-btn-action\" type=\"button\" wire:loading.attr=\"disabled\" wire:click=\"mountAction('Pay')\"\n >\n \n\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n class=\"animate-spin fi-btn-icon h-5 w-5\" wire:loading.delay=\"\" wire:target=\"mountAction('Pay')\"\n>\n <path\n clip-rule=\"evenodd\"\n d=\"M12 19C15.866 19 19 15.866 19 12C19 8.13401 15.866 5 12 5C8.13401 5 5 8.13401 5 12C5 15.866 8.13401 19 12 19ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z\"\n fill-rule=\"evenodd\"\n fill=\"currentColor\"\n opacity=\"0.2\"\n ><\/path>\n <path\n d=\"M2 12C2 6.47715 6.47715 2 12 2V5C8.13401 5 5 8.13401 5 12H2Z\"\n fill=\"currentColor\"\n ><\/path>\n<\/svg>\n \n\n \n \n\n <span\n class=\"fi-btn-label\"\n >\n Pay\n <\/span>\n\n \n\n \n\n \n <\/button>\n \n\n\n <form wire:submit.prevent=\"callMountedAction\">\n \n <div\n aria-modal=\"true\"\n role=\"dialog\"\n x-data=\"{\n isOpen: false,\n\n livewire: null,\n\n close: function () {\n this.isOpen = false\n\n this.$refs.modalContainer.dispatchEvent(\n new CustomEvent('modal-closed', { id: 'BmweDmbKEcsW4DAsbiY6-action' }),\n )\n },\n\n open: function () {\n this.isOpen = true\n\n this.$refs.modalContainer.dispatchEvent(\n new CustomEvent('modal-opened', { id: 'BmweDmbKEcsW4DAsbiY6-action' }),\n )\n },\n }\"\n x-on:close-modal.window=\"if ($event.detail.id === 'BmweDmbKEcsW4DAsbiY6-action') close()\"\n x-on:open-modal.window=\"if ($event.detail.id === 'BmweDmbKEcsW4DAsbiY6-action') open()\"\n x-trap.noscroll=\"isOpen\"\n wire:ignore.self\n class=\"fi-modal block\"\n>\n \n\n <div\n x-cloak\n x-show=\"isOpen\"\n x-transition.duration.300ms.opacity\n class=\"fixed inset-0 z-40 min-h-full overflow-y-auto overflow-x-hidden transition flex items-center\"\n >\n <div\n aria-hidden=\"true\"\n x-on:click=\"$dispatch('close-modal', { id: 'BmweDmbKEcsW4DAsbiY6-action' })\"\n class=\"fi-modal-close-overlay fixed inset-0 bg-gray-950\/50 dark:bg-gray-950\/75 cursor-pointer\"\n style=\"will-change: transform\"\n ><\/div>\n\n <div\n x-cloak\n x-ref=\"modalContainer\"\n class=\"pointer-events-none relative w-full transition my-auto p-4\" x-on:closed-form-component-action-modal.window=\"if (($event.detail.id === 'BmweDmbKEcsW4DAsbiY6') && $wire.mountedActions.length) open()\" x-on:modal-closed.stop=\"const mountedActionShouldOpenModal = false\n\n\n if (! mountedActionShouldOpenModal) {\n return\n }\n\n if ($wire.mountedFormComponentActions.length) {\n return\n }\n\n $wire.unmountAction(false)\" x-on:opened-form-component-action-modal.window=\"if ($event.detail.id === 'BmweDmbKEcsW4DAsbiY6') close()\"\n >\n <div\n x-cloak\n x-data=\"{ isShown: false }\"\n x-init=\"\n $nextTick(() => {\n isShown = isOpen\n $watch('isOpen', () => (isShown = isOpen))\n })\n \"\n x-on:keydown.window.escape=\"$dispatch('close-modal', { id: 'BmweDmbKEcsW4DAsbiY6-action' })\"\n x-show=\"isShown\"\n x-transition:enter=\"duration-300\"\n x-transition:leave=\"duration-300\"\n x-transition:enter-start=\"scale-95\"\n x-transition:enter-end=\"scale-100\"\n x-transition:leave-start=\"scale-95\"\n x-transition:leave-end=\"scale-100\"\n class=\"fi-modal-window pointer-events-auto relative flex w-full cursor-default flex-col bg-white shadow-xl ring-1 ring-gray-950\/5 dark:bg-gray-900 dark:ring-white\/10 mx-auto rounded-xl hidden max-w-sm\"\n >\n \n\n \n\n \n <\/div>\n <\/div>\n <\/div>\n<\/div>\n <\/form>\n\n \n\n \n\n \n\n \n <form wire:submit.prevent=\"callMountedFormComponentAction\">\n <div\n aria-modal=\"true\"\n role=\"dialog\"\n x-data=\"{\n isOpen: false,\n\n livewire: null,\n\n close: function () {\n this.isOpen = false\n\n this.$refs.modalContainer.dispatchEvent(\n new CustomEvent('modal-closed', { id: 'BmweDmbKEcsW4DAsbiY6-form-component-action' }),\n )\n },\n\n open: function () {\n this.isOpen = true\n\n this.$refs.modalContainer.dispatchEvent(\n new CustomEvent('modal-opened', { id: 'BmweDmbKEcsW4DAsbiY6-form-component-action' }),\n )\n },\n }\"\n x-on:close-modal.window=\"if ($event.detail.id === 'BmweDmbKEcsW4DAsbiY6-form-component-action') close()\"\n x-on:open-modal.window=\"if ($event.detail.id === 'BmweDmbKEcsW4DAsbiY6-form-component-action') open()\"\n x-trap.noscroll=\"isOpen\"\n wire:ignore.self\n class=\"fi-modal block\"\n>\n \n\n <div\n x-cloak\n x-show=\"isOpen\"\n x-transition.duration.300ms.opacity\n class=\"fixed inset-0 z-40 min-h-full overflow-y-auto overflow-x-hidden transition flex items-center\"\n >\n <div\n aria-hidden=\"true\"\n x-on:click=\"$dispatch('close-modal', { id: 'BmweDmbKEcsW4DAsbiY6-form-component-action' })\"\n class=\"fi-modal-close-overlay fixed inset-0 bg-gray-950\/50 dark:bg-gray-950\/75 cursor-pointer\"\n style=\"will-change: transform\"\n ><\/div>\n\n <div\n x-cloak\n x-ref=\"modalContainer\"\n class=\"pointer-events-none relative w-full transition my-auto p-4\" x-on:modal-closed.stop=\"const mountedFormComponentActionShouldOpenModal = false\n\n\n if (mountedFormComponentActionShouldOpenModal) {\n $wire.unmountFormComponentAction(false)\n }\"\n >\n <div\n x-cloak\n x-data=\"{ isShown: false }\"\n x-init=\"\n $nextTick(() => {\n isShown = isOpen\n $watch('isOpen', () => (isShown = isOpen))\n })\n \"\n x-on:keydown.window.escape=\"$dispatch('close-modal', { id: 'BmweDmbKEcsW4DAsbiY6-form-component-action' })\"\n x-show=\"isShown\"\n x-transition:enter=\"duration-300\"\n x-transition:leave=\"duration-300\"\n x-transition:enter-start=\"scale-95\"\n x-transition:enter-end=\"scale-100\"\n x-transition:leave-start=\"scale-95\"\n x-transition:leave-end=\"scale-100\"\n class=\"fi-modal-window pointer-events-auto relative flex w-full cursor-default flex-col bg-white shadow-xl ring-1 ring-gray-950\/5 dark:bg-gray-900 dark:ring-white\/10 mx-auto rounded-xl hidden max-w-sm\"\n >\n \n\n \n\n \n <\/div>\n <\/div>\n <\/div>\n<\/div>\n <\/form>\n\n \n<\/div>\n", "dispatches": [ { "name": "close-modal", "params": { "id": "BmweDmbKEcsW4DAsbiY6-action" } } ] } } ] }

Expected behavior

Open modal

Steps to reproduce

Create a Laravel breeze application and create an action to a Livewire component

Reproduction repository

https://github.com/mateusgalasso/test_modal

Relevant log output

No response

zepfietje commented 1 year ago

I'm sorry, but I have no idea where to look for the issue in your linked repository. Please provide clear reproduction steps.

mateusgalasso commented 1 year ago

Look at Route::get('products', ManagePost::class); render only one button. But the modal doesn't show up

mateusgalasso commented 1 year ago

https://github.com/filamentphp/filament/assets/3990028/fbc3c17b-caa8-40dd-ab45-cedd5e6621b5

video example

awcodes commented 12 months ago

Remove Alpine from your app.js. You're confusing livewire by trying to instantiate Alpine outside of filament.

Screenshot 2023-10-04 at 4 48 00 PM

Closing as this is not an issue with Filament.

zepfietje commented 12 months ago

Thanks for tackling these issues, @awcodes!

mydnic commented 11 months ago

I had more or less the same issue : I added an Action to a custom Livewire component, and the modal wasn't showing up at all. Not even the backdrop.

I finally figured why : the string passed in the make() method needs to match the method name that returns the action.

// NOT GOOD
public function createTodoAction(): Action
{
    return Action::make('create')
}

// GOOD
public function createTodoAction(): Action
{
    return Action::make('createTodo')
}

Maybe I'm just dumb or I didn't find that in the documentation. Hope it helps.

victorybiz commented 11 months ago

I had more or less the same issue : I added an Action to a custom Livewire component, and the modal wasn't showing up at all. Not even the backdrop.

I finally figured why : the string passed in the make() method needs to match the method name that returns the action.

// NOT GOOD
public function createTodoAction(): Action
{
    return Action::make('create')
}

// GOOD
public function createTodoAction(): Action
{
    return Action::make('createTodo')
}

Maybe I'm just dumb or I didn't find that in the documentation. Hope it helps.

Thank you @mydnic , your reply saved me from hours of stress. This needs to be stated clearly in the documentation.

kurucu commented 11 months ago

I had more or less the same issue : I added an Action to a custom Livewire component, and the modal wasn't showing up at all. Not even the backdrop.

I finally figured why : the string passed in the make() method needs to match the method name that returns the action.

// NOT GOOD
public function createTodoAction(): Action
{
    return Action::make('create')
}

// GOOD
public function createTodoAction(): Action
{
    return Action::make('createTodo')
}

Maybe I'm just dumb or I didn't find that in the documentation. Hope it helps.

Insane. I've just spent a whole afternoon trying to sort this out.

Context: I have TagGroups rendering actions (delete, edit, create and create tag) and then nested in these are Tags (delete, edit). Perhaps the number of actions throws it off??

aimonext commented 7 months ago

@kurucu, you're absolutely correct. I also discovered that the action name must match the method name for the modal to function properly. It's unfortunate that this crucial detail isn't clearly documented. To enhance this, we should update the documentation to explicitly state this requirement for smoother implementation and user understanding.

ngcoders commented 6 months ago

I had more or less the same issue : I added an Action to a custom Livewire component, and the modal wasn't showing up at all. Not even the backdrop.

I finally figured why : the string passed in the make() method needs to match the method name that returns the action.

// NOT GOOD
public function createTodoAction(): Action
{
    return Action::make('create')
}

// GOOD
public function createTodoAction(): Action
{
    return Action::make('createTodo')
}

Maybe I'm just dumb or I didn't find that in the documentation. Hope it helps.

Needs to go into documentation , spent an hour figuring this.