Wednesday, June 25, 2014

Using Tooltips With Form Validation

The jQuery UI tooltip widget is a good way to describe what's required in a specific form input element. A good way to instruct the user, so that they're less likely to receive validation errors when they submit the form. Even with this help, the user will likely get something wrong, or just forget to supply information altogether. In this case, you can use the same tooltip widget to provide a subtle visual cue that there's something wrong with their input.

For example, here's what the form might look like as they're filling it out - before they make a submission attempt.

And here's what happens when the user tries to submit the form without supplying the first name field.

Note that this form validation also changes the state of the input itself. It also changes the visual state of the tooltip, but it's only displayed if the user hovers over the input, or if the input gains focus. We're not even changing the content of the tooltip when it enters the error state. We usually shouldn't have to because it's going to be something trivial the user got wrong, and the visual cue is enough to set them on the right path. Here's what the tooltip and validation code looks like.

function error( $input ) {
    return $input
        .tooltip( 'option', {
            tooltipClass: 'ui-state-error'
        }).addClass( 'ui-state-error' );
}

$(function () {

    $( '[title]' ).tooltip().on({
        focusin: function( e ) {
            $( e.currentTarget )
                .addClass( 'ui-state-focus' );
        },
        focusout: function( e ) {
            $( e.currentTarget )
                .removeClass( 'ui-state-focus' );
        }
    });

    $( '[type="submit"]' ).button();

    $( 'form' ).on( 'submit', function( e ) {
        e.preventDefault();
        var params = $( e.currentTarget )
            .serializeArray()
            .reduce( function( result, i ) {
                result[ i.name ] = i.value;
                return result;
            });
        if ( !params.firstname ) {
            error( $( '[name="firstname"]' ) );
        }
        if ( !params.lastname ) {
            error( $( '[name="lastname"]' ) );    
        }
        if ( !params.address ) {
            error( $( '[name="address"]' ) );   
        }
    });
});