10

Was wondering if anyone could point me in the right direction with the following piece of jquery. I want to disable the submit button until my input fields have been filled in.

I have come up with this

$(document).ready(function (){
 if ($('#inputName, #inputEmail, #inputTel').val().length > 0) {
  $("input[type=submit]").attr("disabled", "false");
 }
 else {
  $("input[type=submit]").attr("disabled", "true");
 }
});

but the button is permanently disabled, Even after filling in all the text input fields

Still learning Jquery and haven't used it for a while.. So any pointers appreciated

Thanks

Richlewis
  • 15,070
  • 37
  • 122
  • 283

7 Answers7

33

Your event binding is only on document ready.

So there is no listener when you change something.

Do this instead :

$(document).ready(function (){
    validate();
    $('#inputName, #inputEmail, #inputTel').change(validate);
});

function validate(){
    if ($('#inputName').val().length   >   0   &&
        $('#inputEmail').val().length  >   0   &&
        $('#inputTel').val().length    >   0) {
        $("input[type=submit]").prop("disabled", false);
    }
    else {
        $("input[type=submit]").prop("disabled", true);
    }
}
Karl-André Gagnon
  • 33,662
  • 5
  • 50
  • 75
  • 2
    seems better imo but you should use .prop() not .attr() for browser constitency – A. Wolff May 26 '13 at 17:27
  • 2
    I know this is an old answer but this was helpful to me recently. I would like to add a suggestion. I would add (assuming that `inputTel` is the id of the last field before the `submit` button): `$('#inputTel').keypress(function() {validate();});` to the line after `$('#inputName, #inputEmail, #inputTel').change(validate);`. I think it helps with UX as it runs a the `validate()` function again whenever the user is in the "last" field and types, where as as it is the user might type something in the final field before submission and may be thrown off by the still disabled submit button. – salad_bar_breath Nov 28 '15 at 22:08
  • 1
    @Douglas_Symb It is indeed a valid UX point. But I would not only put it on the last input. If an error occur (one input not filled) the keypress would be useful there as well. Instead, on keypress, I would add a debounce function that will trigger validate. So this would be good for UX and performance. – Karl-André Gagnon Nov 30 '15 at 13:57
  • I do like the idea of a debounce better @Karl-AndréGagnon thanks for the feedback! – salad_bar_breath Nov 30 '15 at 16:05
  • For those using `keypress`, I would add that keypress doesn't recognize backspace and `keydown` executes for the 'previous state' (i.e before the key press), so I found `keyup` to be apt for my usecase – Anupam Sep 15 '17 at 06:34
5

Your current code is fine, but doesn't respond to user events, which is where you're tripping.

$('#inputName, #inputEmail, #inputTel').keyup(function(){
    if($(this).val().length > 0){
        $("input[type=submit]").prop("disabled", false);
    }else{
        $("input[type=submit]").prop("disabled", true);
    }
});

Edit actually, this won't work. because one of those elements will caus ethe submit button to become enabled, regardless of the other ones. I'll hotfix momentarily.

Edit Here's the rough draft fix, it could probably be prettier, but will definitely be a good starting point.

var toValidate = $('#inputName, #inputEmail, #inputTel'),
    valid = false;
toValidate.keyup(function () {
    if ($(this).val().length > 0) {
        $(this).data('valid', true);
    } else {
        $(this).data('valid', false);
    }
    toValidate.each(function () {
        if ($(this).data('valid') == true) {
            valid = true;
        } else {
            valid = false;
        }
    });
    if (valid === true) {
        $('input[type=submit]').prop('disabled', false);
    }else{
        $('input[type=submit]').prop('disabled', true);        
    }
});

And here's your jsFiddle illustrating this method

Ohgodwhy
  • 49,779
  • 11
  • 80
  • 110
  • @Richlewis updated to be more portable and address your issue exactly. – Ohgodwhy May 26 '13 at 17:27
  • jsfiddle not going to an example? thanks you for explaining, though still not working, maybe jsfiddle will help, thanks – Richlewis May 26 '13 at 17:29
  • do i need to use jquery 1.9.1 to make this work, im using 1.7.2 at the moment, not a problem if i have to – Richlewis May 26 '13 at 17:31
  • Ya, you should. At least don't wait to be in trouble in the future to upgrade your jquery version – A. Wolff May 26 '13 at 17:32
  • @Richlewis you don't have to, as prop was added in 1.6, but the better question is, why wouldn't you use the latest stable release? Software receive updates for several reasons. – Ohgodwhy May 26 '13 at 17:32
1

change the property of a button and not the attribute...use prop() instead of attr()

$(document).ready(function (){
  if ($('#inputName, #inputEmail, #inputTel').val().length > 0) {
    $("input[type=submit]").prop("disabled", false);
  }
  else {
    $("input[type=submit]").prop("disabled", true);
  }
});

