We identify HTML :mappable types. All form elements are :mappable, but it should be plausible to create your own.
:mappable types have a .mapToObject(?Object) method and an .mapFromObject(Object) methods
##mapToObject(?Object)
Given
<input name="foo" value="bar">I can call:
var o = document.querySelector("input[name='foo']").maptoObject()and it will map this into an object:
{ "foo": "bar" }I can provide it an existing object:
var om = document.querySelector("input[name='foo']").mapToObject({"hello": "world"});and it will set it's mapped values into the provided object:
{ "hello": "world", "foo": "bar" }The .mapToObject() method can be overridden/provided by custom elements to provide custom mappings.
##mapFromObject(Object)
Likewise, :mappable objects have a .mapFromObject(object) which inverts the process. Given an object it can set the values of the element according to the mappings, so, given:
<input name="foo">
<script>
document.querySelector('input').mapFromObject({ "hello": "world", "foo": "bar" });
</script>The form will wind up as
<input name="foo" value="bar">Just as before, this element can be overridden too. Overriding both would allow you to, for example, create something that mapped to the text content of a span instead of the standard name/value strategy.
##HTMLFormElement
HTMLFormElement specifically implments these methods such that it merely iteratates over its children who are mappable, so given:
my-page.html
<form>
<input name='pet[0][species]'>
<input name='pet[0][name]'>
<input name='pet[1][species]'>
<input name='pet[1][name]'>
</form>
<script>
$.getJSON("some/service.json").then(function (data) {
document.querySelector("form").mapFromObject(someServiceData);
})
</script>If the data looked like this:
{
"pet": [
{
"species": "Dahut",
"name": "Hypatia"
},
{
"species": "Felis Stultus"
"name": "Billie"
}
]
}It would set all the values indicated by the mappings:
<form>
<input name='pet[0][species]' value='Dahut'>
<input name='pet[0][name]' value='Hypatia'>
<input name='pet[1][species]' value='Felis Stultus'>
<input name='pet[1][name]' value='Billie'>
</form>And similarly if I now said:
var om = document.querySelector("form").mapToObject();It would walk through those elements and yield output that is identical to the service call above.
##Form Submission
Submitting a <form> does something like
var submittable = { <<submission info like x,y>> };
var elements = mappableElements.filter(function (element) {
return <<the result of submittability tests>>;
});
elements.forEach(function (element) {
submittable.mapToObject(submittable);
});
this.serialize(submittable);serialize(object) relies on another property of HTMLFormElement (plugin style) the .serializer() function which is set automatically according to the enctype attribute, but may be overridden.