I’ve pushed a new release that includes a form reader. With a few lines of code, you can get a complete JSON object, including hierarchy from an HTML form.
When building a spa, you typically do not want forms to be submitted as a regular http request, as it would defeat the purpose of a spa. As you already work with Ajax and JSON, why not use it for form submissions too? It’s now possible in Griffin.Yo.
Start by declaring a simple form:
<form id="MyForm">
<div>
<label>First name:</label>
<input name="FirstName" value="Jonas">
</div>
<div>
<label>Last name:</label>
<input name="LastName" value="Gauffin">
</div>
</form>
Reading it is done with the FormReader
class:
var form = new FormReader("MyForm");
var dto = form.read();
var dto = ctx.readForm("MyForm");
The returned result is a json document:
{
"FirstName": "Jonas",
"LastName": "Gauffin"
}
Radio Buttons
Radio buttons are only appended to the JSON document if they are checked, i.e., all other options are ignored:
<form id="MyForm">
<label>Mood</label>
<input type="radio" name="Mood" value="Rocking"> Rocking
<input type="radio" name="Mood" value="Tired" checked> Tired
<input type="radio" name="Mood" value="Excited"> Excited
</form>
.. results in ..
{
"Mood": "Tired"
}
Check Boxes
The same applies for check boxes:
<form id="MyForm">
<label>Moods</label>
<input type="checkbox" name="Moods" value="Rocking"> Rocking
<input type="checkbox" name="Moods" value="Tired" checked> Tired
<input type="checkbox" name="Moods" value="Excited" checked> Excited
</form>
.. results in ..
{
"Moods": ["Tired", "Excited"]
}
.. which is great since we get an array back.
Collections
Collections are typically difficult to handle in HTML forms, as there is nothing in the HTML specification that states how they should be handled. In this implementation, they are represented by the “data-collection
” attribute.
If you are working with collections that have a single value, you use the special input name “[]
” to indicate that. Example follows:
<form id="MyForm">
<div data-collection="Brands">
<label>Your favorite brands</label>
<p>In reality you and new inputs using javascript and a button.
Just imagine that it's been done here.</p>
<input name="[]" value="Headlight" />
<input name="[]" value="OneTrueError" />
<input name="[]" value="Griffin.Framework" />
</div>
</form>
Which results in:
{
"Brands":["Headlight","OneTrueError","Griffin.Framework"]
}
But if your collection contains complex objects, you simply specify the name of the items:
<div data-collection="Addresses">
<label>Enter your addresses</label>
<input name="Street" value="Here1" />
<input name="City" value="Falun" />
<input name="Street" value="Here2" />
<input name="City" value="Stockholm" />
</div>
Each new item is automatically created when the same input name is repeated. Thus, as long as you have all inputs in the same order, it works pretty excellent.
Result:
{
"Addresses": [{
"Street": "Here",
"City": "Falun"
}, {
"Street": "Here2",
"City": "Stockholm"
}]
}
Complex Objects
Same thing goes for complex objects. There is nothing in the HTML spec. With this library, you have two options.
The first option is to include a <div data-name="SubObjectName">
to wrap the sub
object:
<form id="MyForm">
<div>
<label>First name:</label>
<input name="FirstName" value="Jonas">
</div>
<div>
<label>Last name:</label>
<input name="LastName" value="Gauffin">
</div>
<div data-name="Address">
<h2>Address</h2>
<label>Street:</label>
<input name="Street" value="Awesome street"><br>
<label>Postal code:</label>
<input name="PostalCode" value="12345"><br>
<label>City:</label>
<input name="City" value="Falun"><br>
</div>
</form>
.. which would generate the following JSON:
{
"FirstName": "Jonas",
"LastName": "Gauffin",
"Address": {
"Street": "Awesome street",
"PostalCode": 12345,
"City": "Falun"
}
}
The second option is to use dot notation in the input names:
<div>
<h2>Address</h2>
<label>Street:</label>
<input name="Address2.Street" value="Awesome street"><br>
<label>Postal code:</label>
<input name="Address2.PostalCode" value="12345"><br>
<label>City:</label>
<input name="Address2.City" value="Falun"><br>
</div>
.. which will give you the same result.
Value Handling
All values are parsed. For instance, the string
values “true
” and “false
” are converted to a JSON bool
. String
s containing numbers are converted to JSON numbers. Everything else is treated as string
s.
Summary
The code is available at github.
Questions? Missing a feature? Write a comment.