我有一个多步骤表单,我正在尝试验证表单的每一步(所有输入字段均必填)
搜索并找到有效的解决方案以验证数组的多个输入后:
$("[name^=serialNbs]").each(function() {
$(this).rules("add", {
required: true,
messages: {
required: "Il faut remplir le numéro de série"
}
});
});
我仍然有与该消息有关的问题。
我的个性化消息仅在第一个输入(第3步)上显示
以下是代码段,只需在第一步上默认选择单选选项( Computer&Sonceboz ),在上给出1到10之间的数量第二步,然后尝试在不填写输入内容的情况下转到第三步
$(document).ready(function() {
var id, current_div;
var valid = $("#add_to_stock").validate({
rules: {
pc_quantity: {
required: true,
range: [1, 10],
digits: true
},
/*pc_model:{
required: true
},
hard_type:{
required: true
},
hard_model:{
required: true
},*/
hard_quantity: {
required: true,
range: [1, 10],
digits: true
}
},
messages: {
pc_quantity: "La quantité doit être entre 1 et 10",
pc_model: "Il faut choisir un modèle",
hard_type: "Il faut choisir un type",
hard_model: "Il faut choisir un modèle",
hard_quantity: "La quantité doit être entre 1 et 10"
},
highlight: function(element) {
$(element).closest('.form-group').addClass('has-error');
},
unhighlight: function(element) {
$(element).closest('.form-group').removeClass('has-error');
},
errorElement: 'span',
errorClass: 'help-block',
errorPlacement: function(error, element) {
if (element.hasClass('select2')) {
error.insertAfter(element.next('span'));
} else {
error.insertAfter(element);
}
}
});
$("[name^=serialNbs]").each(function() {
$(this).rules("add", {
required: true,
messages: {
required: "Il faut remplir le numéro de série"
}
});
});
$.fn.select2.defaults.set("theme", "bootstrap");
$(".select2").select2({
selectOnClose: true
});
$('.select2').on('change', function() {
$(this).valid();
});
//empeche l'envoi du formulaire on tappant la touche enter
$(document).on("keypress", "form", function(event) {
return event.keyCode != 13;
});
//évenements click des buttons "suivant"
$(".go_to_step_2").click(function() {
var option_val = $('input[name=mat_type]:checked').val();
//console.log(option_val);
switch (option_val) {
case 'computer':
$('#step1').hide();
$('#step2a').show();
break;
case 'hardware':
$('#step1').hide();
$('#step2b').show();
break;
case 'contract':
$('#step1').hide();
$('#step2c').show();
break;
default:
}
});
$.ajax('./sources/computer_models.txt', {
dataType: 'text',
success: function(text) {
var data = text.split("\n").map(function(item) {
var typeIdName = item.split(':');
return {
'id': typeIdName[0],
'text': typeIdName[1]
};
});
//console.log(data);
$('#pc_model').select2({
'data': data,
placeholder: "Selectionnez un modèle",
allowClear: true
});
}
});
$.ajax('./sources/hardware_types.txt', {
dataType: 'text',
success: function(text) {
var data = text.split("\n").map(function(item) {
var typeIdName = item.split(':');
return {
'id': typeIdName[0],
'text': typeIdName[1]
};
});
//console.log(data);
$('#hard_type').select2({
'data': data,
placeholder: "Selectionnez un type",
allowClear: true
});
}
});
$("#hard_type").on("change", function() {
var selectedType = $("#hard_type").val();
//console.log(selectedType);
$('#hard_model').html('').select2({
data: [{
id: '',
text: ''
}]
});
$.ajax('./sources/hardware_models_' + selectedType + '.txt', {
dataType: 'text',
success: function(text) {
var data = text.split("\n").map(function(item) {
var typeIdName = item.split(':');
return {
'id': typeIdName[0],
'text': typeIdName[1]
};
});
//console.log(data);
$('#hard_model').select2({
'data': data,
placeholder: "Selectionnez un modèle",
allowClear: true
});
}
});
});
$(".go_to_step_3").click(function() {
if ($('div').css('display') == 'block' && $('div').hasClass('add_mat')) {
id = $(".add_mat:visible").attr('id');
}
//console.log(id);
current_div = "#" + id;
//console.log(current_div);
if (valid.form()) {
$(current_div).hide();
$("#step3").show();
}
var option_val = $('input[name=mat_type]:checked').val();
var quantity;
switch (option_val) {
case 'computer':
quantity = $('input[name=pc_quantity]').val();
//console.log(quantity);
break;
case 'hardware':
quantity = $('input[name=hard_quantity]').val();
//console.log(quantity);
break;
case 'contract':
quantity = $('input[name=contr_quantity]').val();
//console.log(quantity);
break;
default:
}
//console.log(quantity);
var wrapper = $('.SN_wrapper');
var labelField = '';
var inputField = '';
var initialInputID = $("input[name*='serialNbs']").attr('id');
var x = parseInt(initialInputID.split("_")[1]);
var y = x + 1;
if (quantity != 1) {
for (i = 0; i < quantity - 1; i++) {
if ($("#serialNb_" + y).length == 0) {
console.log("1: i:" + i + " ; q:" + quantity + " ; y:" + y + " ; x:" + x);
labelField = '<label for="serialNb_' + y + ' " class="col-sm-2 control-label padding-right">' + 'Numéro de série ' + y + ' :</label>';
inputField = '<div class="col-sm-10"><input id="serialNb_' + y + '" name="serialNbs[' + y + ']" class="form-control " type="text" value="" required/></div>';
y++;
$(wrapper).append(labelField, inputField);
} else {
y++;
$(wrapper).append(labelField, inputField);
}
}
}
});
$(".go_to_step_4").click(function() {
if (valid.form()) {
$("#step3").hide();
$("#step4").show();
}
var option_val = $('input[name=mat_type]:checked').val();
var quantity;
var opt_site = $('input[name=stock_site]:checked').val();
var site;
var model;
var type;
var serialNbs = $("input[name*='serialNbs']");
switch (option_val) {
case 'computer':
$("#type_h4").hide();
if ($("#site").text().length == 0) {
site = opt_site;
$("#site").append(site);
} else {
if (site != opt_site) {
$("#site").text('');
site = opt_site;
$("#site").append(site);
} else {
$("#site").append(site);
}
}
if ($("#model").text().length == 0) {
model = $('#pc_model option:selected').text();
$("#model").append(model);
} else {
if (model != $('#pc_model option:selected').text()) {
$("#model").text('');
model = $('#pc_model option:selected').text();
$("#model").append(model);
} else {
$("#model").append(model);
}
}
if ($("#quant").text().length == 0) {
quantity = $('input[name=pc_quantity]').val();
$("#quant").append(quantity);
} else {
if (quantity != $('input[name=pc_quantity]').val()) {
$("#quant").text('');
quantity = $('input[name=pc_quantity]').val();
$("#quant").append(quantity);
} else {
$("#quant").append(quantity);
}
}
serialNbs.each(function() {
var eachVal = $(this).val();
var exists = $('#list_SN li:contains(' + eachVal + ')').length;
if (!exists) {
$("#list_SN").append("<li>" + eachVal + "</li>");
}
});
//console.log(model + ";" + quantity);
break;
case 'hardware':
if ($("#type").text().length == 0) {
type = $('#hard_type option:selected').text();
$("#type").append(type);
} else {
if (type != $('#hard_type option:selected').text()) {
$("#type").text('');
type = $('#hard_type option:selected').text();
$("#type").append(type);
} else {
$("#type").append(type);
}
}
if ($("#model").text().length == 0) {
model = $('#hard_model option:selected').text();
$("#model").append(model);
} else {
if (model != $('#hard_model option:selected').text()) {
$("#model").text('');
model = $('#hard_model option:selected').text();
$("#model").append(model);
} else {
$("#model").append(model);
}
}
if ($("#quant").text().length == 0) {
quantity = $('input[name=hard_quantity]').val();
$("#quant").append(quantity);
} else {
if (quantity != $('input[name=hard_quantity]').val()) {
$("#quant").text('');
quantity = $('input[name=hard_quantity]').val();
$("#quant").append(quantity);
} else {
$("#quant").append(quantity);
}
}
serialNbs.each(function() {
var eachVal = $(this).val();
var exists = $('#list_SN li:contains(' + eachVal + ')').length;
if (!exists) {
$("#list_SN").append("<li>" + eachVal + "</li>");
}
});
//console.log(type + ";" + model + ";" + quantity);
break;
case 'contract':
quantity = $('input[name=contr_quantity]').val();
//console.log(quantity);
break;
default:
}
//console.log(type + ";" + model + ";" + quantity);
});
//évenements click des buttons "précédent"
$(".back_to_step_1").click(function() {
if ($('div').css('display') == 'block' && $('div').hasClass('add_mat')) {
id = $(".add_mat:visible").attr('id');
}
//console.log(id);
current_div = "#" + id;
//console.log(current_div);
$(current_div).hide();
$("#step1").show();
});
$(".back_to_step_2").click(function() {
var option_val = $('input[name=mat_type]:checked').val();
//console.log(option_val);
var wrapper = $('.SN_wrapper');
var labelField = '';
var inputField = '';
switch (option_val) {
case 'computer':
$('#step3').hide();
$('#step2a').show();
wrapper.text('');
labelField = '<label for="serialNb_1 " class="col-sm-2 control-label padding-right">' + 'Numéro de série 1 :</label>';
inputField = '<div class="col-sm-10"><input id="serialNb_1" name="serialNbs[]" class="form-control" type="text" value="" /></div>';
$(wrapper).append(labelField, inputField);
break;
case 'hardware':
$('#step3').hide();
$('#step2b').show();
wrapper.text('');
labelField = '<label for="serialNb_1 " class="col-sm-2 control-label padding-right">' + 'Numéro de série 1 :</label>';
inputField = '<div class="col-sm-10"><input id="serialNb_1" name="serialNbs[]" class="form-control" type="text" value="" /></div>';
$(wrapper).append(labelField, inputField);
break;
case 'contract':
$('#step3').hide();
$('#step2c').show();
wrapper.text('');
labelField = '<label for="serialNb_1 " class="col-sm-2 control-label padding-right">' + 'Numéro de série 1 :</label>';
inputField = '<div class="col-sm-10"><input id="serialNb_1" name="serialNbs[]" class="form-control" type="text" value="" /></div>';
$(wrapper).append(labelField, inputField);
break;
default:
}
});
$(".back_to_step_3").click(function() {
$("#step4").hide();
$("#step3").show();
});
});
#add_to_stock fieldset:not(:first-of-type) {
display: none;
}
.add_mat {
position: relative;
min-height: 200px;
}
.container-decisions {
position: relative;
}
.container-decisions #step1,
#step2,
#step2a,
#step2b,
#step2c,
#step3,
#step4 {
display: none;
}
.container-decisions #step1 {
display: block;
}
.no_margin {
margin: 0;
padding: 0;
}
.btn {
min-width: 120px;
}
.label-info {
font-size: 90%;
}
.has-error input[type="text"],
.has-error input[type="number"],
.has-error select {
border: 1px solid #a94442;
}
.has-error .select2-selection {
border-color: rgb(185, 74, 72) !important;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Gestion du stock</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- Select2 plugin-->
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2-bootstrap-theme/0.1.0-beta.10/select2-bootstrap.min.css" rel="stylesheet" />
<!--JQuery Validator-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>
<!-- js et css perso-->
<script type="text/javascript" src="js/stock.js"></script>
<link rel="stylesheet" type="text/css" href="css/stock.css">
</head>
<body>
<div class="container">
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h3>Ajout de nouveau matériel</h3>
</div>
<div class="panel-body">
<div class="container-decisions">
<form id="add_to_stock" class="form-horizontal" name="add_to_stock" method="post" action="./result.php">
<div id="step1" class="add_mat">
<legend>Step 1 of 4</legend>
<div class="form-group col-sm-12">
<label class="control-label">Type de Matériel</label>
<div class="radio">
<label><input type="radio" name="mat_type" value="computer" checked>Ordinateur</label>
</div>
<div class="radio">
<label><input type="radio" name="mat_type" value="hardware">Hardware</label>
</div>
<div class="radio disabled">
<label><input type="radio" name="mat_type" value="contract" disabled>Contrat</label>
</div>
<div class="form-group col-sm-12">
<label class="control-label">Site du Stock</label>
<div class="radio">
<label><input type="radio" name="stock_site" value="Sonceboz" checked>Sonceboz</label>
</div>
<div class="radio">
<label><input type="radio" name="stock_site" value="Boncourt">Boncourt</label>
</div>
</div>
<div class="form-group col-sm-12">
<div class="col-sm-5 pull-right">
<button class="btn btn-success pull-right go_to_step_2" type="button">
Suivant <span class="glyphicon glyphicon-chevron-right"></span>
</button>
</div>
</div>
</div>
</div>
<div id="step2a" class="add_mat">
<legend>Step 2 of 4</legend>
<div class="form-group col-sm-12 ">
<h4 class="text-muted text-uppercase "><strong>Ajouter un ordinateur</strong></h4>
<div class="alert alert-warning"><span class="glyphicon glyphicon-warning-sign"></span><strong> Attention :</strong> Il faut remplir tous les champs ! La quantité doit être entre 1 et 10.</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="pc_model">Modèle :</label>
<div class="col-sm-10">
<select id="pc_model" name="pc_model" class="select2 form-control" style="width: 100%">
<option></option>
</select>
</div>
</div>
<div class="form-group no_margin">
<div class="col-sm-10">
<input id="pc_deploymentState" name="pc_deploymentState" class="form-control" type="hidden" value="Stock new">
</div>
</div>
<div class="form-group no_margin">
<div class="col-sm-10">
<input id="pc_incidentState" name="pc_incidentState" class="form-control" type="hidden" value="Operational">
</div>
</div>
<div class="form-group cont-quant">
<label class="col-sm-2 control-label" for="pc_quantity">Quantité :</label>
<div class="col-sm-10">
<input id="pc_quantity" name="pc_quantity" class="form-control quantity" type="number" min="1" max="10" value="" required>
</div>
</div>
<div class="form-group col-sm-12">
<div class="col-sm-1"></div>
<div class="col-sm-5">
<button class="btn btn-warning pull-left back_to_step_1" type="button">
<span class="glyphicon glyphicon-chevron-left"></span> Précédent
</button>
</div>
<div class="col-sm-6">
<button class="btn btn-success pull-right go_to_step_3" type="button">
Suivant <span class="glyphicon glyphicon-chevron-right"></span>
</button>
</div>
</div>
</div>
</div>
<div id="step2b" class="add_mat">
<legend>Step 2 of 4</legend>
<div class="form-group col-sm-12">
<label class="control-label">Ajouter du hardware</label>
<div class="form-group">
<label class="col-sm-2 control-label" for="hard_type">Type :</label>
<div class="col-sm-10">
<select id="hard_type" name="hard_type" class="select2 form-control" style="width: 100%" required>
<option></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="hard_model">Model :</label>
<div class="col-sm-10">
<select id="hard_model" name="hard_model" class="select2 form-control" style="width: 100%" required>
<option></option>
</select>
</div>
</div>
<div class="form-group no_margin">
<div class="col-sm-10">
<input id="hard_deploymentState" name="hard_deploymentState" class="form-control" type="hidden" value="Stock new">
</div>
</div>
<div class="form-group no_margin">
<div class="col-sm-10">
<input id="hard_incidentState" name="hard_incidentState" class="form-control" type="hidden" value="Operational">
</div>
</div>
<div class="form-group cont-quant">
<label class="col-sm-2 control-label" for="hard_quantity">Quantité :</label>
<div class="col-sm-10">
<input id="hard_quantity" name="hard_quantity" class="form-control quantity" type="number" min="1" max="10" value="" required>
</div>
</div>
<div class="form-group col-sm-12">
<div class="col-sm-1"></div>
<div class="col-sm-5">
<button class="btn btn-warning pull-left back_to_step_1" type="button">
<span class="glyphicon glyphicon-chevron-left"></span> Précédent
</button>
</div>
<div class="col-sm-6">
<button class="btn btn-success pull-right go_to_step_3" type="button">
Suivant <span class="glyphicon glyphicon-chevron-right"></span>
</button>
</div>
</div>
</div>
</div>
<div id="step2c" class="add_mat">
<legend>Step 2 of 4</legend>
<div class="form-group col-sm-12">
<label class="control-label">Contract</label>
<div class="form-group col-sm-12">
<div class="col-sm-1"></div>
<div class="col-sm-5">
<button class="btn btn-warning pull-left back_to_step_1" type="button">
<span class="glyphicon glyphicon-chevron-left"></span> Précédent
</button>
</div>
<div class="col-sm-6">
<button class="btn btn-success pull-right go_to_step_3" type="button">
Suivant <span class="glyphicon glyphicon-chevron-right"></span>
</button>
</div>
</div>
</div>
</div>
<div id="step3" class="add_mat">
<legend>Step 3 of 4</legend>
<div class="form-group col-sm-12">
<label class="control-label">Ajout des numéros de série</label>
<div class="SN_wrapper form-group">
<label class="col-sm-2 control-label padding-right" for="serialNb_1">Numéro de série 1 :</label>
<div class="col-sm-10">
<input id="serialNb_1" name="serialNbs[1]" class="form-control" type="text" value="" required>
</div>
</div>
<div class="form-group col-sm-12">
<div class="col-sm-1"></div>
<div class="col-sm-5">
<button class="btn btn-warning pull-left back_to_step_2" type="button">
<span class="glyphicon glyphicon-chevron-left"></span> Précédent
</button>
</div>
<div class="col-sm-6">
<button class="btn btn-success pull-right go_to_step_4" type="button">
Suivant <span class="glyphicon glyphicon-chevron-right"></span>
</button>
</div>
</div>
</div>
</div>
<div id="step4" class="add_mat">
<legend>Step 4 of 4</legend>
<div id="recap" class="container">
<h3>Récapitulation</h3>
<h4 id="site_h4"><span class="label label-info">Site :</span> <span id="site"></span></h4>
<h4 id="type_h4"><span class="label label-info">Type :</span> <span id="type"></span></h4>
<h4 id="model_h4"><span class="label label-info">Modèle :</span> <span id="model"></span></h4>
<h4 id="quant_h4"><span class="label label-info">Quantité :</span> <span id="quant"></span></h4>
<div class="">
<h4><span class="label label-info">Numéros de série : </span></h4>
<ol id="list_SN">
</ol>
</div>
</div>
<div class="form-group col-sm-12">
<div class="form-group col-sm-12">
<div class="col-sm-1"></div>
<div class="col-lg-5">
<button class="btn btn-warning pull-left back_to_step_3" type="button">
<span class="glyphicon glyphicon-chevron-left"></span> Précédent
</button>
</div>
<div class="col-lg-6">
<button id="add_new_mat" class="btn btn-primary pull-right" type="submit">
Ajouter
</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
答案 0 :(得分:1)
您是否正在动态生成这些其他字段?它不能像您期望的那样工作,因为当您调用包含.each()
方法的.rules()
时,这些附加字段尚不存在。创建它们后,您必须在 后在这些新字段上调用.rules()
。
它们仍然显示为required
的原因是因为HTML元素中还具有required
属性,这是多余的。如果您要使用jQuery Validate方法正确分配required
规则,则不需要内联required
属性。
似乎您也可以从if / else语句中提取一些多余的行,但这取决于您。
类似的东西:
if (quantity != 1) {
for (i = 0; i < quantity - 1; i++) {
if ($("#serialNb_" + y).length == 0) {
console.log("1: i:" + i + " ; q:" + quantity + " ; y:" + y + " ; x:" + x);
labelField = '<label for="serialNb_' + y + ' " class="col-sm-2 control-label padding-right">' + 'Numéro de série ' + y + ' :</label>';
inputField = '<div class="col-sm-10"><input id="serialNb_' + y + '" name="serialNbs[' + y + ']" class="form-control " type="text" value="" /></div>';
}
// redundant lines on both sides of if/else??
y++;
$(wrapper).append(labelField, inputField);
// assign the rules/messages right here, just after a new field is inserted
$('#serialNb_' + y).rules("add", {
required: true,
messages: {
required: "Il faut remplir le numéro de série"
}
});
} // end for loop
} // end if
或者,如果一次创建所有其他字段,则可以在创建所有这些其他字段之后立即将原始.each()
循环移动到一个点。
if (quantity != 1) {
// create all fields
....
}
// all additional fields exist now
$("[name^=serialNbs]").each(function() {
$(this).rules("add", {
required: true,
messages: {
required: "Il faut remplir le numéro de série"
}
});
});