78

I want to disable my submit button until all the fields have values.. how can I do that?

<html>
    <head>
        <title></title>
        <style type="text/css">
        </style>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
        <script type="text/javascript">
        $(document).ready(function() {
            $('#register').attr("disabled", true);
        });
        </script>
    </head>
    <body>
        <form>
        Username<br />
        <input type="text" id="user_input" name="username" /><br />
        Password<br />
        <input type="text" id="pass_input" name="password" /><br />
        Confirm Password<br />
        <input type="text" id="v_pass_input" name="v_password" /><br />
        Email<br />
        <input type="text" id="email" name="email" /><br />     
        <input type="submit" id="register" value="Register" />
        </form>
        <div id="test">
        </div>
    </body>
</html>
AndrewFerrara
  • 2,383
  • 8
  • 30
  • 45
  • 3
    What about attacks? using enable and disable attributes are not secure....Just click f12 in your browser, find the submit button in the html, and then remove the disabled ! It will submit the form even if the inputs are empty. – Elnaz Sep 26 '16 at 06:45
  • 3
    @Elnaz Obviously, it is not useful as a security and any user-supplied data must be treated as a potential attack. But in many cases it is a good UX. – reducing activity Apr 28 '19 at 07:14

12 Answers12

106

Check out this jsfiddle.

HTML

// note the change... I set the disabled property right away
<input type="submit" id="register" value="Register" disabled="disabled" />

JavaScript

(function() {
    $('form > input').keyup(function() {

        var empty = false;
        $('form > input').each(function() {
            if ($(this).val() == '') {
                empty = true;
            }
        });

        if (empty) {
            $('#register').attr('disabled', 'disabled'); // updated according to http://stackoverflow.com/questions/7637790/how-to-remove-disabled-attribute-with-jquery-ie
        } else {
            $('#register').removeAttr('disabled'); // updated according to http://stackoverflow.com/questions/7637790/how-to-remove-disabled-attribute-with-jquery-ie
        }
    });
})()

