【问题标题】:Yii2: how to make bootstrap tab active if there is any yii2 errorYii2:如果有任何 yii2 错误,如何使引导选项卡处于活动状态
【发布时间】:2017-06-14 01:21:52
【问题描述】:

我使用Yii2 创建了一个CRUD。 现在我使用bootstrap 添加了multi-tab http://getbootstrap.com/javascript/#tabs-examples

现在我在required validation 等字段上有一些验证规则。 单击保存按钮时,它会在活动选项卡上显示错误,但如果在非活动选项卡上有任何错误,则不会提交表单。 如果活动选项卡中有任何错误,用户将通过采取适当的措施来纠正它们,但他不会理解其他选项卡上也有任何错误。

所以我想要的是,如果其他选项卡中有任何错误,那么该选项卡将变为活动状态。

如果用户删除活动选项卡上的所有验证错误,然后尝试重新提交表单,那么它将再次移动到包含选项卡的下一个错误。

这是我的表单代码

 <?php $form = ActiveForm::begin(); ?>
    <div class="nav-tabs-horizontal">
    <ul class="nav nav-tabs nav-tabs-line" data-plugin="nav-tabs" role="tablist">
    <li class="active" role="presentation"><a data-toggle="tab" href="#user" arria-controls="user" role="tab">User Details</a></li>
    <li role="presentation"><a data-toggle="tab" href="#company" aria-controls="company" role="tab">Company Details</a></li>
    </ul>

 <div class="tab-content">

     <div class="tab-pane active" id="user" role="tabpanel">
         <div class="form-group form-material">`  
            <?= $form->field($model, 'first_name')->textInput(['placeholder'=>'First Name']); ?>
            </div>
              <div class="form-group form-material">
              <?= $form->field($model, 'last_name')->textInput(['placeholder'=>'Last Name']); ?>
              </div>
              <div class="form-group form-material">
                <?= $form->field($model, 'email')->input('email'); ?>
                </div>
                <div class="form-group form-material">
               <?= $form->field($model, 'password')->passwordInput(['placeholder'=>'Password']);?> 
                </div>
                  <div class="form-group form-material">
                 <?= $form->field($model, 'repeatpassword')->passwordInput(['placeholder'=>'Repeat Password']);?>
                </div> 

      </div>

      <div class="tab-pane" id="company" role="tabpanel">

       <div class="form-group form-material">
        <?= $form->field($company, 'Title')->textInput(['maxlength' => true]); ?>
        </div>

             <div class="form-group form-material">
            <?= $form->field($company, 'Website')->textInput(['maxlength' => true]); ?>
             </div>


              <div class="form-group form-material">
                  <?= $form->field($company, 'Description')->textarea(['rows' => 6]); ?>
               </div>

                <div class="form-group form-material">
                <?= $form->field($company, 'Status')->dropDownList(['Active' =>'Active','Deactive'=>'Deactive','Pending'=>'Pending'],['prompt'=>'']) ?>
                  </div>
          </div>
     </div>

      <?= Html::submitButton("Save", ["class" => "btn btn-success"]); ?>
   </div>
   <?php ActiveForm::end(); ?>

【问题讨论】:

    标签: javascript jquery twitter-bootstrap yii yii2


    【解决方案1】:

    你有三个选择:

    1.不要使用标签

    坦率地说,在需要验证的表单中使用选项卡的想法通常被认为在可用性方面是一个糟糕的选择,因为您正在为已经很复杂的工作增加复杂性:validation
    我不一定要谈论编程逻辑的复杂性,这可能会根据您的表单而变得足够高,而是谈论必须与表单有问题的用户打交道(并集中注意力)所带来的复杂性首先,他们通常是“不那么精通技术”的人

    一个简单的解决方法是将所有表单放入一个可滚动的容器中。

    2。在离开之前分别验证每个选项卡

    这可能是最好的方法。只需在 show.bs.tab 事件和 preventdefault() 上验证当前选项卡中的元素,如果验证失败,则显示错误,(最终)将选项卡滚动到第一个。

    如果你走这条路,你需要将你的验证分成不同的功能,每个标签一个。表单的整体验证将是各个选项卡验证功能的总和。这将使您的用户更容易理解和浏览表单,并且可能会提高表单的整体可用性和成功率。

    唯一的“棘手”部分是确保错误始终滚动到视图中,以防您的标签内容不适合一个屏幕。如果您不这样做,用户可能会尝试更改选项卡但不明白为什么它不起作用,从而使表单看起来损坏。

    3.创建一个“显示第一个错误”函数

    最后一个选项是让您的验证功能找到并激活第一个错误的选项卡。不是最优的,因为很难向用户提供有关总共有多少错误以及他距离实际提交表单还有多远的信息,但这比尝试提交但不知道为什么它不起作用要好。

    根据您的表单的实际标记,这可能会有所不同,但原则上,如果包含表单元素的错误选择器是.x,这应该使其选项卡处于活动状态:
    $('.x').closest('[role="tabpanel"]').tab('show');

    就像选项 2. 一样,如果在激活选项卡时默认情况下看不到错误,则需要格外小心地将错误滚动到视图中。

    【讨论】:

    • 感谢@Andrei Gheorghiu 的回复。我很欣赏你的回答。但是上面的代码只是我整个代码的一部分。我有大量字段,所以我不能使用单个可滚动部分。我附上了一张我的表格输出的图像。请检查并提出更好的选择。我正在使用 Yii2 验证规则,所以我不想编写自己的 js 验证规则,直到它不是最后一个选项。谢谢
    【解决方案2】:

    正如 Andrei 在他的回答中所写,最好的解决方案是在离开之前分别验证每个选项卡。多年来,这是处理它的最佳方法。

    【讨论】:

      【解决方案3】:

      你应该像这样为你的视图注册 JS 文件

      $this->registerJsFile('js/report/index.js', ['depends' => [\yii\web\JqueryAsset::className()]]);
      

      并在此文件中添加 afterValidate() 处理程序(用您的表单 ID 替换 #report-index):

      $('#report-index').on('afterValidate', function(event, messages, errorAttributes){
        if(errorAttributes.length > 0) {
          var errElement = $('#' + errorAttributes[0].id);
          var pane = errElement.closest('[class="tab-pane"]');
          var tabId = pane[0].id;
          $('.nav-tabs a[href="#' + tabId + '"]').tab('show');
          return false;
        }
      });
      

      【讨论】:

      • 感谢您的重播,即使很晚,但真的很感激。我将对此进行测试,并让您知道它是否有效。谢谢
      • @FahadAli,我遇到了同样的问题,在我最终能够在这个主题的帮助下解决它之后,我决定分享我的解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-28
      相关资源
      最近更新 更多