Óscar
Óscar

Reputation: 351

Event Listener valid for HTML5 forms

  1. New on HTML5 there's an "invalid" event, to which you can add a listener:

    document.addEventListener('invalid', function(e){
       var element = $(e.target);
       element.addClass("invalid");
       element.parent().addClass("invalid");
    }, true);
    

    Please note, this event just works when submitting the form... If I style the input input:invalid { background: red }, the style is applied when the user starts typing and his input is not valid. Is that event only fired on submit? I tried adding the listener to the inputs themselves instead of the document and it didn't work.

  2. I add a listener in order to apply a style to the input's parent... Now, when the user corrects it, it's valid again... I know there's not a "valid" event, so, how can I accomplish it?


Ok, so here's a fiddle --> http://jsfiddle.net/Osoascam/ceArQ/7/ The invalid listener seems to be only fired on submit... I just wanted to know whether there's a way to add a handler just like there is for focus. See that if you type a

Thanks in advance,

Óscar

Upvotes: 23

Views: 34003

Answers (4)

Rob W
Rob W

Reputation: 349042

Since these classes are always added when a form is submit, remove the class prior validating:

$('#myForm').submit(function(){
    $('.invalid', this).removeClass('invalid'); // Remove all invalid classes
    $(this).removeClass('invalid');             // If the parent = form.
    // Normal validation procedure.
});

Expected result:

  1. User initiates submit
  2. onsubmit is triggered > All invalid class names within the form are removed.
  3. The invalid events are triggered, and the invalid classes are added when necessary

Update

Added an extra block to your fiddle, see updated fiddle: http://jsfiddle.net/ceArQ/10/. I have implemented the checkValidity() method and the validity.valid property. Now, the classes are automatically added when the input is invalid.

document.addEventListener('keyup', function(e){
    var input = e.target;
    if (!$.nodeName(input, 'input')) return;
    input.checkValidity();
    var element = $(input).parent();
    if(input.validity.valid) {
        element.removeClass('invalid');
        element.parent().removeClass('invalid');
    } else { //Remove the lines below if you don't want to automatically add
             // classes when they're invalid.
        element.addClass('invalid');
        element.parent().removeClass('invalid');
    }
});

On key-up, the validity of an input element is checked. If it's valid, the invalid class is removed from its parent.

Upvotes: 4

alexander farkas
alexander farkas

Reputation: 14134

You should use the :invalid pseudo selector and the input or the change event, to solve your problem.

$(document).bind('change', function(e){
    if( $(e.target).is(':invalid') ){
        $(e.target).parent().addClass('invalid');
    } else {
        $(e.target).parent().removeClass('invalid');
    }
});

Here is a simple fiddle http://jsfiddle.net/trixta/YndYx/.

If you want to remove the error class as soon as possible you should add the error class on change and remove it on the input event (Note: input event is much better than here suggested keyup, simply because it also is triggered on paste etc., but it only works with input elements, not textarea.)

And here is a fiddle using a mixture of input and change event: http://jsfiddle.net/trixta/jkQEX/

And if you want to have this cross browser you can simply use webshims lib to polyfill. Here is a x-browser example: http://jsfiddle.net/trixta/RN8PA/

Upvotes: 20

Raynos
Raynos

Reputation: 169401

Have you tried using :valid to give an indicator as to whether a field is valid. and having forms that are invalid just keep their default styling.

Then calling form.checkValidity() in the submit handler? (The browser should then tell the end-user which form element is not valid).

Upvotes: 1

mAu
mAu

Reputation: 2018

You could bind your validation logic to the focus and blur events, or to be even more responsive, to the keyup event.

$('input').keyup(function() {
    if(isValid(this)) {
        $(this).removeClass('invalid').parent().removeClass('invalid');
        $(this).addClass('valid').parent().addClass('invalid');
    }
    else {
        $(this).removeClass('valid').parent().removeClass('valid');
        $(this).addClass('invalid').parent().addClass('invalid');
    }
});

Upvotes: 1

Related Questions