禁用提交按钮直到所有字段都有值

78

我想在所有字段都有值之前禁用我的提交按钮。我该怎么做?

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

3
攻击方面怎么办?使用启用和禁用属性并不安全...只需在浏览器中单击F12,在HTML中找到提交按钮,然后删除disable!这样即使输入为空也会提交表单。 - Elnaz
3
显然,使用它作为安全性手段没有用处,任何用户提供的数据都必须被视为潜在攻击。但在许多情况下,这是良好的用户体验。 - reducing activity
@Elnaz 我希望你能在服务器端进行输入验证,这并不是一种攻击手段,只是一种防止过早提交表单的方法。 - undefined
12个回答

106

看看这个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
        }
    });
})()

这种方法的好处在于,无论表单中有多少个输入字段,只要有一个为空,它就会始终保持按钮禁用状态。它还检查了 .keyup() 事件中的空值,我认为这使得它更加方便易用。


1
那么,我如何使用单选按钮来实现它?我有一个多选表单。 - Azzurrio
12
如果有人关闭 JavaScript,按钮将无法使用,因此在脚本执行开始时,应该通过 JavaScript 将其设置为禁用状态,以便保证可用性。 - Jacek Kowalewski
3
使用“form input”而非“form > input”还会选择子元素(例如div)中的输入框。 - Fernando Correia
5
请使用$("form input").on("keyup change",function () { })而不是仅使用keyup,因为这样可以捕获自动完成的值... - ᴍᴀᴛᴛ ʙᴀᴋᴇʀ
显示剩余9条评论

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上运行你的代码, 很好用 :)


4
如果您清空了一个输入框,提交按钮仍然保持可用状态。在if语句后面,我添加了else{$('#register').prop("disabled", true);}。现在,如果您清空了其中一个输入框,注册按钮会被再次禁用。 - Pathros

9

所有解决方案都应该使用“.change”而不是“.keyup”,否则当有人仅选择存储在cookie中的任何文本字段的数据时,提交按钮将不会被禁用。


5
这是一条评论而不是答案。 - Mark W

8
所有变量都被缓存,这样循环和键盘弹起事件就不必每次运行时创建jQuery对象。
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');
});

请查看工作示例,网址为http://jsfiddle.net/DKNhx/3/


如果浏览器缓存了这些值并预填充了字段,这仍然有效吗?还是需要一个keyup事件? - riddle_me_this

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);
})

我认为这是最干净的。 - Oneezy

2
我在这里对所选答案进行了重构并对其进行了改进。 所选答案仅适用于每个页面有一个表单的情况。 我解决了同一页上多个表单的问题(在我的情况下,我有2个模态框在同一页上),我的解决方案仅检查必填字段上的值。 如果JavaScript被禁用,我的解决方案会优雅地降级,并包括一个炫酷的CSS按钮淡出过渡效果。
请查看工作中的JS小样例: https://jsfiddle.net/bno08c44/4/
$(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>

1

本代码基于rsplak的回答。它使用jQuery的新.on()而不是已弃用的.bind()。除了输入外,它还适用于选择和其他html元素。如果其中一个字段再次变为空,它还将禁用提交按钮。

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;
}

演示:JSFiddle


1
这很有效,因为所有输入都必须满足非空条件。
$(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);
        }
     });
 });

在我的情况下,当我填写所有字段后,它可以正常工作,但是当我清空其中一个字段时,#submit 仍然保持 attr('disabled', false)。我认为正确的行为应该是更改为 attr('disabled', true) 状态。 - GalanopD

1

如果你正在使用原生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>


0

挖坑中... 我喜欢一种不同的方法:

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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接