I have a form for which I want to use a dialog to confirm submission. It would be convenient for me to nest the dialog inside the form so that it is easier to dertermine which dialog belongs to which form when querySelector’ing them with javascript. Below are two minimal examples of this. In the first the dialog is outside the form and works as expected. In the second the dialog is nested inside the form and for some reason only the Yes button works, the No button does nothing.
const form = document.getElementById("myForm");
const dialog = document.getElementById("confirmDialog");
const confirmBtn = document.getElementById("confirmBtn");
const cancelBtn = document.getElementById("cancelBtn");
form.addEventListener("submit", function(event) {
event.preventDefault();
dialog.showModal();
});
confirmBtn.addEventListener("click", function() {
dialog.close();
form.submit(); // Continue form submission
});
cancelBtn.addEventListener("click", function() {
dialog.close(); // Cancel form submission
});
<form id="myForm">
<input type="submit" value="Submit" />
</form>
<dialog id="confirmDialog">
<p>Are you sure you want to submit this form?</p>
<menu>
<button id="confirmBtn">Yes</button>
<button id="cancelBtn">No</button>
</menu>
</dialog>
const form = document.getElementById("myForm");
const dialog = document.getElementById("confirmDialog");
const confirmBtn = document.getElementById("confirmBtn");
const cancelBtn = document.getElementById("cancelBtn");
form.addEventListener("submit", function(event) {
event.preventDefault();
dialog.showModal();
});
confirmBtn.addEventListener("click", function() {
dialog.close();
form.submit(); // Continue form submission
});
cancelBtn.addEventListener("click", function() {
dialog.close(); // Cancel form submission
});
<form id="myForm">
<input type="submit" value="Submit" />
<dialog id="confirmDialog">
<p>Are you sure you want to submit this form?</p>
<menu>
<button id="confirmBtn">Yes</button>
<button id="cancelBtn">No</button>
</menu>
</dialog>
</form>
2
Answers
It would seem when the dialog is nested inside the form, the click event on the "No" button triggers the form submission by default, preventing you from handling the cancel action at your discretion.
You can modify the code to prevent the default form submission when the "No" button is clicked by calling the
preventDefault()
method:Any button inside a
<form>
will be a submit button by default.So you could avoid the default action, which is submitting the form, by using the
preventDefault()
method in your listener.I would recommend changing the
type
of these buttons, to solve the issue closer to the root cause and avoid unforeseen consequences. Assistive technology, for example, might otherwise assume they are submit buttons.