在需要“选择”或“输入”时验证表单

Posted

技术标签:

【中文标题】在需要“选择”或“输入”时验证表单【英文标题】:Validating a form when either a "select" OR "input" is required 【发布时间】:2019-01-31 23:51:18 【问题描述】:

我有一个页面包含多个不同的表单,当一个表单被提交时,我使用下面的函数从该表单中收集所有输入,并检查是否有空值:

function validateForm(form) 
  var inputs = form.getElementsByTagName('input');
  var selects = form.getElementsByTagName('select');
  var errors = 0;

  for (var i = 0; i < inputs.length; i++) 
    if(inputs[i].classList.contains('required'))     
      if(inputs[i].value === "") 
        inputs[i].classList.add("warning");
        errors++;
       else 
        inputs[i].classList.remove("warning");
      
    
  
  if(errors) 
    return false;
   else 
    return true;
  

如果它找到一个空值,它会添加一个类“警告”,它只是给输入一个红色边框,然后返回 false,这样表单就不会被提交。

这是我遇到麻烦的地方:一些表单包含一个

假设表单用于添加新产品。选择是用现有产品“类别”动态填充的,如果用户想要创建新类别,则输入文本。这是表单的简化版本:

    <form method = "post" onsubmit = "return validateForm(this)">
      <div class = "form-group">
        <label>Product Name</label>
        <input class = "form-control required" type = "text" name = "product" />
      </div>
      <div class = "form-group">
        <select class = "form-control required" id = "category" name = "category[]">
          <option value = "">Select Existing Category</option>
          <option value = "Shirts">Shirts</option>
          <option value = "Shoes">Shoes</option>
          <option value = "Pants">Pants</option>
        </select>
      </div>
      <div class = "form-group">
        <label>Create New Category</label>
        <input class = "form-control required" type = "text" name = "category[]" />
      </div>
      <div class = "form-group">
        <input class = "btn btn-primary" type = "submit" value = "Submit" />
      </div>
    </form>

由于我使用 for 循环遍历输入 - 选择和输入不会有相同的索引,所以我不能做这样的事情:

  if((selects[i].value === "" && inputs[i].value === "") || (selects[i].value !== "" && inputs[i].value !== "")) 
    // add the warning class to both
   

我觉得答案在于使用 name 属性,即比较 selects.name 和 inputs.name,但是如何绕过循环中的不同索引?而且,它应该只在遇到选择时才进行比较。它不一定存在,取决于形式。

基本上,我需要修改我的函数来做到这一点:

我。从提交的表单中收集所有输入和选择(如果有 - 某些表单不会)

二。确保没有“必需”类的输入是空白的(除非有相应的选择,在这种情况下,请参阅下面的 III)

三。如果有选择,请找到具有相同“名称”的文本输入(不需要具有相同的名称,但我认为这是正确的方法)。其中之一,但不是两者,必须有一个值。如果两者都是空白,或者都有一个值,它们应该得到“警告”类;

任何人都可以提供任何帮助,我们将不胜感激!

【问题讨论】:

我建议您使用 'data-*' 属性来指定备用元素。然后更改函数以检查该数据属性。如果未找到该属性,则表示该元素是必需的。如果找到数据属性,则使用它来检查其他元素。所以,'input' 和 'select' 仍然有一个 required 类,但是你的函数可以检查 data 属性。希望这是有道理的。 @CharlesEF 我想我知道你的意思:向选择/输入对添加一个匹配的 'data-*' 属性值,然后在我的循环中添加一些代码来检查输入是否具有该属性,如果是这样,寻找具有匹配值的数据属性的选择,然后比较它们的值?我如何“找到”具有相同数据属性值的选择? form.elements[theName] 相当老派或document.querySelector("[name='" + theName + "']") 【参考方案1】:

这是一个函数,可以完全按照您的意愿进行操作,并且可以处理您想要的任何形式,只要它们具有相同的 html 结构。

注意事项:

