【问题标题】:Cannot validate single tab per time每次无法验证单个选项卡
【发布时间】:2019-08-21 15:16:07
【问题描述】:

我已经使用BootstrapWizard 创建了一个向导,但我需要在保存之前确认输入。在我填写第一个选项卡的那一刻,我实际上无法转到下一个选项卡,因为valid() 方法将返回 false。

valid() 方法的结果是正确的,因为其他选项卡上还有其他输入,但我无权访问该选项卡控件,因为我在第一个选项卡上。

为了澄清,我创建了一个fiddler

基本上当您填写第一个选项卡,然后单击下一步按钮时,您将从valid() 收到false,因为未填写下一个选项卡中存在的所需控件,但我不能填充。

有没有办法解决这个问题?

代码:

<div class="wizard-container">
  <form id="member-form" method="get" action="" class="form-horizontal">
    <div class="card card-wizard card-wizard-borderless active" data-color="rose">
      <div class="wizard-navigation">
        <ul>
          <li><a href="#tab1" data-toggle="tab">First</a></li>
          <li><a href="#tab2" data-toggle="tab">Second</a></li>
          <li><a href="#tab3" data-toggle="tab">Third</a></li>
        </ul>
      </div>
      <div class="tab-content">
        <div class="tab-pane active" id="tab1">
          <div class="control-group">
            <label class="control-label" for="email">Email</label>
            <div class="controls">
              <input type="text" id="emailfield" name="first_name" class="control-form">
            </div>
          </div>

          <div class="control-group">
            <label class="control-label" for="name">Name</label>
            <div class="controls">
              <input type="text" id="namefield" name="last_name" class="control-form">
            </div>
          </div>
        </div>
        <div class="tab-pane" id="tab2">
          <div class="control-group">
            <label class="control-label" for="url">URL</label>
            <div class="controls">
              <input type="text" id="urlfield" name="state" class="control-form">
            </div>
          </div>
        </div>
        <div class="tab-pane" id="tab3">
          3
        </div>
        <div class="card-footer">
          <div class="mr-auto">
            <input type="button" class="btn btn-previous btn-fill btn-default btn-wd disabled" name="previous" value="previous">
          </div>
          <div class="ml-auto">
            <input type="button" class="btn btn-next btn-fill btn-rose btn-wd" name="next" value="next">
            <input type="button" id="save-member" class="btn btn-finish btn-fill btn-rose btn-wd" name="finish" value="save" style="display: none;">
          </div>
          <div class="clearfix"></div>
        </div>
      </div>
    </div>
  </form>
</div>

$(document).ready(function() {
    $('#member-form').validate({
    ignore: '.ignore',
    rules: {
      first_name: "required",
      last_name: "required",
      state: "required"
    }
  });

  $('.card-wizard').bootstrapWizard({
    'tabClass': 'nav nav-pills',
    'nextSelector': '.btn-next',
    'previousSelector': '.btn-previous',

    onNext: function(tab, navigation, index) {

      let valid = $('#member-form').valid();
      if (!valid) {
        return false;
      }
    }
  });
});

