【问题标题】:jQueryValidate - check if a control is required without triggering validationjQuery Validate - 检查是否需要控件而不触发验证
【发布时间】:2017-11-18 04:51:27
【问题描述】:

我正在尝试为所需的控件显示星号。代码在所需的类中运行良好,但现在我有两个字段,公司和名称。根据其他元素的值,只需要其中一个。是否可以在不验证控件或表单的情况下检查是否需要输入?

示例 html 结构:

<div class="form-group">
    <label class="control-label" for="CompanyName">Company Name</label>
    <div>
        <input type="text" id="CompanyName" name="CompanyName" class="form-control required">
    </div>
</div>

JS:

validationOptions: {
    ignore: ":disabled,:hidden",

    rules: {
        CompanyName: {
            required: function () {
                return ($("#ContactName").val().length === 0);
            }
        },
        ContactName: {
            required: function () {
                return ($("#CompanyName").val().length === 0);
            }
        }
    },

    onkeyup: function (element) {
        const $parent = $(element).parents(".form-group");

        if ($(element).valid()) {
            $parent.removeClass("invalid");
        } else {
            $parent.addClass("invalid");
        }
    },

    onfocusout: function () {
        if ($("form").valid()) {
            $("form.error").removeClass("error");
            $("form .invalid").removeClass("invalid");
        }
    },

    errorPlacement: function (error, element) {
        const $parent = $(element).parents(".form-group");

        if ($(element).hasClass("error")) {
            $parent.addClass("invalid");
        } else {
            $parent.removeClass("invalid");
        }
    },

    invalidHandler: function (event, validator) {
        $.each(validator.successList, function (index, item) {
            $(item).parents(".form-group").removeClass("invalid");
        });
        const errors = validator.numberOfInvalids();
        if (errors) {
            $.each(validator.errorList, function (index, item) {
                $(item.element).parents(".form-group").addClass("invalid");
            });
        }
    }
}

当然,我可以将我的代码放在上面所需的回调中,但这不是一个通用的解决方案。

我希望能够多次调用以下函数来根据字段的所需状态更新(引导)表单上的星号。

appendFormControlAsterisk: function ($panel) {
    //removeFormControlAsterisk($panel);

    let $controls = $(".form-control.required");

    $controls.each(function () {
        const $label = $(this).parents(".form-group").find(">.control-label");

        $label.html($label.html() + " <span class='text-danger'>*</span>");
    });
},

试图完成类似的事情:

appendFormControlAsterisk: function ($panel) {
    //removeFormControlAsterisk($panel);

    let $controls = $(".form-control");

    $controls.each(function () {
        if ($(this).isRequired()) {
            const $label = $(this).parents(".form-group").find(">.control-label");

            $label.html($label.html() + " <span class='text-danger'>*</span>");
        }
    });
},