The nice thing about this is that it doesn't matter how many input fields you have in your form, it will always keep the button disabled if there is at least 1 that is empty. It also checks emptiness on the .keyup() which I think makes it more convenient for usability.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Hristo
  • 45,559
  • 65
  • 163
  • 230
  • 1
    so How Can I do it with radio buttons? I've a multiple choice form – Azzurrio Jul 04 '12 at 09:22
  • 1
    According to http://stackoverflow.com/questions/7637790/how-to-remove-disabled-attribute-with-jquery-ie it may be better to set the disabled attribute to 'disabled' and remove the disabled attribute using .removeAttr('disabled') instead of setting it to be false. – tmarthal Aug 31 '12 at 23:15
  • You might have a problem with above script untill you define empty variable before using it at the top of the script. so put this after (function() { ---> var empty; – Sahil Sep 27 '13 at 15:45
  • 12
    HUGE HOLE HERE!!! If someone turns off the javascript, button is disabled. It should be set to disabled also via javascript at the beginning of the script execution. – Jacek Kowalewski Aug 18 '14 at 05:43
  • The keyup event won't fire if form element is type number. Better use change event instead (or both). – rzb Jul 13 '15 at 14:33
  • 3
    Using `form input` instead of `form > input` also selects inputs inside child elements (e.g. `div`s). – Fernando Correia Feb 10 '16 at 17:05
  • @FernandoCorreia Your comment really helps!!! This piece of JS cannot select child elements inside divs inside the form! – BenBen Aug 22 '16 at 17:36
  • @Hristo. Hi, I am Your code is very helpful for my project. but in my project i have select option and radio also there. can you help me – jvk Mar 12 '17 at 04:26
  • I would use `$('input[type="submit"]')` to target the submit button not the ID, future proofs it a tad. – ᴍᴀᴛᴛ ʙᴀᴋᴇʀ Mar 28 '17 at 10:17
  • 5
    Also use `$("form input").on("keyup change",function () { }` instead of just `keyup` as this will catch autocomplete values too... – ᴍᴀᴛᴛ ʙᴀᴋᴇʀ Mar 28 '17 at 10:19
  • What about radio or even checkboxes ? Does not work for them. – Delphine Jan 26 '18 at 17:08
  • using `$("#formID > input")` not working for me. It works with: `$("#formID input")` – proofzy Dec 13 '19 at 20:23
  • This isn't JS. Please provide a Vanila JS solution if possible also – KontYentE May 10 '21 at 13:00
  • @proofzy I discovered if I have a

    tag between the submit button and the text field then it doesn't work unless I remove the '>' symbol like you suggest. If I replace

    with
     
    then it works with the '>'. I have no idea why.

    – Gregory Grant Jan 14 '22 at 08:24
26
$('#user_input, #pass_input, #v_pass_input, #email').bind('keyup', function() {
    if(allFilled()) $('#register').removeAttr('disabled');
});

function allFilled() {
    var filled = true;
    $('body input').each(function() {
        if($(this).val() == '') filled = false;
    });
    return filled;
}

JSFiddle with your code, works :)

  • 4
    If you empty one input, the submit button keeps enabled. After the `if` statement I added `else{$('#register').prop("disabled", true);}` So now, if you empty one of the inputs, the register button is disabled again. – Pathros Aug 29 '16 at 17:56
9

For all solutions instead of ".keyup" ".change" should be used or else the submit button wont be disabled when someone just selects data stored in cookies for any of the text fields.

Sashank
  • 101
  • 1
  • 4
8

All variables are cached so the loop and keyup event doesn't have to create a jQuery object everytime it runs.

var $input = $('input:text'),
    $register = $('#register');    
$register.attr('disabled', true);

$input.keyup(function() {
    var trigger = false;
    $input.each(function() {
        if (!$(this).val()) {
            trigger = true;
        }
    });
    trigger ? $register.attr('disabled', true) : $register.removeAttr('disabled');
});

Check working example at http://jsfiddle.net/DKNhx/3/

Hussein
  • 42,480
  • 25
  • 113
  • 143
5

DEMO: http://jsfiddle.net/kF2uK/2/

function buttonState(){
    $("input").each(function(){
        $('#register').attr('disabled', 'disabled');
        if($(this).val() == "" ) return false;
        $('#register').attr('disabled', '');
    })
}

$(function(){
    $('#register').attr('disabled', 'disabled');
    $('input').change(buttonState);
})
fl00r
  • 82,987
  • 33
  • 217
  • 237
2

I refactored the chosen answer here and improved on it. The chosen answer only works assuming you have one form per page. I solved this for multiple forms on same page (in my case I have 2 modals on same page) and my solution only checks for values on required fields. My solution gracefully degrades if JavaScript is disabled and includes a slick CSS button fade transition.

See working JS fiddle example: https://jsfiddle.net/bno08c44/4/

JS

$(function(){
 function submitState(el) {

    var $form = $(el),
        $requiredInputs = $form.find('input:required'),
        $submit = $form.find('input[type="submit"]');

    $submit.attr('disabled', 'disabled');

    $requiredInputs.keyup(function () {

      $form.data('empty', 'false');

      $requiredInputs.each(function() {
        if ($(this).val() === '') {
          $form.data('empty', 'true');
        }
      });

      if ($form.data('empty') === 'true') {
        $submit.attr('disabled', 'disabled').attr('title', 'fill in all required fields');
      } else {
        $submit.removeAttr('disabled').attr('title', 'click to submit');
      }
    });
  }

  // apply to each form element individually
  submitState('#sign_up_user');
  submitState('#login_user');
});

CSS

input[type="submit"] {
  background: #5cb85c;
  color: #fff;
  transition: background 600ms;
  cursor: pointer;
}

input[type="submit"]:disabled {
  background: #555;
  cursor: not-allowed;
}

HTML

<h4>Sign Up</h4>
<form id="sign_up_user" data-empty="" action="#" method="post">
 <input type="email" name="email" placeholder="Email" required>
 <input type="password" name="password" placeholder="Password" required>
 <input type="password" name="password_confirmation" placeholder="Password Confirmation" required>
 <input type="hidden" name="secret" value="secret">
 <input type="submit" value="signup">
</form>

<h4>Login</h4>
<form id="login_user" data-empty="" action="#" method="post">
 <input type="email" name="email" placeholder="Email" required>
 <input type="password" name="password" placeholder="Password" required>
 <input type="checkbox" name="remember" value="1"> remember me
 <input type="submit" value="signup">
</form>
J Grover
  • 1,029
  • 1
  • 9
  • 14
1

Built upon rsplak's answer. It uses jQuery's newer .on() instead of the deprecated .bind(). In addition to input, it will also work for select and other html elements. It will also disable the submit button if one of the fields becomes blank again.

var fields = "#user_input, #pass_input, #v_pass_input, #email";

$(fields).on('change', function() {
    if (allFilled()) {
        $('#register').removeAttr('disabled');
    } else {
        $('#register').attr('disabled', 'disabled');
    }
});

function allFilled() {
    var filled = true;
    $(fields).each(function() {
        if ($(this).val() == '') {
            filled = false;
        }
    });
    return filled;
}

Demo: JSFiddle

CSquared
  • 155
  • 3
  • 11
1

This works well since all the inputs have to meet the condition of not null.

$(function () {
    $('#submits').attr('disabled', true);
    $('#input_5').change(function () {
        if ($('#input_1').val() != '' && $('#input_2').val() != '' && $('#input_3').val() != '' && $('#input_4').val() != '' && $('#input_5').val() != '') {
            $('#submit').attr('disabled', false);
        } else {
            $('#submit').attr('disabled', true);
        }
     });
 });
  • In my case it works ok after filling in all fields but when I empty one of the fields, the #submit remains `attr('disabled', false)`. I believe the correct behaviour would be to change to `attr('disabled', true)` status. – GalanopD Feb 18 '22 at 06:02
0

Grave digging... I like a different approach:

elem = $('form')
elem.on('keyup','input', checkStatus)
elem.on('change', 'select', checkStatus)

checkStatus = (e) =>
  elems = $('form').find('input:enabled').not('input[type=hidden]').map(-> $(this).val())
  filled = $.grep(elems, (n) -> n)
  bool = elems.size() != $(filled).size()
  $('input:submit').attr('disabled', bool)
Dudo
  • 4,002
  • 8
  • 32
  • 57
0

If you happen to be using vanilla JavaScript...

let fields = document.querySelectorAll('form > input')
let submitButton = document.querySelector('form > button')

fields = Array.from(fields) // Turn fields into an Array to access the ".every" method.

fields.forEach(field => {
  field.addEventListener('keyup', () => {
    submitButton.disabled = !fields.every(field => field.value)
  })
})
<form>
  <input type="text">
  <input type="text">
  <button type="submit" disabled>Submit</button>
</form>
Zack Plauché
  • 3,307
  • 4
  • 18
  • 34
0

To get all inputs that are not hidden and not directly under the form (inside child elements like divs)

    (function() {
    $('form :input:not(:hidden)').keyup(function() {

        var empty = false;
        $('form :input:not(:hidden)').each(function() {
            if ($(this).val() == '') {
                empty = true;
            }
        });

        if (empty) {
            $('#register').attr('disabled', 'disabled'); // updated according to http://stackoverflow.com/questions/7637790/how-to-remove-disabled-attribute-with-jquery-ie
        } else {
            $('#register').removeAttr('disabled'); // updated according to http://stackoverflow.com/questions/7637790/how-to-remove-disabled-attribute-with-jquery-ie
        }
    });
})()
Karim Samir
  • 1,470
  • 17
  • 17
0

This helps to check the field time by time, whenever the input field become null it detect and disable the button again

function validate() {
  var valid = true;
  valid = checkEmpty($("#user_input")) && checkEmpty($("#pass_input")) && checkEmpty($("#v_pass_input")) && checkEmpty($("#email"));

  $("#register").attr("disabled", true);
  if (valid) {
    $("#register").attr("disabled", false);
  }
}

function checkEmpty(obj) {
  var name = $(obj).attr("name");
  $("." + name + "-validation").html("");
  $(obj).css("border", "");
  if ($(obj).val() == "") {
    $(obj).css("border", "#FF0000 1px solid");
    $("." + name + "-validation").html("Required");
    return false;
  }

  return true;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  Username<br />
  <input type="text" id="user_input" name="username" onkeyup="validate()" /><br />
  Password
  <br />
  <input type="text" id="pass_input" name="password" onkeyup="validate()" /><br />
  Confirm Password<br />
  <input type="text" id="v_pass_input" name="v_password" onkeyup="validate()" /><br />
  Email<br />
  <input type="text" id="email" name="email" onkeyup="validate()" /><br />
  <input type="submit" id="register" value="Register" disabled/>
</form>
Tyler2P
  • 2,324
  • 26
  • 22
  • 31