jQueryUI tabs - deeplinking into tab content
Asked Answered
H

4

7

I am not sure if this is possible at the moment, and the testing ive done seems to offer odd results.

I have on one page a section of 4 tabs, inside these tabs are several sections of text that i have each given a unique anchor name.

What i am trying to do is link from another page to say the 4th block of content in tab 3...

the tabs are all working great, and if i link to content sections on the first tab it works great.. its when i want to link to the tabs that arent the first that it gets tricky..

i have tried

<a href="http://example.com#tab-3#content-4" ></a>

but this doesnt work at all

and when i use just

<a href="http://example.com#tab-3"></a>

i have also seen this being implemented - however it seems to have the same functionality as just using the above piece of code regardless of if this is in my jquery call

$(function(){
  $('tabs').tabs();
  var hash = location.hash;
  $('tabs').tabs( "select" , hash );
});

With either of the above 2 options while the third tab is selected i am pushed all the way to the bottom of the page. I assume this is because all the tabs are placed in list items and then jqueryui turns them into tabs.. in effect moving the tab content for number 3 from the bottom back up to the top of the tabs section..

if anyone knows how i could link to the 4th block of content on the 3rd tab i would be extremely greatful.

someone the solution might lie in $_post and $_get data.. but im not sure if thats really the case, and even then im not sure how to implement it with jqueryui

Thank you in advance

Hindoo answered 8/3, 2011 at 1:44 Comment(3)
Do you need the tab id in the url? For example, could your url look like http://example.com#content-4, and then use JavaScript to select the tab that contains the element with id content-4?Tymes
@andrew: linking in the url to the section (ie #content-4) that isnt on the "current" tab means that the browser just locates itself to the bottom of the page.. (where the content would be if it wasnt moved to a tab) and because the page loads before the javascript the changing of tab after the browser locates to the bottom of the page means that it remains at the bottom of the page when the new tab loads.. if there was a way to load the tab and then select the content might work.. but id prefer not to need to splitting the URL to get variables..Hindoo
That makes sense. I'm thinking that if you keep the URL a single hash with the ID of the element (no matter what tab it's in) the page will gracefully degrade and those links will still work without the tabs widget. If you don't need to support people without JavaScript you have more options. Is this the case?Tymes
R
8

Try this:

As a link use

<a href="http://example.com#content-4" ></a>

And the script

    $(function(){
        $tabs = $('#tabs').tabs();

        var hash = location.hash.substring(1),

        $anchor = $tabs
            .find('a[name="' + hash + '"]'),

        tabId = $anchor.closest('.ui-tabs-panel')
            .attr('id');

        $tabs.find('ul:first a').each(
            function(i){
                    if($(this).attr('href') === '#' + tabId){
                        $tabs.tabs('select', i);
                        window.scrollTo(0, $anchor.position().top);
                        // Stop searching if we found it
                        return false;
                    }
            }
        );
    });
Reproduction answered 6/1, 2012 at 14:26 Comment(6)
Just noticed this is an old question, but I guess the answer is still validReproduction
Yeah, I guess the scrollTo() is the thing that makes it work. [BTW, using $.closest(), you can deduce the containing tab-3 from the content-4 anchor. As a result, the fragment in the url can be reduced to just #content-4.] I'll hold off on the bounty for a little while to see if I get any other approaches. But if not and I can make yours work, then I'll manually award.Braunschweig
The basic technique - specify an anchor name in the url, identify the named element in the body, identify/select the containing tab using` $(elt)closest(), and then scroll to the anchor using top = anchorElt.offset().top` - seems sound. But the results are turning out unpredictable; the further down the page, the greater the error. Seems to be some kind of conflict between $(window).scrollTop() and $(elt).offset().top. Ever experienced anything similar?Braunschweig
I updated the script to eliminate the use of both anchor's and I used the $.cosest() approach. This example should work with $(window).scrollTop() I guess.Reproduction
Thanks,, that pretty much what I have, though your's is a bit cleaner. Are you sure we want position().top rather than offset().top?Braunschweig
In this case it does not mater because the tab object is a straightforward positioned element. But offset should work just the same.Reproduction
W
1

Depending on what server-side scripting language you're using, if any, you could pass the tab you want selected in the url, $_GET[] it, then echo it as the selected option in your call to the tabs(); widget. Then using a nifty function I found in another stack thread, you can get the coordinates of your selected element and scroll to it.

e.g. using PHP

<!--- link on another page -->
<a href="yourtabspage.php?tab=2&ctntid=content4">Your Link to Fourth Piece of Content in Second Tab</a>

Then on your tabs page:

<?php 
  $your_tab = $_GET['tab']; 
  $your_selected_element = $_GET['ctntid'];
?>

<script type="text/javascript">

// this function is from another post on stackoverflow, I didn't write it.

function getOffset( el ) {
  var _x = 0;
  var _y = 0;
  while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
    _x += el.offsetLeft - el.scrollLeft;
    _y += el.offsetTop - el.scrollTop;
    el = el.offsetParent;
  }
  return { top: _y, left: _x };
}

jQuery(document).ready(function () {
  $("#tabs").tabs({
    selected: "<?php echo $your_tab; ?>"
  });


});

jQuery(window).load(function() {
  var x = getOffset( document.getElementById('<?php echo $your_selected_element;?>') ).left;
  var y = getOffset( document.getElementById('<?php echo $your_selected_element;?>') ).top;
  window.scrollTo(x,y)
});

</script>
Wixted answered 11/1, 2012 at 0:44 Comment(1)
I see what you are doing. The core idea is the same - identify the tab, select the tab, then scroll to the block within the tab. Your getOffset() function to calculate the offset seems to work more reliably - though still not perfectly, which is baffling - than directly querying the element using $.offset() or $.position(). I'll poke around with it and see how it goes. Thanks!Braunschweig
B
1

Old question, but I ran into this deep-linking jQuery tab need today. I also had to retain the hash on post-backs. Below works to deep-link into jQuery tabs AND retain the hash on post-back by appending the hash to the form's action.

    $(document).ready(function ($) {

        //Initialize the jQuery tabs
        $("#tabs").tabs({
            activate: function (event, ui) {
                //Add this ID to the URL, and scroll back to the top
                location.hash = ui.newPanel.attr('id');
                window.scrollTo(0, 0);

                //Update the form to append the hash to the action, for post-backs
                var newAction = $("#frmMain").attr("action").split('#')[0] + location.hash;
                $("#frmMain").attr("action", newAction);
            }
        });

        //When the page loads, if we have a hash, load that tab
        var hash = location.hash;
        if (hash.length > 0) {
            //Load the tab associated with this hash
            $("#tabs").tabs("load", hash);

            //Re-update the form to append the hash to the action, for post-backs
            var newAction = $("#frmMain").attr("action").split('#')[0] + hash;
            $("#frmMain").attr("action", newAction);
        }

    });
Breebreech answered 10/2, 2017 at 22:38 Comment(0)
R
-1

try

<a href="#" onclick="changetab(3)">Tab 4</a>


function changetab(idx)
{
  $('tabs').tabs( "select" , idx);
}
Rehash answered 8/3, 2011 at 2:27 Comment(1)
this does not work from another page.. i need to link to content inside a tab from another pageHindoo

© 2022 - 2024 — McMap. All rights reserved.