Appendix JS_F_AA1

Summary

Requirement: If an input error is detected, and suggestions for corrections are known, these can be provided in text.

Details: Where form fields require a specific format or range of values, contextual help-text can be programmatically inserted directly after the field it relates to, using functions of the DOM.

Examples

Correct code

Refer to the JS_F_AA1 live demo for a working example.

<form id="demo" action="..." method="get">
    <fieldset>
        <p>
            <label for="username">Username:</label>
            <input id="username" name="username" type="text" />
        </p>
        <p>
            <label for="email">Email:</label>
            <input id="email" name="email" type="text" />
        </p>
        <p>
            <label for="password">Password:</label>
            <input id="password" name="password" type="password" />
        </p>
    </fieldset>
    <fieldset>
        <button type="submit">Submit</button>
    </fieldset>
</form>
var form = document.getElementById('demo');
var fields = form.getElementsByTagName('input');
var help = 
{
    username : 'Usernames can only contain letters, '
             + 'numbers, spaces or dashes.',
    email    : 'Please make sure you enter a valid '
             + 'email address.'
};
 
for(var i = 0; i < fields.length; i ++)
{
    fields[i].help = null;
 
    fields[i].addEventListener('focus', function(e)
    {
        var field = e.target;
 
        if(typeof(help[field.name]) != 'undefined' 
            && field.help === null)
        {
            var label = document.createElement('label');
            label.htmlFor = field.id;
            label.className = 'help';
            var message = label.appendChild(
                document.createElement('em'));
            message.appendChild(
                document.createTextNode(
                    help[field.name]));
 
            field.help = 
                field.parentNode.appendChild(label);
        }
    }, false);
 
    fields[i].addEventListener('blur', function(e)
    {
        var field = e.target;
 
        if(field.help !== null)
        {
            field.parentNode.removeChild(field.help);
            field.help = null;
        }
    }, false);
}
 
form.addEventListener('submit', function(e)
{
    for(var i = 0; i < fields.length; i ++)
    {
        if(fields[i].help !== null)
        {
            fields[i].parentNode.removeChild(
                fields[i].help);
            fields[i].help = null;
        }
    }
}, false);