我有一个多形态,它分为三部分。fieldsets
. 我试图实现的工作流程是。
fieldset
..next
按钮。validate()
发生在 .next
按钮点击,如果无效(即必填字段没有填写),我想给这些错误类添加一个 input
所以我可以对它们进行样式设计(添加红色边框)。fieldset
.此刻我的 validate()
是出现了一点故障。例如在我下面的演示中,执行以下步骤。
address
也是一个必填字段(在JS中定义的),但不显示错误?在点击按钮时,我希望错误显示出来。
现在,假设名字和地址(该字段集中的两个必填字段)被填写,在下一次点击时,由于这些字段是有效的,我想在下一个字段集中显示动画,但在 submitHandler
没有工作?不确定为什么?
演示一下。
jQuery(function($) {
var current_fs, next_fs, previous_fs;
var left, opacity, scale;
var animating;
$(".next").click(function() {
console.log('next is clicked');
$("form").validate({
rules: {
// name : param
fname: "required",
address: "required",
phone: {
required: true,
matches: "^(\\d|\\s)+$",
minlength: 11,
maxlength: 11
}
},
messages: {
fname: "Please enter your firstname",
address: "Please enter your address",
phone: "Please enter a valid phone number"
},
// if validation is correct, animate in next fieldset
submitHandler: function(form) {
if (animating) return false;
animating = true;
current_fs = $(this).parent();
next_fs = $(this).parent().next();
$("#progressbar li").eq($("fieldset").index(next_fs)).addClass("active");
next_fs.show();
current_fs.animate({
opacity: 0
}, {
step: function(now, mx) {
scale = 1 - (1 - now) * 0.2;
left = (now * 50) + "%";
opacity = 1 - now;
current_fs.css({
'transform': 'scale(' + scale + ')',
'position': 'absolute'
});
next_fs.css({
'left': left,
'opacity': opacity,
'height': 'auto',
'padding': '60px 50px'
});
},
duration: 800,
complete: function() {
current_fs.hide();
animating = false;
},
easing: 'easeInOutBack'
});
}
});
$('input').blur(function() {
$("form").validate().element("input");
});
});
});
.form {
min-height: 800px;
user-select: none;
overflow: hidden;
}
.form form#rsvpForm {
width: 600px;
margin: 50px auto;
text-align: center;
position: relative;
}
.form form#rsvpForm fieldset {
background: white;
border: 0 none;
border-radius: 3px;
box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.4);
padding: 60px 50px;
box-sizing: border-box;
position: relative;
width: 100%;
display: block !important;
}
.form form#rsvpForm fieldset:not(:first-of-type) {
opacity: 0;
}
.form form#rsvpForm input,
.form form#rsvpForm textarea {
padding: 15px;
border: 1px solid #ccc;
border-radius: 3px;
margin-bottom: 10px;
width: 100%;
box-sizing: border-box;
outline: none;
}
.form form#rsvpForm input.error,
.form form#rsvpForm textarea.error {
border: 1px solid red;
}
.form form fieldset .error__message{
display: none;
}
.form form fieldset.has-error .error__message{
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js?ver=5.3.2'></script>
<script type="text/javascript" src='https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js'></script>
<div class="form" id="rsvp-form">
<form id="rsvpForm" action="" method="post">
<!-- fieldset 1 -->
<fieldset>
<input type="text" name="fname" placeholder="First name*" />
<textarea name="address" placeholder="Address*"></textarea>
<input type="button" id="confirm" name="next" class="next" value="Next" />
</fieldset>
<!-- fieldset 2 -->
<fieldset>
<input type="tel" name="phone" placeholder="Phone*" required />
<input type="button" id="confirm" name="next" class="next" value="Next" />
</fieldset>
<!-- fieldset 3 -->
<fieldset>
<textarea name="other" placeholder="Enter your note here ..." required></textarea>
<input type="submit" name="submit" class="submit" value="Submit" />
</fieldset>
</form>
</div>
为了实现这个目标,你必须创建3个独立的表单。每个表单都有自己的验证。在一个表单上设置所有的3个验证将始终导致无效,因为验证是活动的,所需的字段是未填写的。
<div class="form" id="rsvp-form">
<form id="rsvpForm1" action="" method="post">
<!-- fieldset 1 -->
<fieldset id="field1">
<input type="text" name="fname" placeholder="First name*" />
<textarea name="address" placeholder="Address*"></textarea>
<button>Next</button>
</fieldset>
<!--/ fieldset 1 -->
</form>
<form id="rsvpForm2" action="" method="post">
fieldset 2
<!-- fieldset 2 -->
<fieldset id="fieldset2">
<input type="tel" name="phone" placeholder="Phone*" required />
<button>Next</button>
</fieldset>
</form>
<!--/ fieldset 2 -->
<form id="rsvpForm3" action="" method="post">
fieldset 3
<!-- fieldset 3 -->
<fieldset id="fieldset3">
<textarea name="other" placeholder="Enter your note here ..." required></textarea>
<button>Next</button>
</fieldset>
<!--/ fieldset 3 -->
</form>
</div>
其次,删除输入类型按钮,放置一个按钮代替。最后,给3个表单都添加id,并在提交时用它来验证表单。另外,我将验证和消息以对象的形式添加,因为这样更易读。
jQuery(function($) {
var current_fs, next_fs, previous_fs;
var left, opacity, scale;
var animating;
/*First Form*/
$("#rsvpForm1").validate({
rules: {
fname: {
required: true,
},
address: {
required: true,
// minlength: 5
}
},
messages: {
fname: {
required: "Please enter your firstname",
},
address:{
required: "Please enter your address",
}
},
// if validation is correct, animate in next fieldset
submitHandler: function(form) {
formSubmit(form,'#fieldset1','#fieldset2');
}
});
/*----------*/
/*Second Form*/
$("#rsvpForm2").validate({
rules: {
phone: {
required: true,
minlength: 5,
maxlength: 11
}
},
messages: {
phone:{
required: "Please enter a valid phone number",
matches: "Invalid value",
minlength: "Min length is exceeded",
maxlength: "Max length is exceeded",
}
},
// if validation is correct, animate in next fieldset
submitHandler: function(form) {
formSubmit(form,'#fieldset2','#fieldset3');
}
});
/*-----------*/
/*Third Form*/
$("#rsvpForm3").validate({
rules: {
phone: {
required: true,
matches: "^(\\d|\\s)+$",
minlength: 11,
maxlength: 11
}
},
messages: {
other:{
required: "Please enter a message"
},
},
// if validation is correct, animate in next fieldset
submitHandler: function(form) {
formSubmit(form);
}
});
/*----------*/
function formSubmit(form, current, next){
if (animating) return false;
animating = true;
current_fs = $(current);
next_fs = $(next);
next_fs.addClass("active");
next_fs.show();
current_fs.animate({
opacity: 0
}, {
step: function(now, mx) {
scale = 1 - (1 - now) * 0.2;
left = (now * 50) + "%";
opacity = 1 - now;
current_fs.css({
'transform': 'scale(' + scale + ')',
'position': 'absolute'
});
next_fs.css({
'left': left,
'opacity': opacity,
'height': 'auto',
'padding': '60px 50px'
});
},
duration: 800,
complete: function() {
current_fs.hide();
animating = false;
},
easing: 'easeInOutBack'
});
}
});
当点击".next "时,该表格没有提交,因此。submitHandler
没有被调用,表单也没有被验证。要解决这个问题,请从 submitHandler
到.next点击处理程序。
我还将提交按钮改为带有".submit "类的".next "按钮。这样点击处理程序就会被调用,当 .submit
类,然后提交表单。
要使表单在点击下一步后检查任何元素,需要在表单中添加 required
属性到这些元素。
电话验证规则有一个错误 matches: "^(\\d|\\s)+$",
. 首先,目前还没有相应的方法来 matches
其次,regexp必须重新写成这样的内容 /^(\d|\s)+$/
没有引号和转义符)。
这是一个工作的例子。
jQuery(function($) {
var current_fs, next_fs, previous_fs;
var left, opacity, scale;
var animating = false;
// Add method to validate based on regexp
$.validator.addMethod("matches", function(value, element, regexpr) {
return regexpr.test(value);
}, "Please enter a valid phone number");
$("form").validate({
rules: {
// name : param
fname: {
required: true
},
address: {
required: true
},
phone: {
required: true,
matches: /^(\d|\s)+$/,
minlength: 11,
maxlength: 11
}
},
messages: {
fname: "Please enter your firstname",
address: "Please enter your address",
phone: "Please enter a valid phone number"
},
});
// Add process to .next click not submit
$(".next").click(function() {
if ($(this).hasClass("submit"))
$("form").submit();
current_fs = $(this).parent();
let isValid = true;
current_fs.children("[required]").each(function(i, e) {
const valid = current_fs.validate().element(jQuery(e));
if (!valid)
isValid = false;
});
if (!isValid) return false;
if (animating) return false;
animating = true;
current_fs = $(this).parent();
next_fs = $(this).parent().next();
$("#progressbar li").eq($("fieldset").index(next_fs)).addClass("active");
next_fs.show();
current_fs.animate({
opacity: 0
}, {
step: function(now, mx) {
scale = 1 - (1 - now) * 0.2;
left = (now * 50) + "%";
opacity = 1 - now;
current_fs.css({
'transform': 'scale(' + scale + ')',
'position': 'absolute'
});
next_fs.css({
'left': left,
'opacity': opacity,
'height': 'auto',
'padding': '60px 50px'
});
},
duration: 800,
complete: function() {
current_fs.hide();
animating = false;
},
easing: 'easeInOutBack'
});
});
});
.form {
min-height: 800px;
user-select: none;
overflow: hidden;
}
.form form#rsvpForm {
width: 600px;
margin: 50px auto;
text-align: center;
position: relative;
}
.form form#rsvpForm fieldset {
background: white;
border: 0 none;
border-radius: 3px;
box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.4);
padding: 60px 50px;
box-sizing: border-box;
position: relative;
width: 100%;
display: block !important;
}
.form form#rsvpForm fieldset:not(:first-of-type) {
opacity: 0;
}
.form form#rsvpForm input,
.form form#rsvpForm textarea {
padding: 15px;
border: 1px solid #ccc;
border-radius: 3px;
margin-bottom: 10px;
width: 100%;
box-sizing: border-box;
outline: none;
}
.form form#rsvpForm input.error,
.form form#rsvpForm textarea.error {
border: 1px solid red;
}
.form form fieldset .error__message {
display: none;
}
.form form fieldset.has-error .error__message {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js?ver=5.3.2'></script>
<script type="text/javascript" src='https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js'></script>
<div class="form" id="rsvp-form">
<form id="rsvpForm" action="" method="post">
<!-- fieldset 1 -->
<fieldset>
<input type="text" name="fname" placeholder="First name*" required />
<textarea name="address" placeholder="Address*" required></textarea>
<input type="button" id="confirm" name="next" class="next" value="Next" />
</fieldset>
<!-- fieldset 2 -->
<fieldset>
<input type="tel" name="phone" placeholder="Phone*" required />
<input type="button" id="confirm1" name="next" class="next" value="Next" />
</fieldset>
<!-- fieldset 3 -->
<fieldset>
<textarea name="other" placeholder="Enter your note here ..." required></textarea>
<input type="button" name="submit" class="next submit" value="Submit" />
</fieldset>
</form>
</div>
我观察到你的电流没有工作,因为你已经给了... display: block !important;
所有字段集,所以当你验证第一个字段集的时候,它也在检查 phone
为了克服这个问题,你可以使用 display:none
中的其他字段组。css
.
您的 submitHandler
没有接到电话,因为你没有点击 submit
按钮,所以里面的代码 submitHandler
没有得到执行.也因为这个字段没有得到验证。我刚刚添加了一个 if (form.valid() === true)
来检查字段集是否有效,根据这一点你可以调用下一个字段集。
所以这就是工作代码。
$(function() {
var current_fs, next_fs, previous_fs;
var left, opacity, scale;
var animating;
$(".next").click(function() {
console.log('next is clicked');
var form = $("#rsvpForm");
// Custom method to validate phone
$.validator.methods.matches = function(value, element, params) {
var re = new RegExp(params); //pass regex
return this.optional(element) || re.test(value); //test value with pattern
}
$("form").validate({
rules: {
fname: "required",
address: "required",
phone: {
required: true,
matches: "^(\\d|\\s)+$",
minlength: 11,
maxlength: 11
}
},
messages: {
fname: "Please enter your firstname",
address: "Please enter your address",
phone: "Please enter a valid phone number"
},
// if validation is correct, animate in next fieldset
submitHandler: function(form) {
console.log("done submit now")
//$("#rsvpForm").submit();
}
});
//checking for each fieldset validation
if (form.valid() === true) {
console.log("validate go to next fieldset")
if (animating) return false;
animating = true;
current_fs = $(this).parent();
next_fs = $(this).parent().next();
$("#progressbar li").eq($("fieldset").index(next_fs)).addClass("active");
next_fs.show();
current_fs.animate({
opacity: 0
}, {
step: function(now, mx) {
scale = 1 - (1 - now) * 0.2;
left = (now * 50) + "%";
opacity = 1 - now;
current_fs.css({
'transform': 'scale(' + scale + ')',
'position': 'absolute'
});
next_fs.css({
'left': left,
'opacity': opacity,
'height': 'auto',
'padding': '60px 50px'
});
},
duration: 800,
complete: function() {
current_fs.hide();
animating = false;
},
easing: 'easeInOutBack'
});
} else {
console.log("not validate")
}
});
});
#b,
#c {
display: none;
/*to hide other fieldset on load*/
}
.form {
min-height: 800px;
user-select: none;
overflow: hidden;
}
.form form#rsvpForm {
width: 600px;
margin: 50px auto;
text-align: center;
position: relative;
}
.form form#rsvpForm fieldset {
background: white;
border: 0 none;
border-radius: 3px;
box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.4);
padding: 60px 50px;
box-sizing: border-box;
position: relative;
width: 100%;
}
.form form#rsvpForm fieldset:not(:first-of-type) {
opacity: 0;
}
.form form#rsvpForm input,
.form form#rsvpForm textarea {
padding: 15px;
border: 1px solid #ccc;
border-radius: 3px;
margin-bottom: 10px;
width: 100%;
box-sizing: border-box;
outline: none;
}
.form form#rsvpForm input.error,
.form form#rsvpForm textarea.error {
border: 1px solid red;
}
.form form fieldset .error__message {
display: none;
}
.form form fieldset.has-error .error__message {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js?ver=5.3.2'></script>
<script type="text/javascript" src='https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js'></script>
<div class="form" id="rsvp-form">
<form id="rsvpForm" action="" method="post">
<!-- fieldset 1 -->
<fieldset id="a">
<input type="text" class="form-control" name="fname" placeholder="First name*" required/>
<textarea name="address" class="form-control" placeholder="Address*" required></textarea>
<input type="button" id="confirm" name="next" class="next" value="Next" />
</fieldset>
<!-- fieldset 2 -->
<fieldset id="b">
<input type="tel" class="form-control" name="phone" placeholder="Phone*" required/>
<input type="button" id="confirm" name="next" class="next" value="Next" />
</fieldset>
<!-- fieldset 3 -->
<fieldset id="c">
<div class="form-group">
<textarea name="other" class="form-control" placeholder="Enter your note here ..."></textarea>
</div>
<input type="submit" name="submit" class="submit" value="Submit" />
</fieldset>
</form>
</div>