【问题讨论】:

    标签: jquery bootstrap-4 twitter-bootstrap-wizard


    【解决方案1】:

    你得到这个是因为 jQuery 验证插件试图验证你提供的所有输入,包括你无法到达的 URL 输入,所以你总是会得到一个 false 结果阻止你到达URL 输入所在的下一个选项卡。

    jQuery 验证插件提供了一种单独检查每个输入的方法,而不是一次检查整个表单的输入,更多信息here

    因此,从那里开始,我修改了您的一些代码以使其按您的预期工作,我评论了一些行来解释它是如何工作的:

    $(document).ready(function() {
      var validator = $('#member-form').validate({
        ignore: '.ignore',
        rules: {
          first_name: "required",
          last_name: "required",
          state: "required"
        }
      });
    
      $('.card-wizard').bootstrapWizard({
        'tabClass': 'nav nav-pills',
        'nextSelector': '.btn-next',
        'previousSelector': '.btn-previous',
    
        onNext: function(tab, navigation, index) {
          let tab_id = tab.children().attr('href'); //we select the current's tab ID
          let inputs = $(tab_id).find('input'); //we fetch the current's tab inputs
          var fail = false; //we initalize fail validation variable
          //we loop through each of the inputs to validate them
          $(inputs).each(function(key, val) {
            if (!validator.element(val)) {
              fail = true;
            }
          });
    
          //if fail equals true it means at least one input failed to get validated thus we stop the script from executing further
          if (fail) {
            return false;
          }
        }
      });
    });
    

    下面的工作演示:

    $(document).ready(function() {
      var validator = $('#member-form').validate({
        ignore: '.ignore',
        rules: {
          first_name: "required",
          last_name: "required",
          state: "required"
        }
      });
    
      $('.card-wizard').bootstrapWizard({
        'tabClass': 'nav nav-pills',
        'nextSelector': '.btn-next',
        'previousSelector': '.btn-previous',
    
        onNext: function(tab, navigation, index) {
          let tab_id = tab.children().attr('href'); //we select the current's tab ID
          let inputs = $(tab_id).find('input'); //we fetch the current's tab inputs
          var fail = false; //we initalize fail validation variable
          //we loop through each of the inputs to validate them
          $(inputs).each(function(key, val) {
            if (!validator.element(val)) {
              fail = true;
            }
          });
    
          //if fail equals true it means at least one input failed to get validated thus we stop the script from executing further
          if (fail) {
            return false;
          }
        },
        onTabClick: function(tab, navigation, index, tabIndex) {
          let tab_id = tab.children().attr('href'); //we select the current's tab ID
          let inputs = $(tab_id).find('input'); //we fetch the current's tab inputs
          var fail = false; //we initalize fail validation variable
          //we loop through each of the inputs to validate them
          $(inputs).each(function(key, val) {
            if (!validator.element(val)) {
              fail = true;
            }
          });
          //if the clicked tab is the third one, we check all previous tabs input fields for validation
          if (tabIndex == 2) {
            $('#tab1, #tab2').find('input').each(function(key, val) {
              if (!validator.element(val)) {
                fail = true;
              }
            });
          }
          //if fail equals true it means at least one input failed to get validated thus we stop the script from executing further
          if (fail) {
            return false;
          }
        }
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap-wizard/1.2/jquery.bootstrap.wizard.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.min.js"></script>
    
    <div class="wizard-container">
      <form id="member-form" method="get" action="" class="form-horizontal">
        <div class="card card-wizard card-wizard-borderless active" data-color="rose">
          <div class="wizard-navigation">
            <ul>
              <li><a href="#tab1" data-toggle="tab">First</a></li>
              <li><a href="#tab2" data-toggle="tab">Second</a></li>
              <li><a href="#tab3" data-toggle="tab">Third</a></li>
            </ul>
          </div>
          <div class="tab-content">
            <div class="tab-pane active" id="tab1">
              <div class="control-group">
                <label class="control-label" for="email">Email</label>
                <div class="controls">
                  <input type="text" id="emailfield" name="first_name" class="control-form">
                </div>
              </div>
    
              <div class="control-group">
                <label class="control-label" for="name">Name</label>
                <div class="controls">
                  <input type="text" id="namefield" name="last_name" class="control-form">
                </div>
              </div>
            </div>
            <div class="tab-pane" id="tab2">
              <div class="control-group">
                <label class="control-label" for="url">URL</label>
                <div class="controls">
                  <input type="text" id="urlfield" name="state" class="control-form">
                </div>
              </div>
            </div>
            <div class="tab-pane" id="tab3">
              3
            </div>
            <div class="card-footer">
              <div class="mr-auto">
                <input type="button" class="btn btn-previous btn-fill btn-default btn-wd disabled" name="previous" value="previous">
              </div>
              <div class="ml-auto">
                <input type="button" class="btn btn-next btn-fill btn-rose btn-wd" name="next" value="next">
                <input type="button" id="save-member" class="btn btn-finish btn-fill btn-rose btn-wd" name="finish" value="save" style="display: none;">
              </div>
              <div class="clearfix"></div>
            </div>
          </div>
        </div>
      </form>
    </div>

    希望这会有所帮助。

    【讨论】:

    • 我很欣赏你的回答,但为什么我在 codepen 上找到的这个解决方案有效:codepen.io/makshh/pen/dOQyqJ?editors=1010 而我的不是?有什么区别?
    • 是的,在我之前的消息中,我指的是选项卡单击不起作用,因为您也必须编写选项卡单击方法,因此我相应地更新了我的代码以使其在选项卡单击时工作。
    • @tjc 不,错误仍然存​​在,如果您填写第一个选项卡然后单击第三个选项卡,您会看到您可以跳过选项卡 2,这很糟糕,因为选项卡 2 需要也验证..
    • 知道了,等几分钟我会解决的。
    • Bug 修复,检查更新代码,我已经注释了添加的代码行。
    猜你喜欢
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多