【问题讨论】:

    标签: jquery jquery-validate


    【解决方案1】:

    是否可以在不验证控件或表单的情况下检查是否需要输入?

    作为 jQuery Validate 插件的一部分,没有任何方法可以返回声明、定义或分配的规则列表。 (您可以查看 settings.rules 对象内部的值,但这不是动态的或全面的

    但是,插件中内置了一个名为.check() 的未记录方法,该方法将在不触发任何错误消息的情况下检查有效性。它不限于required 规则,只是有效性。它只会在该字段为空白时有效地寻找required 规则。

    换句话说,在空白表单上,此方法将始终判断字段是否为required,而不会触发消息。

    您必须将它附加到验证器对象,并且参数必须是 DOM 元素。

    $('#myform').validate().check($('[name="test3"]')[0]) // <-- returns a boolean if defined
    

    var validator = $('#myform').validate({...}); // initialize plugin with options
    
    validator.check($('[name="test3"]')[0]) // <-- returns a boolean if defined
    

    演示:jsfiddle.net/we2johru/2/

    请注意,此方法仅在定义规则时返回布尔值。如果没有定义规则,此方法将返回undefined

    【讨论】:

    • 正如我所见,这可以解决问题。它在不再需要该字段时返回 undefined,在需要时返回 true/false。
    【解决方案2】:

    下面的代码示例应该可以为您解决问题。

    appendFormControlAsterisk: function ($panel) {
        //removeFormControlAsterisk($panel);
    
        let $controls = $(".form-control");
    
        $controls.each(function () {
            // if ($(this).isRequired()) {
            if ($(this).rules().required) {
                const $label = $(this).parents(".form-group").find(">.control-label");
    
                $label.html($label.html() + " <span class='text-danger'>*</span>");
            }
        });
    },
    

    如果每个元素上没有 .form-control 类,则可以从插件的 .elements() 方法中获取元素数组,并通过检查它们的 .rules() 方法来循环它们。

    const elements = $("#signupform").validate().elements();
    for (let i=0; i<elements.length; i++) {
        const $el = $(elements[i]);
        if ($el.rules().required) {
            $el.parents(".form-group").find(">.control-label").append(" <span class='text-danger'>*</span>");
        }
    }
    

    编辑:

    JSBin Demo 已添加。

    【讨论】:

    • 遗憾的是 $(this).rules().required 对于有条件的必填字段没有返回 true。这就像我之前的代码一样。
    • @HasanGürsoy 请在更新的答案中查看演示,如果它解决了您的问题,请告诉我。
    【解决方案3】:

    根据jQuery Validation Plugin 的示例,您的规则可以像下面的示例一样修改以解决您的问题。

     rules: {
        CompanyName: {
          required: {
            depends: function(element) {
              return $("#ContactName").val().length === 0;
            }
          }
        },
        ContactName: {
          required: {
            depends: function(element) {
              return $("#CompanyName").val().length === 0;
            }
          }
        }
      }
    

     rules: {
        CompanyName: {
          required: {
            depends: function(element) {
              if($("#ContactName").val().length === 0) {
                  $("#ContactName").removeClass("required");
                  return true;
              } else {
                  return false;
              }             
            }
          }
        },
        ContactName: {
          required: {
            depends: function(element) {
              if($("#CompanyName").val().length === 0) {
                  $("#CompanyName").removeClass("required");
                  return true;
              } else {
                  return false;
              }
            }
          }
        }
      }
    

    终于

    另一种方法是使用分组。

    <div class="form-group">
        <label class="control-label" for="CompanyName">Company Name</label>
        <div>
            <input type="text" id="CompanyName" name="CompanyName" class="form-control required">
        </div>
    </div>
    <div class="form-group">
        <label class="control-label" for="ContactName">Contact Name</label>
        <div>
            <input type="text" id="ContactName" name="ContactName" class="form-control required">
        </div>
    </div>
      // Use require_from_group to ensure at least one of the fields is complete
      rules: {
        ContactName: {
          require_from_group: [1, ".required"]
        },
        CompanyName: {
          require_from_group: [1, ".required"]
        }
      }
    

    【讨论】:

    • @HasanGürsoy 我知道我没有很好地解释我的答案,但它确实解决了你的问题。转到jqueryvalidation.org/validate 检查Specifies a contact element as required and as email address, the latter depending on a checkbox being checked for contact via email.示例。该示例显示了如何将元素嵌套在一起并创建所需的逻辑。对您而言,“必需”是至少一个字段具有价值。
    • @HasanGürsoy 请检查编辑,这正是您想要的。
    • 很高兴知道,但我只需要其中一个控件没有问题。我需要更新所有必需控件的可见星号。这意味着当字段 A 被填充时,B 不再必填,并且不再需要显示星号。
    • @HasanGürsoy 您的.required 类在您的输入元素旁边应用星号?您可以使用depends 来使用第一个示例,我将进行一些小修改。
    • 是的,到元素之前的标签。
    【解决方案4】:

    据我了解,您的每个输入元素都有form-control 类,而required 类仅适用于选定元素。基于此,下面是一个 sn-p,它将仅将星号分配给具有 required 类的那些。

    逻辑: 循环遍历具有form-control 类的元素,并使用hasClass() 检查它们是否也具有required 类。如果是,请附加危险星号。

    $(".form-control").each(function() {
      var requiredHtml = "<span class='text-danger'>*</span>";
      if ($(this).hasClass('required')) {
        $(this).closest('.form-group').find('label').append(requiredHtml);
      }
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="form-group">
      <label class="control-label" for="CompanyName">Company Name</label>
      <div>
        <input type="text" id="CompanyName" name="CompanyName" class="form-control required">
      </div>
    </div>
    <div class="form-group">
      <label class="control-label" for="designation">Designation</label>
      <div>
        <input type="text" id="designation" name="designation" class="form-control">
      </div>
    </div>

    【讨论】:

    • 我的代码已经这样做了。问题是我需要将星号附加到那些没有 .required 但在检查时是必需的。
    • 使用上面的代码应该很容易。而不是 if ($(this).hasClass('required')) { 将其更改为 if (!$(this).hasClass('required')) {
    • "我需要将星号附加到那些没有 .required 但在检查时是必需的。"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    • 1970-01-01
    相关资源
    最近更新 更多