How to validate a twitter bootstrap form wizard

user1502071 picture user1502071 · May 29, 2013 · Viewed 11.8k times · Source

I am using twitter bootstrap and want to combine form wizard with validation. But after trying very much the form wizard and validation is not working on next botton. Where I am making mistake. My coding is below

<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>

Answer

user1502071 picture user1502071 · May 29, 2013

Assigning an id to

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

And replace $('#form_sample_2').bootstrapWizard with $('#form2_steps').bootstrapWizard and other with this "form2_steps" After: onNext: function (tab, navigation, index) { add this coding:

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

Complete solution in a combined script is here:

<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>