Inline form validation with gravity forms

At work we recently launched this awesome new site for Kallo where (among other things) I attempted to add inline form validation to the somewhat clunky Gravity Forms interface.

When you submit a form with validation errors (such as required fields not being filled in), Gravity Forms provides useful class hooks like .gfield_error and .gfield_contains_required which can be styled to provide visual feedback to the user. However, I always disliked the fact that on corrected my mistakes, the shouty error messages and bright red text would still remain.

This little jQuery snippet does a bit of the old class-name-switchero to provide user-friendly feedback based on whether inputs are valid or not. If you’re not using Gravity Forms, you could modify the classes accordingly for similar behaviour. For a warning about browser compatibility and how to work around it, keep reading below

// if an invalid form field has been made valid,
// remove the shouty error highlighting - if a valid
// required field has been made invalid, start shouting

$('input, textarea, select').on('change', function(){
    var $input     = $(this);
    var isRequired = $input.parents('.gfield').is('.gfield_contains_required');
    var isValid    = $input.is(':valid');

    if ( isRequired && isValid ) {
        $input.parents('.gfield').removeClass('gfield_error');
        $input.parent().next('.validation_message').slideUp();
    }

}).blur(function(){
    var $input     = $(this);
    var isRequired = $input.parents('.gfield').is('.gfield_contains_required');
    var isInValid  = $input.is(':invalid');
    var isEmpty    = $input.val() === '';

    if ( isRequired && ( isInValid || isEmpty ) ) {
        $input.parents('.gfield').addClass('gfield_error');
        $input.parent().next('.validation_message').slideDown();
    }
});

Here it is a a Github gist

Here we create a couple of conditions like isRequired or isValid by making use some CSS3 pseudo classes and/or checking the Gravity Forms hooks. You can also use these in the CSS:

input,
input:valid,
select,
select:valid,
textarea,
textarea:valid {
    /* normal styles & valid input styles */
}
input:invalid,
select:invalid,
textarea:invalid {
    /* invalid input styles */
}

By grouping these styles together, the inline validation turning on and off works a treat.

Browser compatibility

This was all working great in Chrome (and other modern browsers) but failed miserably in IE9 and below. I had completely forgotten that IE9 doesn’t support these pseudo selectors and as they were part of a comma separated list, none of the styles (valid or otherwise) applied correctly.

Fortunately, using a bit of Sass, this problem was easy to overcome whilst reducing the potential for lots of nasty duplication.

@mixin valid-form-styles {
    /* normal & valid form styles */
}
@mixin invalid-form-styles {
    /* invalid form styles */
}
input,
select,
textarea {
    @include valid-form-styles;
}
input:valid,
select:valid,
textarea:valid {
    @include valid-form-styles;
}
input:invalid,
select:invalid,
textarea:invalid {
    @include invalid-form-styles;
}

Browsers that don’t understand a selector, ignore it. If an unknown selector occurs in a comma-separated block, the whole block gets ignored. Splitting the concern here enables us to have a single place to update the valid/invalid style declarations (which is nice and DRY) and means that non-supporting browsers don’t interfere with our best-laid plans for good user feedback. Progressive enhancement at it’s best!

If you hate email but still want to keep in touch, follow me on Twitter.

Guy Routledge avatar
Currently available hire me