TextareaFormComponent is not defined when in tabs
Package
filament/filament
Package Version
v3.3.20
Laravel Version
v11.45.1
Livewire Version
v3.6.3
PHP Version
PHP 8.3.21
Problem description
While using SPA mode, rendering a Filament form schema that includes tabs (schema-based tabs), placing a Textarea form component inside the second tab tab content triggers this error during runtime but if in first tab there is no error. The component fails to initialize correctly via Alpine.js, resulting in a JS exception.
But if without SPA no error show.
The relevant error trace:
Uncaught ReferenceError: TextareaFormComponent is not defined
at [Alpine] textareaFormComponent
at eval (at safeAsyncFunction)
...
Uncaught ReferenceError: state is not defined
at [Alpine] state (at safeAsyncFunction)
...
Attached is the screenshot of the full error log as shown in the developer console:
https://github.com/user-attachments/assets/50c7bda9-ea8e-4032-bfbd-7396ec743ae5
Expected behavior
- No Alpine runtime error should be triggered.
Steps to reproduce
- Create a Filament form schema using tabs.
- Inside the second the tab item, add a Forms\Components\Textarea::make() field.
- Render the page.
- Observe the browser console for the ReferenceError.
Reproduction repository (issue will be closed if this is not valid)
https://github.com/str4wh4t/app-filament-issue-3.x
Relevant log output
So I investigated a bit and found out that if I open the page at the first tab, and click save, the error shows just as the video.
However if I open the second tab, then return to the first, and click save, no error appears.
As if opening the second tab is loading that second text area making it available in javascript. Specifically this script is requested only when opening the second tab:
/js/filament/forms/components/textarea.js?v=3.3.18.0
So to resolve we should either:
- ensure the scripts for all fields in a form are loaded on page load instead of waiting for it to be visible then loading it
- not interact with components which values did not change, or did not load to begin with, something such as:
if (typeof textareaFormComponent === 'undefined') return;
In packages/forms/resources/views/components/textarea.blade.php, replacing visible with eager:
from
<textarea
@if (FilamentView::hasSpaMode())
{{-- format-ignore-start --}}x-load="visible || event (ax-modal-opened)"{{-- format-ignore-end --}}
to
<textarea
@if (FilamentView::hasSpaMode())
{{-- format-ignore-start --}}x-load="eager || event (ax-modal-opened)"{{-- format-ignore-end --}}
Allows the script to load correctly! Although it might have performance impact on other parts of filament.
So maybe we should detect if the component is inside of a tab and if that's the case load it immediately?
I'd be happy to open a PR for this btw :)
thank you for your investigation @Saad5400 , please can you open a PR so it will fix this bug in future release . i love to use spa mode in filament . but this bug only occur in spa mode .
This is happening with SPA mode in v4 as well. And also with Wizards:
https://github.com/user-attachments/assets/599a18e0-d618-4c9b-8e34-0dc2c30abaf0
Reproduction repo: https://github.com/binaryfire/filament-bug-reproduction (Wizard Text Area Not Found page).
I can confirm that changing the Async Alpine loading strategy to eager on the textarea view fixes it. Happy to PR that change for all the components but maybe you've got an idea for a more performant fix... Eg. if this only happens in tabs and wizards, maybe we can detect when fields are inside one of those schema types and only use eager then?
On the other hand, loading all assets when the page loads might have advantages too. It'd probably eliminate that momentary visual glitch after switching tabs / steps while the js is still being loaded.
Fixed in 4.x by #16817