Issue
Platform: Windows 10. Firefox 119.
I built a modal dialog in a more complex project and came across this bug. The other browsers I'm testing on are Chrome and Edge. These don't have the bug. The following code is a highly-simplified version of my original project.
In Firefox, as soon as you click on the select dropdown, the modal closes, not allowing the form to be submitted.
Has anyone else come across this? Has anyone got a fix?
Note: fixed - see answer below. Updated Demo: https://jsfiddle.net/najfiddle/1uxw2Le8/9/
/** Form **/
const form = document.getElementById("form")
form.addEventListener("submit", e => {
e.preventDefault()
e.target.reset()
modal.close()
})
/** Modal **/
const launchModalBtn = document.getElementById("launch-modal")
const modal = document.getElementById("modal")
launchModalBtn.addEventListener("click", () => {
modal.showModal()
})
/* modal backdrop */
modal.addEventListener("click", (e) => {
const modalDimensions = modal.getBoundingClientRect()
if (
e.clientX < modalDimensions.left ||
e.clientX > modalDimensions.right ||
e.clientY < modalDimensions.top ||
e.clientY > modalDimensions.bottom
) {
form.reset()
modal.close()
}
})
/*Form */
form,
form>div {
display: flex;
flex-direction: column;
gap: 1rem;
}
/** Modal */
.modal {
z-index: 50;
padding: 4rem;
margin: auto;
border-radius: 0.2rem;
border: 0;
}
.modal-content {
display: flex;
flex-direction: column;
gap: 2rem;
align-items: flex-end;
}
.modal::backdrop {
background-color: rgba(9, 9, 70, 0.8);
z-index: 40;
cursor: pointer;
}
<button id="launch-modal">
Open modal
</button>
<dialog id="modal" class="modal">
<div class="modal-content">
<form id="form">
<div class="word-phrase">
<label for="term" class="term">Word</label>
<input id="term" type="text">
</div>
<div>
<label for="definition">Definition </label>
<textarea id="definition" rows="5" cols="50"></textarea>
</div>
<div>
<label for="language-select">Choose language</label>
<select id="language-select" name="language-select">
<option value="en">English</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="it">Italian</option>
<option value="la">Latin</option>
<option value="es">Spanish</option>
<option value="und">Other</option>
</select>
</div>
<div>
<button>Submit</button>
</div>
</form>
</div>
</dialog>
Solution
I can confirm the issue. There is a similar issue with drag: https://bugzilla.mozilla.org/show_bug.cgi?id=505521#c80
The issue is: you get a clientX and Y which are 0 when you click the select or its options.
The safest solution is to not look at the bounding box but just check if the click was inside the form
Tested in Fx 118 and 119 on Windows 10
/** Form **/
const form = document.getElementById("form")
form.addEventListener("submit", e => {
console.log("submitted")
e.preventDefault()
e.target.reset()
modal.close()
})
/** Modal **/
const launchModalBtn = document.getElementById("launch-modal")
const modal = document.getElementById("modal")
launchModalBtn.addEventListener("click", () => {
modal.showModal()
})
/* modal backdrop */
modal.addEventListener("click", (e) => {
const formClicked = e.target.closest('form');
if (!formClicked) { //click was NOT inside the form
form.reset()
modal.close()
}
})
/*Form */
form,
form>div {
display: flex;
flex-direction: column;
gap: 1rem;
}
/** Modal */
.modal {
z-index: 50;
padding: 4rem;
margin: auto;
border-radius: 0.2rem;
border: 0;
}
.modal-content {
display: flex;
flex-direction: column;
gap: 2rem;
align-items: flex-end;
}
.modal::backdrop {
background-color: rgba(9, 9, 70, 0.8);
z-index: 40;
cursor: pointer;
}
<button id="launch-modal">
Open modal
</button>
<dialog id="modal" class="modal">
<div class="modal-content">
<form id="form">
<div class="word-phrase">
<label for="term" class="term">Word</label>
<input id="term" type="text">
</div>
<div>
<label for="definition">Definition </label>
<textarea id="definition" rows="5" cols="50"></textarea>
</div>
<div>
<label for="language-select">Choose language</label>
<select id="language-select" name="language-select">
<option value="en">English</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="it">Italian</option>
<option value="la">Latin</option>
<option value="es">Spanish</option>
<option value="und">Other</option>
</select>
</div>
<div>
<button>Submit</button>
</div>
</form>
</div>
</dialog>
The code above will only close the modal if you click OUTSIDE the blue area if you use closest("form") and green area if you use .closest(".modal-content")
Answered By - mplungjan
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.