Search code examples
backbone.jshandlebars.jswebshim

Webshims - Show invalid form fields on initial load


(Follow on questions from Placeholder Hidden)

I'd like my form to validate existing data when it is loaded. I can't seem to get that to happen

  • I jQuery.each of my controls and call focus() and blur(), is there a better way than this? I tried to call ctrl.checkValidity(), but it wasn't always defined yet. When it was, it still didn't mark the controls.
  • I seem to have a timing issue too, while the focus and blur() fire, the UI does not update. It's as if the Webshims are not fully loaded yet, even though this fires in the $.webshims.ready event.
  • I also tried to call $('#form').submit(), but this doesn't fire the events as I expected. The only way I could make that happen was to include an input type='submit'. How can I pragmatically case a form validation like clicking a submit button would?

Here's a jsFiddle that demonstrates the problem. When the form loads, I want the invalid email to be marked as such. If you click the add button it will be marked then, but not when initially loaded. Why?

  • Focus and blur in the control will cause it to be marked.
  • BUT, clicking ADD will too (which runs the same method that ran when it was loaded). Why does it work the 2nd time, but not when initially loaded?

    updateValidation : function ()  {
    this.$el.find('[placeholder]').each(function (index, ctrl) {  
        var $ctrl = $(ctrl);
        if( $ctrl.val() !== "" && (ctrl.checkValidity && !ctrl.checkValidity()) ) {
            // alert('Do validity check!');
            $ctrl.focus();
            $ctrl.blur();
        }
    });
    }
    

I see this in FF 17.0.5. The problem is worse in IE9, sometimes taking 2 or 3 clicks of ADD before the fields show in error. However, I get errors on some of the js files I've liked 'due to mime type mismatch'.


Solution

  • This has to do with the fact, that you are trying to reuse the .user-error class, which is a "shim" for the CSS4 :user-error and shouldn't be triggered from script. The user-error scripts are loaded after onload or as soon as a user seems to interact with an invalid from.

    From my point of view, you shouldn't use user-error and instead create your own class. You can simply check for validity using the ':invalid' selector:

    $(this)[ $(this).is(':invalid') ? 'addClass' : 'removeClass']('invalid-value');
    

    Simply write a function with similar code and bind them to events like change, input and so on and call it on start.

    In case you still want to use user-error, you could do the following, but I would not recommend:

    $.webshims.polyfill('forms');
    //force webshims to load form-validation module as soon as possible
    $.webshims.loader.loadList(['form-validation']);
    //wait until form-validation is loaded
    $.webshims.ready('DOM form-validation', function(){
        $('input:invalid')
            .filter(function(){
                return !!$(this).val();
            })
            .trigger('refreshvalidityui')
        ;
    });