37

I have a form that detects if all the text-fields are valid on each keyup() and focus(); if they're all valid, it will enable the submit button for the user to press. However, if the user fills in one of the text inputs with a browsers autocomplete feature, it prevents the submit button from being enabled.

Is there a way to detect if any of the input has changed regardless of how it's been changed, using jQuery?

Ryan
  • 21,437
  • 7
  • 25
  • 28

9 Answers9

27

You could try using on input to detect text-based changes (except keys like ctrl and shift) in <input>'s.

For example:

$(input).on('input', function() { 
    console.log($(this).val()); 
});
Zabavsky
  • 13,340
  • 8
  • 54
  • 79
cheshireoctopus
  • 1,670
  • 1
  • 22
  • 31
18

The jQuery change event will only fire on blur. The keyup event will fire as you type. Neither fire on clicking an auto-completion option. I am also searching for a way to detect this, but I'm currently going with

$(selector).bind("change keyup",function(){
    //Do something, probably with $(this).val()
});

But it doesn't quite solve the problem...

Spycho
  • 7,698
  • 3
  • 34
  • 55
  • 1
    I unfortunately had to downvote this! I had 90% good experiences with `change keyup` but keyup does not attach to autofill in chrome-cases and `change` attach to autofill **only if the focus get lost!** Chrome sometimes keep the textcursor inside the input-field after autofill and did not trigger the change-event! Maybe a chrome-only problem... – Grim Jul 17 '16 at 10:35
  • @PeterRader: Yes, I thought I'd made that clear in the answer. – Spycho Aug 08 '16 at 13:07
  • @Spycho If you have a 3rd field after `username` and `password` then `change` is called for `username` and `password` every time! This is a workaround reaching 100%. – Grim Aug 08 '16 at 18:23
  • @PeterRader: Excellent. Post that as an answer? – Spycho Aug 08 '16 at 22:13
14

Myself I used

$(selector).on("change keyup blur input", function() {});

which did the trick in Chrome. input is what made it work for autocomplete.

avoliva
  • 3,181
  • 5
  • 23
  • 37
2

My issue was detecting auto-fill (via a plugin like lastpass or 1password) as well as the issue described above.

The solution that worked for me was:

$(function(){    
    function validate(){
        if($('#email').val() !== '' && $('#password').val() !== '')
            $('#submit').prop('disabled', false);
        else
            $('#submit').prop('disabled', true);
    }

    // Validate after user input
    $('#email, #password').on('keyup change', validate);

    // Validate on mouse enter of body and login form
    // to catch auto-fills from roboform/1password etc...
    $('body, #loginform').on('mouseenter', validate);

    // Validate onload incase of autocomplete/autofill
    validate();
});

See demo in JSFiddle.

Justin
  • 26,443
  • 16
  • 111
  • 128
  • 1
    i know this is old but can't you do ```$("#email, "#password").on("keyup change", validate);``` instead? – eytanfb Aug 26 '14 at 17:37
  • As an FYI - mouseenter is triggered it appears on hover, and while this may work for a password manager, it does not appear ideal because it triggers validation on hover and the field is invalid (turns red). This is nitpicky, but I'd prefer to not give negative feedback on hover events. Still looking for the unicorn event to detect a lastpass fill_in. – kross Mar 17 '15 at 15:08
0

The answer has been given in this question. It doesn't use jQuery, but it works for Autocomplete:

Use js onpropertychange event.

Community
  • 1
  • 1
Yehuda Shapira
  • 8,460
  • 5
  • 44
  • 66
0

I have a decent solution after having the same problem. Set keyup as normal to our form fields, then mouseover to the surrounding div. So once you click the autocomplete option, you mouse will be over the top of the div:

$("#emailaddress").bind("keyup", function() {
    displayFullSubcribeForm();
});

$(".center_left_box").bind("mouseover", function() {
    displayFullSubcribeForm();
});
0

I wanted a very good user experience on a field where it would not be invalid (turn red in my case) as long as the user was reasonably active e.g. still filling out the field.

To do this for normal input, I was able to hook up to keyup with a debounce function, while blur is connected for immediate validation. While it appears that keyup is triggered by lastpass, since I have debounced it, there was a delay in validation. Thanks to @peter-ajtai I tried to add the change event and it indeed catches last pass and leaves the other niceties alone.

Coffeescript example:

@fieldExp .keyup($.debounce(@_onExpChange, 3000)) .blur(@_onExpChange) .change(@_onExpChange)

This worked well and lastpass form fill triggers immediate validation.

kross
  • 3,627
  • 2
  • 32
  • 60
0

You could use the jQuery .change() function.

After the page initially loads, you can validate the entire form, just to check that it is in fact not filled in. After that you can use .change() to check if things have changed on the form, and if anything has changed, validate the form again.

$(document).ready(function() {
   // validate form once, just to be sure (if valid, activate submit button)
});
...
<form>
  <input class="target" type="text" value="Field 1" />
  <select class="target">
    <option value="option1" selected="selected">Option 1</option>
    <option value="option2">Option 2</option>
  </select>
</form>
<script type="text/javascript">     
    $('.target').change(function() {
        alert('Something changed');
        // Try validating form again (if valid, activate submit button)
    });
</script>

Plan B

Another option is to always have the submit button clickable, but use .submit() to bind it to the form validator. Then if the form IS valid, carry on. If the form IS NOT valid use .preventDefault() to stop the submission of the form..... and you'd display a warning message too, indicating the missing fields.

Peter Ajtai
  • 56,972
  • 13
  • 121
  • 140
-2

this is the ultimate solution, guaranteed to work

$(document).bind('mouseover', function(){
        liveValidate();
    });