Event Listener valid for HTML5 forms

26,042

Solution 1

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/

Solution 2

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.

Solution 3

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).

Solution 4

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');
    }
});
Share:
26,042
Óscar
Author by

Óscar

Updated on July 09, 2022

Comments

  • Óscar
    Óscar almost 2 years
    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

  • Óscar
    Óscar over 12 years
    Mmmm, yeah, but that doesn't solve my problem. If the user enters invalid input, then it gets the "invalid" class, but let's say they don't submit it. Instead, they correct the field. Thus, the form is now valid (input:invalid selector isn't applied anymore). So it's not a matter of setting or removing the class, but rather, of knowing when the event is fired...
  • Óscar
    Óscar over 12 years
    But I would have to add it myself then... So, isn't there an event that is fired when the form becomes valid? And furthermore, of an input getting invalid?
  • mAu
    mAu over 12 years
    You mean the validation logic? Or the event binding? Because the latter you would have to do with a valid or invalid event too. Honestly, I do not get what you want to achieve ... If you want a custom valid or invalid event, try this: jsfiddle.net/mAu888/vrZa3/3 It checks in a given interval, if the form contains any :invalid elements. If so, it triggers a custom invalid event on the form, to which you may register your functions. If the form becomes valid, it triggers a valid event. Be sure to change #foo to the id of your form.
  • alexander farkas
    alexander farkas over 12 years
    The code here is wrong. The submit event should not be triggered, if the form has invalid form fields. The keyup event is not the right event for this purpose. The input (or much better, but not so good supported, the textinput) event is the right event.
  • Rob W
    Rob W over 12 years
    @alexanderfarkas I have moved the comment and slightly updated the code, see jsfiddle.net/ceArQ/10. What do you imply with your comment?
  • Óscar
    Óscar over 12 years
    Yeap, I tried this approach but it didn't quite meet my needs, because the inputs' parents must also change and there's no parent selector on CSS :(
  • Óscar
    Óscar over 12 years
    No, I mean the event does not exist like "click", or "change", for example, so in order to simulate a document.addEventListener('invalid') listener I would have to do what you did there, checking on a given interval. Sorry if I didn't explain myself properly and thanks again! :D
  • Óscar
    Óscar over 12 years
    Yeap, this definitely seems the way to go. Thank you very much. I would've thought there's a $("#inputBlah").bind("invalid") that gets fired only when that input gets invalid...
  • alexander farkas
    alexander farkas over 12 years
    Actually your code is much worse now. The checkValditiy method already returns true/false and additionally triggers an invalid event (which is already handeld). So you would not have to check the validityState object, keyup event is not the right event. The user can paste content with mouse into a field etc. I made a fiddle for you: jsfiddle.net/trixta/SMaNM
  • thdoan
    thdoan over 9 years
    @Raynos A > B would select B, not A.