如何验证 twitter 引导表单向导

Posted

技术标签:

【中文标题】如何验证 twitter 引导表单向导【英文标题】:How to validate a twitter bootstrap form wizard 【发布时间】:2013-05-24 10:00:04 【问题描述】:

我正在使用 twitter 引导程序,并希望将表单向导与验证结合起来。但是在尝试了很多表单向导和验证后,下一个按钮不起作用。我在哪里犯错。我的编码如下

<div class="portlet-body form">
                        <form action="#" id="form_sample_2" class="form-horizontal">
                           <div class="form-wizard">
                              <div class="navbar steps">
                                 <div class="navbar-inner">
                                    <ul class="row-fluid nav nav-pills">
                                       <li class="span3 active">
                                          <a href="#tab1" data-toggle="tab" class="step active">
                                          <span class="number">1</span>
                                          <span class="desc"> Registration</span>   
                                          </a>
                                       </li>
                                       <li class="span3">
                                          <a href="#tab2" data-toggle="tab" class="step">
                                          <span class="number">2</span>
                                          <span class="desc"> Review Application</span>   
                                          </a>
                                       </li>
                                     </ul>
                                 </div>
                              </div>
                              <div id="bar" class="progress progress-success progress-striped">
                                 <div class="bar" style="width: 25%;"></div>
                              </div>
                              <div class="tab-content background-color-blue">
                                 <div class="tab-pane active" id="tab1">
                                    <h3 class="block">Registration</h3>
                                    <div class="control-group">
                                       <label class="control-label">UserName:</label>
                                       <div class="controls span8">
                                          <input type="text" data-required="1" name="username" id="username" value="user" class="span6 m-wrap">
                                          <span class="help-inline">UsernameTip</span>
                                       </div>
                                    </div>
                                    <div class="control-group">
                                       <label class="control-label">PassWord:</label>
                                       <div class="controls span8">
                                          <input type="password" data-required="1" name="password" id="password" value="password" class="span6 m-wrap">
                                          <span class="help-inline">L_PassWordTip</span>
                                       </div>
                                    </div>
                                    <div class="control-group">
                                       <label class="control-label">ConfirmPassWord:</label>
                                       <div class="controls span8">
                                          <input type="password" data-required="1" name="password2" id="password2" value="password2" class="span6 m-wrap">
                                          <span class="help-inline">ConfirmPassWordTip</span>
                                       </div>
                                    </div>                                
                                 </div>
                                 <div class="tab-pane" id="tab2">
                                    <h3 class="block">AppReview</h3>
                                     <div class="control-group">
                                       <label class="control-label">Entered UserName:</label>
                                       <div class="controls span8">
                                          <span class="text" id="username_pr"></span>
                                       </div>
                                     </div>
                                    <div class="control-group">
                                       <label class="control-label">Entered PassWord:</label>
                                       <div class="controls span8">
                                          <span class="text">**Hidden**</span>
                                       </div>
                                    </div>
                              </div>
                              <div class="clearfix">
                                 <a href="javascript:;" class="btn btn-large btn-info button-previous" style="display: none;">
                                 <i class="m-icon-swapleft m-icon-white"></i> Back 
                                 </a>
                                 <a href="javascript:;" onclick="submit" class="btn btn-large btn-info button-next">
                                 Continue <i class="m-icon-swapright m-icon-white"></i>
                                 </a>
                                 <a href="javascript:;" class="btn btn-large btn-success button-submit" style="display: none;">
                                 Submit <i class="m-icon-swapright m-icon-white"></i>
                                 </a>
                              </div>
                           </div>
                        </form>
                     </div>

