在需要“选择”或“输入”时验证表单
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,它们可能会对您有所帮助。以上是关于在需要“选择”或“输入”时验证表单的主要内容,如果未能解决你的问题,请参考以下文章
ruby 上使用 lbs 或 ' 和 " 符号输入时如何验证表单字段中的身高和体重