我建议尽可能避免使用内联事件侦听器,在 下面的sn-p我用addEventListener方法附加submit 事件到文档中的所有表单,您可以将其更改为 如果需要,可以使用一些特定的表格。 我建议不要只为所需元素添加边框 您还可以添加一些文字来说明问题所在。

// getting all forms in the page you can also get specific forms based on their class-name
var forms = document.getElementsByTagName('form'),
  l = forms.length,
  i = 0;
// adding submit submit event listener to the referenced forms
for(; i < l; i++) 
  forms[i].addEventListener('submit', validateForm);



function validateForm(e) 
  var els = this.querySelectorAll('input.required'),
    len = els.length,
    err = false,
    c = 0,
    inpName = '';
  // checking if the form has a select, if so, allow only the select or the input to be filled
  var isSelect = this.getElementsByTagName('select');
  if(isSelect[0] !== undefined && isSelect[0] !== null) 
    var inp = isSelect[0].parentNode.nextElementSibling.querySelector('input.required');
    inpName = inp.name;
    if((isSelect[0].value == '' && inp.value.trim().length === 0) || (isSelect[0].value != '' && inp.value.trim().length > 0)) 
      err = true;
      isSelect[0].classList.add("warning");
      inp.classList.add("warning");
     else 
      isSelect[0].classList.remove("warning");
      inp.classList.remove("warning");
    
  

  // iterate through the rest of the inputs and check for empty one, thus trimming them before checking
  for(; c < len; c++) 
    if(els[c].name !== inpName) 
      if(els[c].value.trim() == '') 
        err = true;
        els[c].classList.add("warning");
       else 
        els[c].classList.remove("warning");
      
    
  
  // based on the error variable, either submit the form or cancel submission
  (!err) ? this.submit():e.preventDefault();
.warning 
  border: 2px solid red;
<form method="post">
    <div class="form-group">
        <label>Product Name</label>
        <input class="form-control required" type="text" name="product" />
    </div>
    <div class="form-group">
        <select class="form-control required" id="category" name="category[]">
            <option value="">Select Existing Category</option>
            <option value="Shirts">Shirts</option>
            <option value="Shoes">Shoes</option>
            <option value="Pants">Pants</option>
        </select>
    </div>
    <div class="form-group">
        <label>Create New Category</label>
        <input class="form-control required" type="text" name="category[]" />
    </div>
    <div class="form-group">
        <input class="btn btn-primary" type="submit" value="Submit" />
    </div>
</form>

希望我把你推得更远。

您可能会收到一条消息:“自定义错误模块没有 识别此错误。”当您从 上面的 sn-p,这是由于 *** 的限制,因为他们 不允许/服务器端代码(*** 不允许表单 提交)。

【讨论】:

哇,你说得对,这正是我想要的,哈哈。太感谢了。它肯定比我自己写的要先进,但我逐行将其分开以了解每个步骤。绝对是一次很棒的学习经历。再次感谢! @JohnO 随时欢迎您。如果您需要进一步的解释,请告诉我。但是,请记住,我没有从你那里得到太多细节,所以我根据你在问题中提供的表单结构来实现我的答案,因此更改表单结构可能会导致故障。再次,需要任何帮助让我听到。 感谢您的报价,我会通知您的!我现在仍在逐行浏览它。当我遵循它时这是有道理的,但是是的......我自己绝对不可能写这个。我需要复习一下我的 javascript 哈哈。 我们都还在学习。慢慢来,我在代码中添加了一些 cmets,它们可能会对您有所帮助。

以上是关于在需要“选择”或“输入”时验证表单的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript ---[表单验证,正则表达式]

如何验证反应选择

ruby 上使用 lbs 或 ' 和 " 符号输入时如何验证表单字段中的身高和体重

在保护评论表单和相关 API 端点时,是不是应该在浏览器、服务器或两者中对输入进行清理、验证和编码?

看用Tornado如何自定义实现表单验证

Kofax 转换 - 在验证时更新表单上的字段