<script type="text/javascript">
var FormWizard = function () 


    return 
        //main function to initiate the module
        init: function () 
            if (!jQuery().bootstrapWizard) 
                return;
            

            // default form wizard
            $('#form_sample_2').bootstrapWizard(
                'nextSelector': '.button-next',
                'previousSelector': '.button-previous',
                onTabClick: function (tab, navigation, index) 
                    alert('on tab click disabled');
                    return false;
                ,

                onNext: function (tab, navigation, index) 
                    var total = navigation.find('li').length;
                    var current = index + 1;
                    // set wizard title
                    $('.step-title', $('#form_sample_2')).text('Step ' + (index + 1) + ' of ' + total);
                    // set done steps
                    jQuery('li', $('#form_sample_2')).removeClass("done");
                    var li_list = navigation.find('li');
                    for (var i = 0; i < index; i++) 
                        jQuery(li_list[i]).addClass("done");
                    

                    if (current == 1) 
                        $('#form_sample_2').find('.button-previous').hide();
                     else 
                        $('#form_sample_2').find('.button-previous').show();
                    

                    if (current >= total) 
                        $('#form_sample_2').find('.button-next').hide();
                        $('#form_sample_2').find('.button-submit').show();
                     else 
                        $('#form_sample_2').find('.button-next').show();
                        $('#form_sample_2').find('.button-submit').hide();
                    
                    App.scrollTo($('.page-title'));
                ,
                onPrevious: function (tab, navigation, index) 
                    var total = navigation.find('li').length;
                    var current = index + 1;
                    // set wizard title
                    $('.step-title', $('#form_sample_2')).text('Step ' + (index + 1) + ' of ' + total);
                    // set done steps
                    jQuery('li', $('#form_sample_2')).removeClass("done");
                    var li_list = navigation.find('li');
                    for (var i = 0; i < index; i++) 
                        jQuery(li_list[i]).addClass("done");
                    

                    if (current == 1) 
                        $('#form_sample_2').find('.button-previous').hide();
                     else 
                        $('#form_sample_2').find('.button-previous').show();
                    

                    if (current >= total) 
                        $('#form_sample_2').find('.button-next').hide();
                        $('#form_sample_2').find('.button-submit').show();
                     else 
                        $('#form_sample_2').find('.button-next').show();
                        $('#form_sample_2').find('.button-submit').hide();
                    

                    App.scrollTo($('.page-title'));
                ,
                onTabShow: function (tab, navigation, index) 
                    var total = navigation.find('li').length;
                    var current = index + 1;
                    var $percent = (current / total) * 100;
                    $('#form_sample_2').find('.bar').css(
                        width: $percent + '%'
                    );
                
            );

            $('#form_sample_2').find('.button-previous').hide();
            $('#form_sample_2 .button-submit').click(function () 
                alert('Finished! Hope you like it :)');
            ).hide();
        

    ;

();
</script>

<script type="text/javascript">
var FormValidation = function () 


    return 
        //main function to initiate the module
        init: function () 

            //Sample 2
            var form2 = $('#form_sample_2');
            var error2 = $('.alert-error', form2);
            var success2 = $('.alert-success', form2);
            form2.validate(
                errorElement: 'span', //default input error message container
                errorClass: 'help-inline', // default input error message class
                focusInvalid: false, // do not focus the last invalid input
                ignore: "",
                rules: 
                    username: 
                        minlength: 5,
                        maxlength: 32,
                        required: true
                    ,
                    password:
                        minlength: 4,
                        maxlength: 32,
                        required:true
                    ,
                    password2:
                        required:true,
                        equalTo:password
                    ,
                ,


                errorPlacement: function (error, element)  // render error placement for each input type
                        error.insertAfter(element); // for other inputs, just perform default behavoir
                ,

                invalidHandler: function (event, validator)  //display error alert on form submit   
                    success2.hide();
                    error2.show();
                    App.scrollTo(error2, -200);
                ,

                highlight: function (element)  // hightlight error inputs
                    $(element)
                        .closest('.help-inline').removeClass('ok'); // display OK icon
                    $(element)
                        .closest('.control-group').removeClass('success').addClass('error'); // set error class to the control group

                ,

                unhighlight: function (element)  // revert the change dony by hightlight
                    $(element)
                        .closest('.control-group').removeClass('error'); // set error class to the control group
                ,

                success: function (label) 
                        label
                        .addClass('valid').addClass('help-inline ok') // mark the current input as valid and display OK icon
                        .closest('.control-group').removeClass('error').addClass('success'); // set success class to the control group
                ,

                submitHandler: function (form) 
                    success2.show();
                    error2.hide();
                

            );

        

    ;

();
</script>


<script src="js/chosen.jquery.min.js"></script>
<script src="js/plugins/wizard-master/jquery.bootstrap.wizard.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/jquery.validate.min.js"></script>

【问题讨论】:

我的目标:如果当前步骤中的任何字段无效,则阻止向导转移到下一个选项卡。允许用户修复所有无效字段,然后才能继续下一步。 【参考方案1】:

分配一个id给

<div class="form-wizard" id="form2_steps">

并将 $('#form_sample_2').bootstrapWizard 替换为 $('#form2_steps').bootstrapWizard 和其他有这个“form2_steps” 之后:onNext:函数(选项卡、导航、索引) 添加此编码:

var $valid = $("#form_sample_2").valid();
                if(!$valid) 
                    form2.focusInvalid();
                    return false;
                 

组合脚本中的完整解决方案在这里:

