如何避免在此 jQuery 验证案例中重复 isValid?

How can I avoid the repeated isValid in this jQuery validate case?

我正在尝试验证一个字段,我的主要目标是:

  1. 当用户登陆页面时,没有验证
  2. 验证从用户单击“名称查询”字段开始,它会在按键向上和焦点移出时进行验证
  3. 表单提交时也会验证字段:如果字段无效,单击提交按钮除了显示验证消息外什么都不做;只有在字段有效时才会提交表单。

这是我想出的一个片段:

var myForm = $("#myform"),
    nameQuery = $("#NameQuery");

myForm.validate({
  rules: {
    NameQuery: "required"
  },
  messages: {
    NameQuery: "Please fill in name query"
  }
});

nameQuery.on("focusout keyup submit", function() {
  var isValid = myForm.valid();
  if (!isValid) {
    nameQuery.addClass("alert-text");
  }
  else {
    nameQuery.removeClass("alert-text");
  };
});

nameQuery.on("submit", function() {
  var isValid = myForm.valid();
  if (isValid) {
    $("p").html("Form sumitted");
  }
  else {
    $("p").empty();
  };
});
.alert-text {
  border: 1px dashed red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.12.0/jquery.validate.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.12.0/additional-methods.js"></script>


<form id="myform" method="post">
  <label for="NameQuery">Name Query: </label>
  <input type="text" id="NameQuery" name="NameQuery">
  <input type="submit" value="Search">
  <p></p>
</form>

几个问题:

  1. 我用了两次var isValid = myForm.valid();,好像有点重复,但我想不出更简洁的方法?
  2. 如果字段有效,点击提交按钮会导致一切消失?
  3. 我的代码片段可以改进吗?

编辑:通过重复代码并使代码更简洁,我的意思是可以将这两个部分合并为一个部分:

nameQuery.on("focusout keyup submit", function() {
  var isValid = myForm.valid();
  if (!isValid) {
    nameQuery.addClass("alert-text");
  }
  else {
    nameQuery.removeClass("alert-text");
  };
});

nameQuery.on("submit", function() {
  var isValid = myForm.valid();
  if (isValid) {
    $("p").html("Form sumitted");
  }
  else {
    $("p").empty();
  };
});

他们操作的是同一个元素,里面的逻辑看起来很相似。

答案:

1)如果看起来重复var isValid = myForm.valid();然后使用if(myForm.valid())这个。

2)一切都消失了,因为你在输入框而不是表单上调用提交功能,默认的表单提交行为是刷新。 试试下面的代码

  var myForm = $("#myform"),
    nameQuery = $("#NameQuery");

myForm.validate({
  rules: {
    NameQuery: "required"
  },
  messages: {
    NameQuery: "Please fill in name query"
  }
});

nameQuery.on("focusout keyup submit", function() {
  if (!myForm.valid()) {
    nameQuery.addClass("alert-text");
  }
  else {
    nameQuery.removeClass("alert-text");
  };
});

myForm.on("submit", function(e) {
  e.preventDefault();
  if (myForm.valid()) {
    $("p").html("Form submitted");
  }
  else {
    $("p").empty();
  };
});
.alert-text {
  border: 1px dashed red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.12.0/jquery.validate.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.12.0/additional-methods.js"></script>


<form id="myform" method="post">
  <label for="NameQuery">Name Query: </label>
  <input type="text" id="NameQuery" name="NameQuery">
  <input type="submit" value="Search">
  <p></p>
</form>

3)我改进了一点。可以看到上面

你完全误解了这个插件能为你做什么...

when a user lands on the page, no validations

这已经是这个插件的默认行为。除了用户看不到的插件初始化外,页面加载时没有任何反应。

validation starts on a user clicks the Name Query field, and it validates on both key up and focus out

这称为 "eager" 验证,插件默认为 "lazy"。有一种无需任何外部事件处理程序即可实现 "eager" 的简单方法。

Field is also validated on form submission: if field is invalid, clicking the submit button should do nothing but showing the validation message; form will only be submitted when the field is valid.

这正是该插件在正确使用时的工作方式。

by saying code repeated and being more concise I meant can these 2 parts be merged into 1 part:

不,这两部分应该完全删除。它们是多余的,因为插件已经为您提供了这些选项。


You really need to review the docs to understand everything here。很少有需要外部事件处理函数的情况,所以如果需要,它会开始变得比需要的复杂得多。到那时,您还不如从头开始编写自己的自定义验证函数。

此插件有 submitHandler 用于当表单有效并被提交时的自定义代码,onfocusoutonkeyup 选项用于当这些操作发生时的自定义代码,还有很多很多其他选项和配置。

对于输入框周围的红色虚线,默认的 class 是 error,因此只需将此 class 设为 CSS。

input.error {
    /* this targets the input element with a pending validation error */
    border: 1px dashed red;
}

label.error [
    /* this targets the validation error message */
}

如果您确实需要更改默认 class 的名称,请使用 errorClass 选项。

如果您在提交时需要额外的自定义代码,请仅使用 submitHandler。示例:通过 ajax 提交时。否则,对于常规提交,可以省略 submitHandler 并且插件的默认行为是在有效时简单地提交表单。

对这些操作使用 onfocusoutonkeyup 自定义代码。如果您想要更积极的验证,例如在初始提交尝试之前进行验证,那么您可以在此处放置自定义代码以强制执行此操作。否则,请删除这两个选项并重试。您的表单只有一个输入,所以它可能根本无关紧要,因为如果他们输入字段和退格键,验证就会开始。当用户在不输入任何内容的情况下通过多个输入选项卡时,Eager vs. Lazy 更像是一个问题。这里并非如此。

var myForm    = $("#myform");

// nameQuery = $("#NameQuery"); // NOT needed here.  
/* Plugin uses NAME attribute only, not ID and not assigned variables */

myForm.validate({
    rules: {
        NameQuery: "required"
    },
    messages: {
        NameQuery: "Please fill in name query"
    },
    onkeyup: function(element) {
        this.element(element);  // <- force "eager validation"
    },
    onfocusout: function(element) {
        this.element(element);  // <- force "eager validation"
    },
    // errorClass: "alert-text", // default is "error" - just use CSS
    submitHandler: function(form) {
        $("p").html("Form submitted"); // for demo
        // form.submit(); // default line, un-comment to submit when valid or leave out entire submitHandler to submit when valid
    }
});
input.error {
    border: 1px dashed red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.12.0/jquery.validate.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.12.0/additional-methods.js"></script>


<form id="myform" method="post">
    <label for="NameQuery">Name Query: </label>
    <input type="text" id="NameQuery" name="NameQuery">
    <input type="submit" value="Search">
    <p></p>
</form>