Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Typescript

Working with Forms in Griffin.Yo – A Spa Library in TypeScript

0.00/5 (No votes)
7 Aug 2015LGPL32 min read 5.2K  
Working with Forms in Griffin.Yo – A Spa Library in TypeScript

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:

XML
<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:

JavaScript
var form = new FormReader("MyForm");
var dto = form.read();

// .. or in your view model:
var dto = ctx.readForm("MyForm");

The returned result is a json document:

JavaScript
{
    "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:

XML
<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 ..

JavaScript
{
    "Mood": "Tired"
}

Check Boxes

The same applies for check boxes:

XML
<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 ..

JavaScript
{
    "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:

XML
<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:

JavaScript
{
    "Brands":["Headlight","OneTrueError","Griffin.Framework"]
}

But if your collection contains complex objects, you simply specify the name of the items:

XML
<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:

JavaScript
{
    "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:

XML
<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:

JavaScript
{
    "FirstName": "Jonas",
    "LastName": "Gauffin",
    "Address": {
        "Street": "Awesome street",
        "PostalCode": 12345,
        "City": "Falun"
    }
}

The second option is to use dot notation in the input names:

XML
 <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. Strings containing numbers are converted to JSON numbers. Everything else is treated as strings.

Summary

The code is available at github.

Questions? Missing a feature? Write a comment.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)