Question

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?

Was it helpful?

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.

OTHER TIPS

What you had was almost there

The idea is that you position your divs side-by-side and slide them all along together as you move through the tabs.

To get it to work give each of your divs a starting point e.g. 0px, 400px, 800px and position: relative:

    <div class="tab-pane active" id="options" style="left: 0; position: relative;">

    <div class="tab-pane" id="information" style="left: 400px; position: relative;">

In the submit slide all of the divs 400px further to the left by animating the left property:

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

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

Note that I changed the selector to target the specific divs rather than all divs under tab-content.

Here is the link to the bin with my changes.

I just did the first two divs but you should get the idea from this.

Hope this helps.

Have a look at this modified version of your code:

http://jsbin.com/asarek/21/edit

In particular, I added some CSS and JS to make it work closer to the example you provided:

JS:

var currentPanel = jQuery(this).parent();
$(".tab-content").animate({left: "-"+currentPanel.width()+"px"}, { duration: 350, easing: 'easeInOutCirc' });

That code moves the tab content left relative to the width of this currentPanel, which in this case is your first form. What you'll need to do is define widths for each of your panels and move their parent container (.tab-content) to the left according to where each one is.

The CSS puts the panels all on the same line (using inline-block). It uses an additional wrapper to contain the tab-content and hide the overflow.

CSS

  .tab-wrapper
    {
     overflow:hidden;
     width:500px;
    }
    .tab-content
    {
      position:relative;
      white-space:nowrap;
      overflow:visible;
    }
    .tab-content .tab-pane
    {
      display:inline-block;
    }

What my example doesn't do is incorporate the sliding effect into the tab clicks. The example you provided does this by checking which link is clicked. You can do this in the same way by checking the selector parameter and sliding left according to which panel should be shown. Let me know if you want me to further illustrate any of this.

JS Bin

I found your problem...

 $(".tab-content div").css({position: 'absolute'}).animate({left: "-400px"}, 350);

First, your Div needs absolute positioning. More easily done in the CSS.

.tab-content div {position:absolute;}

Second using something like

"-400px"

will move the div -400px from its original position, where as

"400px"

will move the div to 400px from 0 , landing it to +400px.

Are the jQuery UI effects "Slide" and "Drop" meeting your requirements? They should be configurable (left-right sides).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top