and i assume this make no sense since you don't have any event binding on it.. this will only check if the input has value in document.ready or not.. however event binding or not that depends on you.. but for these particular reason prop() was introduced in later version of jquery...

updated

after seeing the comments below,

$(function(){
  validate();
  $('input[type="text"]').keyup(validate); //you can use your multiple id selector instead of the attribute selector that i am using
});

function validate() {
  var inputvalue = $('input[type="text"]').filter(function (n) {
     return this.value.length > 0;
  })

  if (inputvalue.length == $('input[type="text"]').length) {
     $("input[type=submit]").prop("disabled", false);
  } else {
     $("input[type=submit]").prop("disabled", true);
  }
}

this should work for any number of inputs with type as text (no need to change the javascript/jquery codes at all)... here is the fiddle

bipen
  • 36,319
  • 9
  • 49
  • 62
  • i didnt downvote...but as others have explained i wasnt binding to a users action – Richlewis May 26 '13 at 17:19
  • 1
    @Rohit Agrawal ya, for sure but at least is using .prop() not .attr() as your answer :) – A. Wolff May 26 '13 at 17:20
  • 2
    @RohitAgrawal ... FYI `Use your downvotes whenever you encounter an egregiously sloppy, no-effort-expended post, or an answer that is clearly and perhaps dangerously incorrect.` – bipen May 26 '13 at 17:24
  • Also, this doesn't address the issue. This should have been a comment more than anything. You never detect any user-events, so how can you respond to changes? -1 from me. – Ohgodwhy May 26 '13 at 17:28
  • @bipen that was incorrect totally prop and attr doesn't make any impact here on the result but the event binding makes – Rohit Agrawal May 26 '13 at 17:54
  • @RohitAgrawal have you read the jquery docs earlier ?? if yes then i guess you should see this too...`The .prop() method should be used to set disabled and checked instead of the .attr() method.` if not then here is the link to the doc http://api.jquery.com/prop/ ...and since you guys insisted for answer (correct i assume)..so here you go i updated my answer – bipen May 26 '13 at 18:03
0

you have to run the if command again to enable that can be done on change event of input

function updateSubmit(){
  if ($('#inputName').val().length+$('#inputEmail').val().length+$('#inputTel').val().length > 2) {
     $("input[type=submit]").prop("disabled", false);
   }
   else {
     $("input[type=submit]").prop("disabled", true);
   }
}

$(document).ready(function (){
  updateSubmit();
  $('#inputName, #inputEmail, #inputTel').on('change',function(){
   updateSubmit();
  });
});
Rohit Agrawal
  • 5,372
  • 5
  • 19
  • 30
0

I've been trying to follow this thread to implement this with a custom stripe form.

This is my code:

$(document).ready(function (){
  validate();
  $('#EMAIL, #FNAME, #LNAME, #card-element').change(validate);
});

function validate(){
    if ($('#EMAIL').val().length   >   0   &&
        $('#FNAME').val().length  >   0   &&
        $('#LNAME').val().length    >   0  &&
        $('#card-element').hasClass('StripeElement--complete')
        ){
        $("button[type=button]").prop("disabled", false);
    }
    else {
        $("button[type=button]").prop("disabled", true);
    }
}

Everything worked fine until I added the .hasClass condition. The button just stays disabled!

Adrita Sharma
  • 21,581
  • 10
  • 69
  • 79
Timo
  • 1
0

This code will check textbox, email and checkbox input types, works fine at my end and also if input fields are hidden, will check only visible fields.

  var register_disable = false;
  jQuery("#SUBMIT_BUTTON-ID").prop('disabled', register_disable);
  jQuery("input[type!='submit']").bind('keyup change', function () {
    jQuery("input[type='text'], input[type='email']").not(':input:hidden').each(function () {
      if (jQuery(this).val().trim() == "" || !$("input[type='checkbox']").is(':checked')) {
        register_disable = true;
      }
    });
    jQuery("#SUBMIT_BUTTON-ID").prop('disabled', register_disable);
    register_disable = false;
  });
-1

Use the form onsubmit. Nice and clean. You don't have to worry about the change and keypress events firing. Don't have to worry about keyup and focus issues.

http://www.w3schools.com/jsref/event_form_onsubmit.asp

<form action="formpost.php" method="POST" onsubmit="return validateCreditCardForm()">
   ...
</form>

function validateCreditCardForm(){
    var result = false;
    if (($('#billing-cc-exp').val().length > 0) &&
        ($('#billing-cvv').val().length  > 0) &&
        ($('#billing-cc-number').val().length > 0)) {
            result = true;
    }
    return result;
}
jecz
  • 21
  • 1
  • 7