F
Filamentβ€’2w ago
lukaveck1

Modal closes only on certain field when I click away

I just upgraded from filament V3 to V4 and noticed modal isn't closing when clicking away on certain field. I have ->closeModalByClickingAway(true) on my modal, when I'm on 'title' field and click away the modal doesn't close, I don't get any error anywhere, when I then click on 'content' field, I can click away and the modal closes, again no errors anywhere. Any ideas? Code in test123.txt
17 Replies
LeandroFerreira
LeandroFerreiraβ€’2w ago
could you change the action name from edit to editTable and try again?
lukaveck1
lukaveck1OPβ€’2w ago
Doesn't work
Dennis Koch
Dennis Kochβ€’2w ago
Does this happen with any TextInput?
lukaveck1
lukaveck1OPβ€’2w ago
Yes
lukaveck1
lukaveck1OPβ€’2w ago
So, I just went through the source code for this and read the docs and found few things that aren't mentioned in docs https://filamentphp.com/docs/4.x/actions/modals#closing-the-modal-by-clicking-away 1. If the input field on modal is toggled, then the modal doesn't close due to this piece of code in source code of modal/index.blade.php: @if ($closeByClickingAway) {{-- Ensure that the click element is not triggered from a user selecting text inside an input. --}} x-on:click.self=" document.activeElement.selectionStart === undefined && document.activeElement.selectionEnd === undefined && {{ $closeEventHandler }} " This does not mimic behavior of pressing escape button, which closes modal no matter what and it's also why I went down this rabbit hole. 2. If the field on modal is RichEditor and toggled, then the same behavior does not apply, since the HTML element for that is quite different from your standard Text input field and alpine doesn't handle logic the same way. FIX: I changed the source code of modal/index.blade.php a bit as below and now it handles the logic for fields with text editor correctly. @if ($closeByClickingAway) {{-- Ensure that the click element is not triggered from a user selecting text inside an input. --}} x-on:click.self=" ( (!document.activeElement || document.activeElement.selectionStart === undefined) && document.activeElement?.getAttribute('contenteditable') !== 'true' ) && {{ $closeEventHandler }} " 3. Can you please add in documentation that modals won't close by clicking away despite having ->closeModalByClickingAway() if any field on modal is toggled? If that is even intended logic, since pressing escape closes modal no matter what :). @Dennis Koch @LeandroFerreira
Dennis Koch
Dennis Kochβ€’2w ago
Do you mind sending that as a PR? πŸ˜…
lukaveck1
lukaveck1OPβ€’2w ago
Yes, but can you elaborate why is the logic different when clicking away and pressing escape, looks intended but in docs nothing is said about fields being toggled and clicking away not working in that scenario?
Dennis Koch
Dennis Kochβ€’2w ago
See the comment:
Ensure that the click element is not triggered from a user selecting text inside an input.
That's not needed when pressing ESC
lukaveck1
lukaveck1OPβ€’2w ago
Yeah, but add that to docs site.. πŸ˜„
Dennis Koch
Dennis Kochβ€’2w ago
It's obviously a bug. The modal should close on click away. But apparently it closed when selecting text in the past. That's why I'm asking whether you could submit a PR. For the code. Not for the docs πŸ˜…
lukaveck1
lukaveck1OPβ€’2w ago
Yes, I'm just trying to make sure what's even the intended behavior here and if it's correct that modal shouldn't close when field is toggled. Because when we press escape we are closing it anyway. Two different behaviors for seemingly same procedure - closing the modal on some event.
Dennis Koch
Dennis Kochβ€’2w ago
Intended behaviour should be the same for both: Close the modal on action
lukaveck1
lukaveck1OPβ€’4d ago
@Dan Harrin Can you explain to me how to reproduce this problem https://github.com/filamentphp/filament/commit/e61efcdea78dd5af91d0b049930d31c39b95c569 I'm not sure how click event was triggered by selecting text inside input field and this change makes it impossible to close modal now, if input field is toggled. Dennis said that it should close in any case, like it happens when pressing escape. I was trying to fix this, but now I'm not able to replicate the issue in first place.
Dan Harrin
Dan Harrinβ€’4d ago
iirc if you have content in a text input, start selecting it by dragging your mouse, and release the mouse when your pointer is outside the modal
lukaveck1
lukaveck1OPβ€’3d ago
Oh, just noticed we have a custom fix for this in some separate .js file. And if I just leave it with how it was before you made the fix it works correctly. const preventClick = function (event) { event.stopPropagation(); event.preventDefault(); document.removeEventListener('click', preventClick, true); }; document.addEventListener('DOMContentLoaded', function () { // Track where interaction began let mouseDownOnModal = false; const modalElementClass = ".fi-modal-window"; const backdropElementClass = ".fi-modal-close-overlay"; const filamentPageElementClass = ".fi-page"; // Handle mousedown - just track where it started document.addEventListener('mousedown', function (e) { if (e.target.closest(modalElementClass)) { mouseDownOnModal = true; } }, true); // Handle mouseup - prevent only specific scenarios document.addEventListener('mouseup', function (e) { // Mouse up on modal, return if (e.target.closest(modalElementClass) != null) { if (mouseDownOnModal) { mouseDownOnModal = false; return; } // If mouse was not down on modal prevent default document.addEventListener('click', preventClick, true); return; } // Check if mouse was not up on modal but on backdrop const endedOnBackdrop = e.target.closest(modalElementClass) == null && (e.target.closest(backdropElementClass) != null || e.target.closest(filamentPageElementClass) != null); // Only prevent if drag started inside and ended on backdrop if (mouseDownOnModal && endedOnBackdrop) { document.addEventListener('click', preventClick, true); } else { document.removeEventListener('click', preventClick, true); } // Reset tracking mouseDownOnModal = false; }, true); }); This fixes everything basically and you can revert to pre-fix version with it. Not sure though where to integrate something like this, we just have custom file named modal-fix.js. @Dennis Koch @Dan Harrin I'm just looking at this again and trying to push the fix, but I'm having problem testing this. Basically, I forked filament project and pulled it into my app. Now I made changes in modal.js (console.log) and these changes aren't being reflected in browser, as if I didn't change modal.js at all. After making changes in modal.js I also went into filament/packes/support directory and did npm install, npm run build and can see that my fork changes are reflected in my vendor files (modal.js, support.js and dist/index.js in support dir for fork and vendor). However, my browser still loads as if I didn't do any changes, any ideas? I'm disabling cache in browser and also cleared in my app.
Dan Harrin
Dan Harrinβ€’3d ago
you need to run artisan filament:assets
lukaveck1
lukaveck1OPβ€’3d ago
Yeah works now thanks, I did run php artisan vendor:publish --tag=filament-assets, but I guess this is deprecated.

Did you find this page helpful?