在需要 "select" 或 "input" 时验证表单
Validating a form when either a "select" OR "input" is required
我有一个包含多个表单的页面,所有表单都不同,当提交一个表单时,我使用下面的函数使用 class "required" 从该表单收集所有输入并检查是否为空值:
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;
}
}
如果它找到一个空值,它会添加 class "warning" 这只会给输入一个红色边框,然后 returns false 这样表单就不会被提交。
这就是我 运行 遇到麻烦的地方:一些表单包含一个
假设该表单用于添加新产品。 select 是用现有产品 "categories" 动态填充的,文本输入用于用户是否要创建新类别。这是表格的简化版本:
<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 循环遍历输入 - select 和输入不会有相同的索引,所以我不能这样做:
if((selects[i].value === "" && inputs[i].value === "") || (selects[i].value !== "" && inputs[i].value !== "")) {
// add the warning class to both
}
我觉得答案在于使用 name 属性,即比较 selects.name 和 inputs.name,但我如何绕过循环中的不同索引?而且,它应该只在遇到 select 时进行比较。不一定存在,要看形式。
基本上,我需要修改我的函数来执行此操作:
我。从提交的表单
中收集所有输入和 selects(如果有 - 有些表单不会)
二.确保带有 "required" class 的输入中的 none 是空白的(除非有相应的 select,在这种情况下请参见下面的 III)
三。如果有 select,找到具有相同 "name" 的文本输入(不需要具有相同的名称,但我认为这是正确的方法)。其中之一,但不是两者,必须有一个值。如果两者都是空白,或者两者都有值,则它们应该得到 "warning" class;
任何人都可以提供任何帮助,我们将不胜感激!
这是一个函数,它可以完全按照您的要求进行操作,并且可以处理您想要的任何形式,只要它们具有相同的 HTML
结构即可。
备注:
- 我建议尽可能避免内联事件侦听器,在
下面的片段我使用
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>
希望我能进一步推动你。
You may get a message saying: "The custom error module does not
recognize this error." when you successfully submit the form from the
snippet above, that due to Whosebug
's restrictions as they
don't allow/server side code (Whosebug
doesn't let the form to
be submitted).
我有一个包含多个表单的页面,所有表单都不同,当提交一个表单时,我使用下面的函数使用 class "required" 从该表单收集所有输入并检查是否为空值:
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;
}
}
如果它找到一个空值,它会添加 class "warning" 这只会给输入一个红色边框,然后 returns false 这样表单就不会被提交。
这就是我 运行 遇到麻烦的地方:一些表单包含一个
假设该表单用于添加新产品。 select 是用现有产品 "categories" 动态填充的,文本输入用于用户是否要创建新类别。这是表格的简化版本:
<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 循环遍历输入 - select 和输入不会有相同的索引,所以我不能这样做:
if((selects[i].value === "" && inputs[i].value === "") || (selects[i].value !== "" && inputs[i].value !== "")) {
// add the warning class to both
}
我觉得答案在于使用 name 属性,即比较 selects.name 和 inputs.name,但我如何绕过循环中的不同索引?而且,它应该只在遇到 select 时进行比较。不一定存在,要看形式。
基本上,我需要修改我的函数来执行此操作:
我。从提交的表单
中收集所有输入和 selects(如果有 - 有些表单不会)二.确保带有 "required" class 的输入中的 none 是空白的(除非有相应的 select,在这种情况下请参见下面的 III)
三。如果有 select,找到具有相同 "name" 的文本输入(不需要具有相同的名称,但我认为这是正确的方法)。其中之一,但不是两者,必须有一个值。如果两者都是空白,或者两者都有值,则它们应该得到 "warning" class;
任何人都可以提供任何帮助,我们将不胜感激!
这是一个函数,它可以完全按照您的要求进行操作,并且可以处理您想要的任何形式,只要它们具有相同的 HTML
结构即可。
备注:
- 我建议尽可能避免内联事件侦听器,在
下面的片段我使用
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>
希望我能进一步推动你。
You may get a message saying: "The custom error module does not recognize this error." when you successfully submit the form from the snippet above, that due to
Whosebug
's restrictions as they don't allow/server side code (Whosebug
doesn't let the form to be submitted).