Created
August 22, 2023 21:51
-
-
Save dfkaye/938b9bf78f63968491b82cc4378c1c3b to your computer and use it in GitHub Desktop.
scoped reset button actions on fields in the same fieldset.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 16 August 2023 | |
// Scoped reset button actions on fields in the same fieldset. | |
// This is one way to manage resetting only radio groups or checkboxes in a form | |
// without resetting every other element. | |
// We could go further and group such related fields in separate forms to avoid | |
// any JavaScript with click handler logic. | |
// This came up because one of the loudest front-end developers on Twitter was | |
// completely baffled as to why radio elements cannot be completely un-selected | |
// by the user, even when none of them in the group is checked by default. | |
// Rather than waste time debating the Why and/or urging a revision to the spec | |
// for radio groups now 20-something years old, we show how you can reset all | |
// elements in a form, or some elements in selected fieldsets using a custom | |
// data attribute with names of resettable elements (in this case only the | |
// checkable ones). | |
// We also contrast scoped reset with global reset and scoped submit with | |
// global submit. | |
// With that, we start with a template literal that we'll pass into the DOM... | |
var html = ` | |
<form name=one> | |
<fieldset name=first data-scope="F"> | |
<legend>first</legend> | |
<label for="F.1">F1</label> | |
<input type=radio value=1 name="F" id="F.1"> | |
<label for="F.2">F2</label> | |
<input type=radio value=2 name="F" value=2 id="F.2"> | |
<hr> | |
<input type=reset value="Clear first"> | |
<input type=submit value="Submit first"> | |
</fieldset> | |
</form> | |
<form name=two> | |
<fieldset name=other data-scope="O"> | |
<legend>other</legend> | |
<input type=checkbox name="O" id="O.1"> | |
<label for="O.1">check</label> | |
<hr> | |
<input type=reset value="Clear other"> | |
<input type=submit value="Submit other"> | |
<hr> | |
<label for=t1>t1</label> | |
<input id=t1 name=t1> | |
</fieldset> | |
<hr> | |
<input type=reset value="Clear all"> | |
<input type=submit value="Submit all"> | |
</form> | |
`; | |
// Then insert it using setHTML() (if in Chrome, to avoid the "trusted HTML" CSP | |
// policy in "blank" windows... | |
`setHTML` in document.body | |
? document.body.setHTML(html) | |
: document.body.innerHTML = html; | |
// reset and submit examples follow... | |
/* reset */ | |
document.querySelectorAll(`[type="reset"]`).forEach(reset => { | |
var fs = reset.closest(`[data-scope]`); | |
var name = fs && fs.getAttribute("data-scope"); | |
if (!name) { | |
reset.addEventListener("click", function (e) { | |
Array.from(document.forms).forEach(form => { | |
form.reset(); | |
}); | |
console.log("normal course"); | |
}); | |
return; | |
} | |
reset.addEventListener("click", function (e) { | |
e.preventDefault(); | |
// yes, use the form.elements array. | |
var group = reset.form.elements[name]; | |
var elms = group.length > 1 | |
? Array.from(group) | |
: [group]; | |
// yes, use defaultChecked. | |
elms.forEach(function (f) { f.checked = f.defaultChecked; }); | |
}); | |
}); | |
/* submit */ | |
document.querySelectorAll(`[type="submit"]`).forEach(submit => { | |
var fs = submit.closest(`[data-scope]`); | |
var name = fs && fs.getAttribute("data-scope"); | |
if (!name) { | |
submit.addEventListener("click", function (e) { | |
e.preventDefault(); | |
var data = new FormData; | |
Array.from(document.forms).forEach(form => { | |
var formData = new FormData(form); | |
console.log("form", form.name, ":",); | |
for (var [k, v] of formData) { | |
data.set(k, v); | |
} | |
}); | |
return console.log("all data:", data); | |
}); | |
return; | |
} | |
submit.addEventListener("click", function (e) { | |
e.preventDefault(); | |
var { form } = submit; | |
var formData = new FormData(form); | |
return console.log("form", form.name, ":", formData) | |
}); | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment