jQuery 针对 Twitter bootstrap 带有隐藏输入的按钮组进行验证

jQuery validation against twitter bootstrap button group with hidden input

我有一个使用 Bootstrap 向导的 PHP 数据输入页面,现在我正在使用 jQuery Validate 添加一些数据验证。

我已经让基本类型字段正常工作,只需使用 "required" 属性即可。

但是向导的最后 9 个选项卡 "btn-groups" 不是输入类型,因此没有此功能。为了解决之前的问题(老实说这似乎很常见),我添加了一个 "hidden" 输入字段,当 btn-group 更改时,它会设置隐藏字段的值。

但我无法对 btn 组或隐藏字段执行验证。

我看到了以下线程的第一个解决方案:

Similar Issue

这看起来很完美。但是,当我将它插入我的站点时,如果我不预先设置初始值 (然后破坏了验证测试!)。

目前,代码如下所示。在第一个分数选项卡 "hole1score" 中,我删除了 'value="0"' 并添加了 "required",因此它得到了验证。所有其他选项卡都具有将值预设为 0 的原始语法。如果我可以在向导中通过此页面,我会将其应用于所有选项卡。

<head>
    <!-- THERE IS SOME MORE CODE ABOVE, BUT JUST THE USUAL IMPORTING FILES -->

    <!-- Include jQuery Validate -->
    <script src="../js/jquery.validate.min.js"></script>

    <!-- Include Bootstrap Wizard -->
    <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap-wizard/1.2/jquery.bootstrap.wizard.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js"></script>
    <script>
        $(document).ready(function() {
            var $validator = $("#entry_form").validate({
              ignore: [],
              rules: {
                firstname: {
                  required: true,
                }
              },
              messages: {
                hcap: "A number is required"
              }
            }); 

            $('#rootwizard').bootstrapWizard({
                'tabClass': 'nav nav-pills',
                'onNext': function(tab, navigation, index) {
                    //if(index>=2) {
                    //  //alert($('#hole1score').val());
                    //}

                    var $valid = $("#entry_form").valid();
                    if(!$valid) {
                        $validator.focusInvalid();
                        return false;
                    }
                }
            });



            $('#rootwizard').bootstrapWizard({onTabShow: function(tab, navigation, index) {
                var $total = navigation.find('li').length;
                var $current = index+1;
                var $percent = ($current/$total) * 100;

                $('#rootwizard .progress-bar').css({width:$percent+'%'});

                // If it's the last tab then hide the last button and show the finish instead
                if($current >= $total) {
                    $('#rootwizard').find('.pager .next').hide();
                    $('#rootwizard').find('.pager .finish').show();
                    $('#rootwizard').find('.pager .finish').removeClass('disabled');
                } else {
                    $('#rootwizard').find('.pager .next').show();
                    $('#rootwizard').find('.pager .finish').hide();
                }
            }});

            $(".btn-group :input").change(function() {
                $('input[name="' + $(this).parent().parent().attr('id') + '"]').val($(this).val());
            }); 
        });
    </script>
    <script>
      function selectPlayer(myForm)
      {
        var jplayerid = myForm.playerlist.options[myForm.playerlist.selectedIndex].value;
        var jplayername = myForm.playerlist.options[myForm.playerlist.selectedIndex].text;
        var jplayernames = jplayername.split(" ");
        myForm.firstname.value = jplayernames[0];
        myForm.lastname.value = jplayernames[1];
      }
    </script>
</head>

<body>

            <div id="rootwizard">

                <div class="row">
                    <div class="col-xs-12 col-sm-12">
                        <div class="navbar">
                            <div class="navbar-inner">
                                <ul>
                                    <li><a href="#tab1" data-toggle="tab">Info</a></li>
                                    <li><a href="#tab2" data-toggle="tab">1st</a></li>
                                    <li><a href="#tab3" data-toggle="tab">2nd</a></li>
                                    <li><a href="#tab4" data-toggle="tab">3rd</a></li>
                                    <li><a href="#tab5" data-toggle="tab">4th</a></li>
                                    <li><a href="#tab6" data-toggle="tab">5th</a></li>
                                    <li><a href="#tab7" data-toggle="tab">6th</a></li>
                                    <li><a href="#tab8" data-toggle="tab">7th</a></li>
                                    <li><a href="#tab9" data-toggle="tab">8th</a></li>
                                    <li><a href="#tab10" data-toggle="tab">9th</a></li>
                                </ul>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="row">
                    <div class="col-xs-12">
                        <div id="bar" class="progress progress-striped active">
                            <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>
                        </div>  
                    </div>              
                </div>

                <form action="" method="post" class="form" role="form" name="entry_form" id="entry_form" autcomplete="on">
                    <div class="tab-content">
                        <div class="tab-pane" id="tab1">

                            <div class="row">
                                <div class="col-xs-12">
                                    <label for="">Name</label>
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-xs-12 col-sm-6 col-md-4">
                                    <select class="form-control" name="playerlist" id="playerlist" onchange="selectPlayer(this.form)">
                                        <option value="" selected>Select Name or Type New Name</option>
                                        <?php
                                            $player_list = get_players();
                                            echo $player_list;
                                        ?>
                                    </select>
                                    <br>                                    
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-xs-6 col-sm-3 col-md-2">
                                    <input class="form-control" id="firstname" name="firstname" type="text" required />
                                </div>
                                <div class="col-xs-6 col-sm-3 col-md-2">
                                    <input class="form-control" id="lastname" name="lastname" type="text" required />
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-xs-12">
                                    <br>
                                    <label for="">HCap and Nine</label>
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-xs-6 col-sm-3 col-md-2">
                                    <input class="form-control" name="hcap" placeholder="HCap" type="number" required />
                                </div>
                                <div class="col-xs-6 col-sm-3 col-md-2">
                                    <select name="nine" class="form-control" required>
                                        <option value="">Select Nine</option>
                                        <option value="1">Low</option>
                                        <option value="2">Middle</option>
                                        <option value="3">High</option>
                                    </select>
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-xs-12">
                                    <br>
                                    <label for="">Date Played</label>
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-xs-12 col-sm-6 col-md-4">
                                    <div class="col-xs-4">
                                        <select class="form-control" name="dateday">
                                            <?php
                                                for ($x = 1; $x <= 31; $x++) {
                                                    if ($todayday==$x){
                                                        $dynday .= '<option value='.$x.' selected>'.$x.'</option>';
                                                    } else {
                                                        $dynday .= '<option value='.$x.'>'.$x.'</option>';
                                                    }
                                                ;
                                                }
                                                echo $dynday;
                                            ?>
                                        </select>
                                    </div>
                                    <div class="col-xs-4">
                                        <select class="form-control" name="datemonth">
                                            <?php
                                                for ($x = 1; $x <= 12; $x++) {
                                                    if ($todaymonth==$x){
                                                        $dynmonth .= '<option value='.$x.' selected>'.$x.'</option>';
                                                    } else {
                                                        $dynmonth .= '<option value='.$x.'>'.$x.'</option>';
                                                    }
                                                };
                                                echo $dynmonth;
                                            ?>
                                        </select>
                                    </div>
                                    <div class="col-xs-4">
                                        <select class="form-control" name="dateyear">
                                            <?php
                                                $dynyear = '<option value='.$todayyear.' selected>'.$todayyear.'</option>';
                                                echo $dynyear;
                                            ?>
                                        </select>
                                        <br>
                                    </div>
                                </div>
                            </div>                              

                        </div>

                        <div class="tab-pane" id="tab2">

                            <div class="row">
                                <div class="col-xs-12">
                                    <label for="">HOLE 1 Gross Score</label>                                        
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-xs-12 col-sm-9">
                                    <div class="btn-group btn-group-justified" data-toggle="buttons" id="hole1score">
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="0"> Blob
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="2">2
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="3">3
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="4">4
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="5">5
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="6">6
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="7">7
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="8">8
                                        </label>
                                        <input type="hidden" name="hole1score" required>
                                    </div>

                                </div>                              
                            </div>
                        </div>

                        <div class="tab-pane" id="tab3">

                            <div class="row">
                                <div class="col-xs-12">
                                    <label for="">HOLE 2 Gross Score</label>                                        
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-xs-12 col-sm-9">
                                    <div class="btn-group btn-group-justified" data-toggle="buttons" id="hole2score">
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="0"> Blob
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="2">2
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="3">3
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="4">4
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="5">5
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="6">6
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="7">7
                                        </label>
                                        <label class="btn btn-primary btn-responsive">
                                            <input type="radio" autocomplete="off" value="8">8
                                        </label>
                                        <input type="hidden" name="hole2score" value="0">
                                    </div>

                                </div>                              
                            </div>
                        </div>

                            <div class="row">
                                <br>
                                <div class="col-xs-4 col-xs-offset-8 col-sm-2 col-sm-offset-7 col-md-offset-8">
                                    <button name="submit" class="btn btn-responsive btn-success" type="submit">Submit</button>                              
                                </div>
                            </div>
                        </div>

                        <div class="row">
                            <div class="col-xs-12">
                                <ul class="pager wizard">
                                    <li class="previous first"><a href="javascript:;">First</a></li>
                                    <li class="previous first" style="display:none;"><a href="#">First</a></li>
                                    <li class="previous"><a href="#">Previous</a></li>
                                    <li class="next last" style="display:none;"><a href="#">Last</a></li>
                                    <li class="next"><a href="#">Next</a></li>
                                    <li class="next finish" style="display:none;"><a href="javascript:;">Finish</a></li>
                                </ul>                               
                            </div>
                        </div>                          

                    </div>
                </form>


            </div>


</body>

如有任何帮助,我们将不胜感激

answer you linked to 试图通过侦听按钮上的更改并填充隐藏字段来解决问题,以便 jQuery Validate 可以验证一些东西。但是,有一种更简单的方法可以使用库中已有的本机功能来执行此操作。

Bootstrap的按钮组只是对input[type=radio]的css包装,让它看起来更漂亮,你可以easily require radio buttons这样:

myRadioGroupName: { required: true}

或者这个:

<input type="radio" name="myRadioGroupName" value="0" required>  1
<input type="radio" name="myRadioGroupName" value="1" > 2
<input type="radio" name="myRadioGroupName" value="2" > 3

Note: Make sure you name all radio button groups. This ensures the radio buttons work properly in all browsers and that they post back a value with the form correctly.

现在 jQuery Validate 会自动为您的组提供字段验证消息,但您可能希望将它们移到单选按钮组之外。您可以 customize their placement 像这样:

<label for="myRadioGroupName" generated="true" class="error"></label>

这是 Stack Snippets 中的一个演示

$(function() { 

  $("#test-form").validate({  
    ignore: [],
    rules: {
      first_name: { 
        required: true
      },
      hole1score: {
        required: true
      }
    }
  });
});
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

<form id="test-form" action="post.php">
  <input type="text" name="first_name" class="form-control" required /><br/>
  
  <div class="btn-group btn-group-justified" data-toggle="buttons" id="hole1score">
    <label class="btn btn-primary btn-responsive">
      <input type="radio" autocomplete="off" name="hole1score" value="1" >1
    </label>
    <label class="btn btn-primary btn-responsive">
      <input type="radio" autocomplete="off" name="hole1score" value="2" >2
    </label>
    <label class="btn btn-primary btn-responsive">
      <input type="radio" autocomplete="off" name="hole1score" value="3">3
    </label>
  </div>

  <label for="hole1score" generated="true" class="error"></label><br/>
  
  <input type="submit" />
</form>

您需要验证的每个 input 元素 必须 包含唯一的 name 属性,否则 jQuery 验证插件将忽略它。

<div class="row">
    <div class="col-xs-12 col-sm-9">
        <div class="btn-group btn-group-justified" data-toggle="buttons" id="hole2score">
            <label class="btn btn-primary btn-responsive">
                <input type="radio" autocomplete="off" value="0"> Blob
            </label>
            <label class="btn btn-primary btn-responsive">
                <input type="radio" autocomplete="off" value="2">2
            </label>....

radiocheckbox 元素的情况下,当它们属于单个输入组时,它们共享相同的 name...

<input type="radio" autocomplete="off" value="0" name="foo">
<input type="radio" autocomplete="off" value="2" name="foo">
<input type="radio" autocomplete="off" value="3" name="foo"> ....

I saw the first solution to the following thread: Similar Issue

这个问题实际上与你的问题无关。他们正在尝试将验证应用于 <button> 元素,not jQuery 验证插件可以处理的元素种类。 <button> 也不是 "data input" 元素,所以不确定为什么首先需要对其进行验证。

jQuery 验证插件只能验证 input(某些类型包括 radio)、selecttextarea 元素。因为你想验证 <input type="radio"> 元素,插件可以很好地处理这些,默认情况下,没有任何特殊的事件处理程序或隐藏元素。