<script type="text/javascript">         
var FormValidation = function () 

    return         
        init: function () 
                //Sample 2
                var form2 = $('#form_sample_2');
                var error2 = $('.alert-error', form2);
                var success2 = $('.alert-success', form2);

                form2.validate(
                errorElement: 'span', //default input error message container
                focusInvalid: true, // do not focus the last invalid input
                ignore: ':hidden',
                rules: 
                    username: 
                        minlength: 5,
                        maxlength: 32,
                        required: true
                    ,
                    password:
                        minlength: 4,
                        maxlength: 32,
                        required:true
                    ,
                    password2:
                        required:true,
                        equalTo:password
                    ,
                ,


                errorPlacement: function (error, element)  // render error placement for each input type
                        error.insertAfter(element); // for other inputs, just perform default behavoir
                ,

                invalidHandler: function (event, validator)  //display error alert on form submit   
                    success2.hide();
                    error2.show();
                    App.scrollTo(error2[0], -200);
                ,

                highlight: function (element)  // hightlight error inputs
                    $(element)
                        .closest('.help-inline').removeClass('ok'); // display OK icon
                    $(element)
                        .closest('.control-group').removeClass('success').addClass('error'); // set error class to the control group

                ,

                unhighlight: function (element)  // revert the change dony by hightlight
                    $(element)
                        .closest('.control-group').removeClass('error'); // set error class to the control group
                ,

                success: function (label) 
                        label
                        .addClass('valid').addClass('help-inline ok') // mark the current input as valid and display OK icon
                        .closest('.control-group').removeClass('error').addClass('success'); // set success class to the control group
                ,

                submitHandler: function (form) 
                    success2.show();
                    error2.hide();
                

            );

        

    ;

();

var FormWizard = function () 


    return 
        //main function to initiate the module
        init: function () 
            if (!jQuery().bootstrapWizard) 
                return;
            

            // default form wizard
            $('#form2_steps').bootstrapWizard(
                'nextSelector': '.button-next',
                'previousSelector': '.button-previous',
                onTabClick: function (tab, navigation, index) 
                    alert('on tab click disabled');
                    return false;
                ,

                onNext: function (tab, navigation, index) 
                    var $valid = $("#form_sample_2").valid();
                    if(!$valid) 
                        form2.focusInvalid();
                        return false;
                                        
                    var total = navigation.find('li').length;
                    var current = index + 1;

                    // set wizard title
                    $('.step-title', $('#form2_steps')).text('Step ' + (index + 1) + ' of ' + total);
                    // set done steps
                    jQuery('li', $('#form2_steps')).removeClass("done");
                    var li_list = navigation.find('li');
                    for (var i = 0; i < index; i++) 
                        jQuery(li_list[i]).addClass("done");
                    
                    // Make sure we entered the name

                    if (current == 1) 
                        $('#form2_steps').find('.button-previous').hide();
                     else 
                        $('#form2_steps').find('.button-previous').show();
                    

                    if (current >= total) 
                        $('#form2_steps').find('.button-next').hide();
                        $('#form2_steps').find('.button-submit').show();
                     else 
                        $('#form2_steps').find('.button-next').show();
                        $('#form2_steps').find('.button-submit').hide();
                    
                    App.scrollTo($('.page-title'));
                ,
                onPrevious: function (tab, navigation, index) 
                    var total = navigation.find('li').length;
                    var current = index + 1;
                    // set wizard title
                    $('.step-title', $('#form2_steps')).text('Step ' + (index + 1) + ' of ' + total);
                    // set done steps
                    jQuery('li', $('#form2_steps')).removeClass("done");
                    var li_list = navigation.find('li');
                    for (var i = 0; i < index; i++) 
                        jQuery(li_list[i]).addClass("done");
                    

                    if (current == 1) 
                        $('#form2_steps').find('.button-previous').hide();
                     else 
                        $('#form2_steps').find('.button-previous').show();
                    

                    if (current >= total) 
                        $('#form2_steps').find('.button-next').hide();
                        $('#form2_steps').find('.button-submit').show();
                     else 
                        $('#form2_steps').find('.button-next').show();
                        $('#form2_steps').find('.button-submit').hide();
                    

                    App.scrollTo($('.page-title'));
                ,
                onTabShow: function (tab, navigation, index) 
                    var total = navigation.find('li').length;
                    var current = index + 1;
                    var $percent = (current / total) * 100;
                    $('#form2_steps').find('.bar').css(
                        width: $percent + '%'
                    );
                
            );

            $('#form2_steps').find('.button-previous').hide();
            $('#form2_steps .button-submit').click(function () 
                alert('Finished! Hope you like it :)');
            ).hide();
        
    ;

();
</script>

【讨论】:

以上是关于如何验证 twitter 引导表单向导的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jQuery Validate 正确验证放置在多个选项卡上的 Twitter 引导表单?

ASP.Net 4.5 Twitter 引导和客户端验证

将引导向导表单提交到 sql 数据库

将 Twitter 引导验证样式和消息应用于 ASP.NET MVC 验证

引导向导下一个按钮不起作用

将 twitter 引导程序与 Django 表单一起使用