【问题标题】:Multiple form validation issues on submit click提交单击时出现多个表单验证问题
【发布时间】:2020-05-22 16:35:39
【问题描述】:

我有一个包含三个fieldsets 的多步表单。

基本上当用户单击next 按钮时,下一个fieldset 将显示。

但我有两个问题:


1.

我检查fieldset 中的必填字段是否已填写的函数返回false,即使required 字段已填写。

该函数称为checkInputs()#confirm 是我的next 按钮的 ID(完整的工作演示如下):

function checkInputs() {
  var isValid = true;
  $('fieldset').find('[required]').each(function() {
    if ($(this).val() === '') {
      isValid = false;
      return false;
    }
  });
  if (isValid) {
    $('#confirm').prop('disabled', false)
  }
  return isValid;
}

2.

required 字段未填写(没有值)时,我想添加一个简单的红色边框。为了实现这一点,我在next click 上添加了一个类到fieldset 和任何input:required 没有val。

我遇到的问题是:

  1. 如果我运行下面的演示(没有输入)并单击next,我将看到以下内容:

...这是正确的。它显示未填写哪些必需的输入并显示错误消息。但是,它还将这些类添加到那些尚不可见的fieldsetsinputs(它们将在next 点击时可见)。

当然你不能直观地看到这一点,因为我的第一个问题阻止我们进入第二个字段集,但是在这个 fiddle 中,如果你只是点击 next 然后检查表单,你可以看到字段集注释 <!--fieldset 1--><!--fieldset 2--> 现在有了 .has-error 类,它的输入也是如此。

我只想将错误类添加到视图中的字段集中。

还想知道是否可以动态添加和删除类?例如,如果inputs 之一有错误(因此是红色边框),一旦用户填写它,删除分配红色边框的那个类(在填写后,您必须单击@ 987654346@ 再次删除)。


完整演示:

jQuery(function($) {

  var current_fs, next_fs, previous_fs; //fieldsets
  var left, opacity, scale;
  var animating;

  /*************************************************/
  // CHECK IF FIELDS ARE FILLED IN BEFORE NEXT CLICK
  /**************************************************/

  function checkInputs() {
    var isValid = true;
    $('fieldset').find('[required]').each(function() {
      if ($(this).val() === '') {
        isValid = false;
        return false;
      }
    });
    if (isValid) {
      $('#confirm').prop('disabled', false)
    }
    return isValid;
  }


  /***********************************************/
  // ONCLICK NEXT BUTTON, ANIMATE IN NEXT FIELDSET
  /***********************************************/

  $(".next").click(function() {

    checkInputs();

    if (checkInputs() == false) {
      
      console.log('required fields in this fieldset are not filled in.');
      
      
      // highlight invalid fields 
		  	$("fieldset").find(":required").filter(function() {
		   		if( $(this).val().length === 0 ) {
		     		$(this).addClass("error");
		   		} else {
		   			$(this).removeClass("error");
		   		}
			});

			// add class to fieldset on error
		 	$('fieldset input').each(function() {
		   		if (!$(this).val()) {
		    		$(this).parents('fieldset').addClass('has-error');
		   		}
          /* else{
                       $(this).parents('fieldset').removeClass('has-error');
                     } */

		  	});
      
      
    } else {
    	console.log('all required fields are filled in, moving onto next fieldset');
      
     
     if (animating) return false;
      animating = true;
      current_fs = $(this).parent();
      next_fs = $(this).parent().next();

      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
          });
        },
        duration: 800,
        complete: function() {
          current_fs.hide();
          animating = false;
        },
        easing: 'easeInOutBack'
      });
    } // else close
  });




});
.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>

<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" />
      <div class="error__message"><p>Please complete all required fields.</p></div>
    </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 forms


    【解决方案1】:

    如果您在checkInputs() 函数和.next click 事件处理程序中使用opacity=1 过滤输入元素,它会起作用,因此只有当前可见的输入元素会受到影响。

    jQuery(function($) {
    
      var current_fs, next_fs, previous_fs; //fieldsets
      var left, opacity, scale;
      var animating;
    
      /*************************************************/
      // CHECK IF FIELDS ARE FILLED IN BEFORE NEXT CLICK
      /**************************************************/
    
      function checkInputs() {
        var isValid = true;
        $('fieldset').filter(function() {
          return $(this).css('opacity') == '1';
        }).find('[required]').each(function() {
          if ($(this).val() === '') {
            isValid = false;
            return false;
          }
        });
        if (isValid) {
          $('#confirm').prop('disabled', false)
        }
        return isValid;
      }
    
    
      /***********************************************/
      // ONCLICK NEXT BUTTON, ANIMATE IN NEXT FIELDSET
      /***********************************************/
    
      $(".next").click(function() {
    
        checkInputs();
    
        if (checkInputs() == false) {
    
          console.log('required fields in this fieldset are not filled in.');
    
    
          // highlight invalid fields 
          $('fieldset').filter(function() {
            return $(this).css('opacity') == '1';
          }).find(":required").filter(function() {
            if ($(this).val().length === 0) {
              $(this).addClass("error");
            } else {
              $(this).removeClass("error");
            }
          });
    
          // add class to fieldset on error
          $('fieldset input').each(function() {
            if (!$(this).val()) {
              $(this).parents('fieldset').addClass('has-error');
            }
            /* else{
                         $(this).parents('fieldset').removeClass('has-error');
                       } */
    
          });
    
    
        } else {
          console.log('all required fields are filled in, moving onto next fieldset');
    
    
          if (animating) return false;
          animating = true;
          current_fs = $(this).parent();
          next_fs = $(this).parent().next();
    
          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
              });
            },
            duration: 800,
            complete: function() {
              current_fs.hide();
              animating = false;
            },
            easing: 'easeInOutBack'
          });
        } // else close
      });
    
    
    
    
    });
    .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>
    
    <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" />
          <div class="error__message"><p>Please complete all required fields.</p></div>
        </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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-26
      • 2021-05-10
      • 2019-12-10
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多