利用JQuery Validate库(在按钮点击时)检查字段集中的输入是否有效,然后在下一个字段集中制作动画。

问题描述 投票:1回答:1

我有一个多形态,它分为三部分。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>
javascript html jquery jquery-validate
1个回答
0
投票

为了实现这个目标,你必须创建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'
      });
  }

});

工作实例。https:/jsfiddle.netmrAhmedkhanpjgz7cwq


0
投票

当点击".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>

0
投票

我观察到你的电流没有工作,因为你已经给了... 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>
© www.soinside.com 2019 - 2024. All rights reserved.