Skip to content

Instantly share code, notes, and snippets.

@whiteinge
Last active July 27, 2023 10:28
Show Gist options
  • Save whiteinge/25342d6488c38ac1f6285accfe3527e2 to your computer and use it in GitHub Desktop.
Save whiteinge/25342d6488c38ac1f6285accfe3527e2 to your computer and use it in GitHub Desktop.
A wrapper around FormData to return an object with checkbox booleans and arrays for compound fields
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>A wrapper around FormData</title>
<style>
form > div { margin-bottom: 1em; }
</style>
<script>
function handleSubmit(ev) {
ev.preventDefault();
const data = getFormData(ev.target, ev.submitter)
console.log('XXX', data)
// ---
/**
A wrapper around FormData to return booleans for checkboxes and
arrays for compound elements (for easier JSON serialization)
**/
function getFormData(formEl, submitter) {
const formData = new FormData(formEl, submitter)
const data = Array.from(formData.keys()).reduce((acc, key) => {
const vals = formData.getAll(key)
const val = vals.length > 1 ? vals : vals.shift()
acc[key] = val
return acc
}, {})
const isValidCheckbox = x => x.name != null
&& x.disabled !== true
&& x.type === 'checkbox'
const checkboxes = Array.from(formEl.elements)
.filter(isValidCheckbox)
.reduce((acc, el) => {
const item = formEl.elements.namedItem(el.name)
const vals = (item.length > 1 ? Array.from(item) : [item])
.filter(isValidCheckbox)
.map(x => x.checked)
const val = vals.length > 1 ? vals : vals.shift()
acc[el.name] = val
return acc
}, {})
return Object.assign(data, checkboxes)
}
}
</script>
</head>
<body>
<form id="form" onsubmit="handleSubmit(event)">
<div>
text1:
<input type="text" name="text1" value="foo" />
</div>
<div>
text2:
<input type="text" name="text2" value="bar" />
<input type="text" name="text2" value="baz" />
</div>
<div>
text3:
<input type="text" name="text3" />
</div>
<div>
check1:
<input type="checkbox" name="check1" checked />
</div>
<div>
check2:
<input type="checkbox" name="check2" checked disabled />
</div>
<div>
check3:
<input type="checkbox" name="check3" />
<input type="checkbox" name="check3" checked />
<input type="checkbox" name="check3" checked disabled />
</div>
<div>
selectSingle:<br>
<select name="selectSingle">
<option value="first">First Value</option>
<option value="second" selected>Second Value</option>
<option value="third">Third Value</option>
</select>
</div>
<div>
selectMultiple:<br>
<select name="selectMultiple" multiple size="4">
<optgroup label="4-legged pets">
<option value="dog" selected>Dog</option>
<option value="cat" selected>Cat</option>
<option value="hamster" disabled>Hamster</option>
</optgroup>
<optgroup label="Flying pets">
<option value="parrot">Parrot</option>
<option value="macaw">Macaw</option>
<option value="albatross">Albatross</option>
</optgroup>
</select>
</div>
<div>
radio1:<br>
<input type="radio" name="radio1" value="email" checked />
<label for="contactChoice1">Email</label>
<input type="radio" name="radio1" value="phone" />
<label for="contactChoice2">Phone</label>
<input type="radio" name="radio1" value="mail" />
<label for="contactChoice3">Mail</label>
</div>
<div>
radio2:<br>
<input type="radio" name="radio2" value="email" />
<label for="contactChoice1">Email</label>
<input type="radio" name="radio2" value="phone" />
<label for="contactChoice2">Phone</label>
<input type="radio" name="radio2" value="mail" />
<label for="contactChoice3">Mail</label>
</div>
<div>
image1:
<input type="file" name="image1" accept="image/png, image/jpeg">
</div>
<div>
button1:<br>
<button name="button1" value="save">Save</button>
<button name="button1" value="saveAsCopy">Save As Copy</button>
</div>
</form>
</body>
</html>
@whiteinge
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment