【问题标题】:Can this jQuery validation be refactored?这个 jQuery 验证可以重构吗?
【发布时间】:2010-08-06 06:51:30
【问题描述】:

我正在使用 jQuery 进行一些简单的客户端验证。

var passedValidation = new Boolean(true);

// Required Field Validators.
if ($('#fbsignup input.firstName').val().trim() == '') {
    $('#fbsignup tr.firstName em').show();
    passedValidation = false;
}
if ($('#fbsignup input.lastName').val().trim() == '') {
    $('#fbsignup tr.lastName em').show();
    passedValidation = false;
}
if ($('#fbsignup input.email').val().trim() == '') {
    $('#fbsignup tr.email em').show();
    passedValidation = false;
}
if ($('#fbsignup input.password').val().trim() == '') {
    $('#fbsignup tr.password em').show();
    passedValidation = false;
}
if ($('#fbsignup input.screenName').val().trim() == '') {
    $('#fbsignup tr.screenName em').show();
    passedValidation = false;
}


if (passedValidation == true) {
    // All validation passed. Hide the modal signup dialog and post back to signup user.
    $('#fbcSignupModal').jqmHide();
    return true;
} else {
    return false;
}

基本上,我想确保所有字段都已填写。如果没有,则返回 false,否则返回 true。很简单。

这可以重构为一行吗? (也许通过对所有元素应用一个类?)。

关于答案的警告,我不想使用 jquery-validate 插件。我知道它很棒,但这并不是很难验证,我不想影响表单的其余部分(这是一个模式弹出窗口)。

那么,话虽这么说 - 有什么想法吗?

编辑

澄清一下,我确实需要知道哪个字段不需要填写,所以我可以在它旁边显示一个 *。

EDIT2

更新了原始代码以表明我需要显示必填字段标签,如果验证失败则返回 false。

EDIT3

好的,我已经重新考虑了我的解决方案,看起来我需要进行服务器调用以根据会员模式验证电子邮件。因此,我可能最终要么将字段包装在更新面板中,要么进行 Web 服务发布(并在 json 数组中返回错误)。不过,我会暂时搁置这个问题,然后选择得票最多的答案。

回答

所以我选择了@box9 答案的修改版本。我仍然需要对服务器进行 AJAX 调用以验证电子邮件(正如我上面的编辑所建议的那样),但这将确保我只有在填写所有字段时才这样做。

$('#fbsignup input.required').each(function (index) {
        if ($(this).val().trim() == '') {
            $(this).next('em').show();
            passedValidation = false;
        }
    });

我在必需的输入字段后面直接有一个 em 元素,所以我可以轻松使用.next([selector]) jQuery 选择器。

简单又好用。

感谢大家的回答。

【问题讨论】:

  • 重新编辑:这与“如果不是,则返回 false,否则返回 true。简单。”相矛盾。你需要彻底重新思考逻辑,当你的功能不完整时不要过多考虑优化代码长度。
  • @David - 授予。我将“编辑”我的“编辑”
  • JavaScript 不是 Java:var passedValidation = new Boolean(true); 并不比 var passedValidation = true; 好。事实上,这很危险——if (new Boolean(false)) return true; 将返回 true。
  • @Casey Hope - 同意。虽然我不是这样用的,所以没关系。

标签: javascript jquery html validation


【解决方案1】:

以下代码与您的代码完全相同:

var passedValidation = true;

$('#fbsignup input').each(function(index) {
    if ($(this).val().trim() == '') {
        $('#fbsignup tr').filter('.' + $(this).attr('class').split(' ').slice(0, 1)).find('em').show();
        passedValidation = false;
    }
});

if (passedValidation) $('#fbcSignupModal').jqmHide();

return passedValidation;

...除了一个警告:只有当“firstName”、“lastName”等类是您输入的类属性中的第一个类时,它才会起作用。这个限制,以及复杂的行$('#fbsignup tr').filter('.' + $(this).attr('class').split(' ').slice(0, 1)).find('em').show();,只存在因为我不知道你的 HTML 的结构。选择器可以更简洁(如果 HTML 结构已知,则使用 .sibling().children().parent() 等。

或者,包含输入的所有类名的数组:

var inputClasses = ['firstName', 'lastName', 'email', 'password', 'screenName'];

并遍历这些:

var passedValidation = true;

$.each(inputClasses, function(index, className) {
    if ($('#fbsignup').find('input.' + className).val().trim() == '') {
        $('#fbsignup').find('tr.' + className + ' em').show();
        passedValidation = false;
    }
});

if (passedValidation) $('#fbcSignupModal').jqmHide();

return passedValidation;

这样做的缺点是,如果您更改/添加输入,则必须手动更新数组。您最好的选择可能是使用 HTML 的已知结构修改我的第一个解决方案,甚至将类转换为 ID。

【讨论】:

    【解决方案2】:
    function validate() {
        var fields = ['firstName', 'lastName', 'email', 'password', 'screenName'];
        for(fieldIdx in fields) {
            if($('#fbsignup input.' + fields[fieldIdx]).val().trim()) == '' {
                $('#fbsignup input.' + fields[fieldIdx]).after("*");
                return false;
            }
        }
        return true;
    }

    这可以满足您的需求,但缺点是会丢失有关哪个字段验证失败的信息(例如,如果您想弹出特定于字段的消息)。 p>

    【讨论】:

    • 有趣,但不幸的是我想在未填写的字段上显示一个 *。猜猜这就是我们需要验证插件的原因。
    • 这将获取每个数组项的索引,即 0 而不是 'firstName'
    • @RPM1984 — 您的原始代码没有这样做(也没有设置为方便这样做)
    • @RPM1984:编辑后的响应中多余的jQuery行在失败字段后添加了*
    【解决方案3】:

    这样的东西应该适合你。

    var failedElements = $("#fbsignup input").filter(".firstname[value=''], .lastname[value=''], .email[value='']");
    

    这是一个例子:

    http://jsfiddle.net/zfQbz/

    编辑:我刚刚注意到您再次编辑了问题。因此,如果您想对每个失败的项目采取措施,只需使用 for 循环来迭代集合中的所有项目并为每个项目执行您需要的操作。

    【讨论】:

      【解决方案4】:

      如果您想检查 所有 字段是否已填写,只需执行以下操作:

      function validate() {
          ret = true;
          $('#fbsignup input').each(function(index) {
            if ($(this).val().trim()) == '') ret = false;
          });    
          return ret;
      }
      

      【讨论】:

      • 是的,JochenJung 是对的,each() 处理它。但是,return false 将不起作用,因为它只会从内部匿名函数返回,而不是 validate() 函数。
      【解决方案5】:

      我推荐你使用这个jquery validation plugin,它好用又强大..

      【讨论】:

      • -1 发帖人明确表示不想使用jquery验证插件。我不认为现在他会因为你这么说而突然改变主意。
      • @spion 你从我嘴里说出来的话。为什么哦为什么人们忽略警告?就像他们阅读了主题并开始繁荣,这将做到,甚至不看问题的实际细节。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多