Search code examples
jqueryhtmlformstwitter-bootstrapjquery-easing

HTML Tabbed Form Sliding


I have a three page registration form that is split up amongst three tabs all developed upon bootstrap. I want to slide one page into another after the current page has been validated. Here is a working demo of what I mean. I tried implementing this demo but the code was too different for me to replicate properly. So here a demonstration of what I have so far: bin. As you can see the 2nd and 3rd tabs are disabled until the first tab is validated properly. After choosing an option and clicking continue, I want it to slide into the second tab. I tried something like this:

$(".tab-content div").animate({left: "0px"}, { duration: 350, easing: 'easeInOutCirc' });

But that didn't work, so how do I do it?


Solution

  • I've worked this up on jsFiddle at http://jsfiddle.net/technotarek/ymxn4/.

    The revised JS, in its entirety, is below. Note that the fiddle includes a bit of new CSS. I also modified the HTML, but aside from the #tab-container div, it was all just for appearances sake. The solution works with Twitter Bootstrap in the recommended manner per their documentation at http://twitter.github.com/bootstrap/javascript.html#tabs

    var selector;
    var selectorID;
    
    activateTab('#myTab a:first');
    
    function activateTab(selectorID) 
    {
        $(selectorID).tab('show')
            .closest('.disabled').removeClass('disabled');    
    }
    
    function deactivateTab(selector) 
    {
        $(selector).off('click.twbstab')
            .closest('li').addClass('disabled');
    }
    
    $('.btn-demo').on('click',function() {
        selector = '#myTab a[href="'+$(this).data('activate')+'"]';
        selectorID = $(selector).attr('href');
    });
    
    var val1 = $('#frmtype1').validate(
    {
        errorPlacement: function(error, element) {}, 
        // prevent the standard error message from showing, rather you use the inline-text
        rules: {
            'Reg_type': {
                required: true
            }
        }
    });
    
    // validate 1st form
    $('#frmtype1').submit(function(e) 
    {
        // validate the first page
        if(val1.form()) {
            $('.help-inline').hide();
            activateTab(selector);
        } else {
            $('.help-inline').show();
        }
        return false;
    });
    
    // validate 2nd form
    $('#frmtype2').submit(function(e) 
    {
        // validate the second page
        activateTab(selector);
        return false;
    });
    
    
    // if 2nd or 3rd tab is clicked, validate as if the form was submitted
    $('#myTab li:eq(1) a, #myTab li:eq(2) a').click(function(e) 
    {
        selectorID = $(this).attr('href');
        // validate the first page
        if(val1.form()) {
            $('.help-inline').hide();
            activateTab(this);
            $(selectorID).tab('show');
        } else {
            $('.help-inline').show();
        }
        return false;
    });
    
    // re-position all tab-panes, except the active pane, so that they are prepared for the slide effect
    $(".tab-pane").css("position", "relative");
    $(".tab-pane").not(".active").animate({
        left: "1000px"
    });
    
    // perform slide effect
    $('a[data-toggle="tab"]').on('show', function (e) {
        lastPane = $(e.relatedTarget).attr('href');
        $(lastPane).animate({left: "1000px"}, 300)
        currPane = $(e.target).attr('href');
        $(currPane).animate({left: "0px"}, 300);
    });
    ​
    

    The key to getting everything to work is at the very end of the script (starting with "// re-position..."). Note that the reason your original code did not work is partly because you didn't include the easing library used in the demo (per the comment by @forty-two), but also because the code in the demo used to create the tab effect is fundamentally different than how tabs work in Twitter Bootstrap.