3

I have page with various accordions on. Some of these accordions reference content in another accordion on the page, my question is how do I make it so that the in the first accordion expands the other accordion.

I cant seem to get it to work.

I have set the link up as <a href="#SubTitle2">Test</a>

And on the first <p> under the <div class="panel-body"> as <p id="SubTitle2">Content</p> but this does nothing at all.

Am I putting it in the wrong place or am I going about it completely wrong?

Below is my complete code

    <div class="panel-group" id="accordion">
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">
                <a class="accordion-toggle collapsed" data-parent="#accordion" href="#collapseOne" data-toggle="collapse">Heading 1</a>
            </h3>
        </div>
        <div class="panel-collapse collapse" id="collapseOne">
            <div class="panel-body">
                <p><a href="#SubTitle2">Test</a></p>
            </div>
        </div>
    </div>
</div>
<div class="panel-group" id="accordion">
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">
                <a class="accordion-toggle collapsed" data-parent="#accordion" href="#collapseTwo" data-toggle="collapse">Heading 2</a>
            </h3>
        </div>
        <div class="panel-collapse collapse" id="collapseTwo">
            <div class="panel-body">
                <p id="SubTitle2">Content</p>
            </div>
        </div>
    </div>
</div>
creimers
  • 4,975
  • 4
  • 33
  • 55
murday1983
  • 3,806
  • 14
  • 54
  • 105

5 Answers5

3

If you're inclined to use jQuery for this, you could do the following:

$('#SubTitle2').click(function(){
  $('#collapseTwo').collapse('show');
});

...having the anchor setup something like this:

<a href="#" id="SubTitle2" data-target="#collapseTwo">Test</a>

You can test it out here: http://www.bootply.com/jQMOup05vG

benomatis
  • 5,536
  • 7
  • 36
  • 59
  • according to this there is no need to use data-target="#collapseTwo" – Nasir Mahmood Oct 03 '14 at 09:58
  • you can do one or the other... this one is just the direct jQuery alternative of your solution. Both do the same (both are js calls), but in a different way... – benomatis Oct 03 '14 at 10:00
  • @webeno please see my comment as by mixing your comment and Nasis's I was able to achieve what I needed – murday1983 Oct 03 '14 at 10:39
  • @webeno don't suppose you know what I need to do to get them to open if they are on a different page. This only works if the accordions are on the same page. please see the following post I have going for this issue http://stackoverflow.com/questions/26180828/twitter-bootstrap3-make-an-accordion-expand-on-a-different-page-when-a-link-is – murday1983 Oct 03 '14 at 15:10
  • first of all, if it only works by applying both of these answers, then you're missing something, or doing something wrong... both of these answers are correct; it's up to you which one you prefer using... as to the other question, you already have the correct answer on there in the meantime ;) – benomatis Oct 03 '14 at 21:32
2

by using data-target you can achieve this as

<a data-toggle="collapse" data-target="#id_to_expand">click</a>

hope this will help you

Nasir Mahmood
  • 1,445
  • 1
  • 13
  • 18
  • i like your answer, just make sure you use the OP's original `id`, if they provided it already... – benomatis Oct 03 '14 at 09:49
  • @Nasir Mahmood please see my comment as by mixing your comment and webeno's I was able to achieve what I needed – murday1983 Oct 03 '14 at 10:40
  • @NasirMahmood don't suppose you know what I need to do to get them to open if they are on a different page. This only works if the accordions are on the same page. please see the following post I have going for this issue http://stackoverflow.com/questions/26180828/twitter-bootstrap3-make-an-accordion-expand-on-a-different-page-when-a-link-is – murday1983 Oct 03 '14 at 15:11
  • this was most excellent! using the W3 tutorial for bookmarks (http://www.w3schools.com/HTML/html_links.asp), I combined your response with the code from the W3 sample. so basically, on click, the page was scrolled into place and THAN expanded the accordion. `Jump to comments` – Uncle Iroh Nov 22 '16 at 21:44
2

Managed to get it working by mixing the answers from Nasir Mahmood and webeno.

Basically I mixed and matched both solutions and it works. My code is now:

<p><a class="collapsed" 
      href="#SubTitle2" 
      data-toggle="collapse" 
      data-target="#collapseTwo">Test
</a></p>

As you are not able to mark responses as answer I will add a comment on them both

7stud
  • 46,922
  • 14
  • 101
  • 127
murday1983
  • 3,806
  • 14
  • 54
  • 105
0

None of the answers submitted previously are acceptable for my situation. I don't know ahead of time which links exist on the page, and which links will necessitate expanding collapsed sections. I also have nested collapsible sections. Also, I want the expansion to occur if someone links into the page from another document. So I settled on a solution that detects dynamically what sections must be opened. When a click on a link I care about happens, the handler:

  1. Finds all parents of the target which are collapsed sections. ($(target).parents(".collapse:not(.in)").toArray().reverse();)

  2. Starting with the outermost parent, it requests that the element be expanded. (These are the calls to next(). The call $parent.collapse('show'); is what shows a parent.)

  3. Once an element is expanded, it expands the next parent (closer to the link target). (if (parents.length)...)

  4. Until finally it requests that the target be scrolled into view. (target.scrollIntoView(true);)

I've initially tried walking the DOM tree in the reverse order, from innermost parent to outermost, but I got strange results. Even compensating for event bubbling, the results were inconsistent. The request for scrolling to the target is necessary as it is likely that the browser will have scrolled the window before the sections are expanded.

Here's the code. win and doc are set to the Window and Document instance that actually hold the DOM tree being processed. Since frames may be used, just referring to window and document ain't okay. The root variable is an Element that holds the part of the DOM I care about.

function showTarget() {
    var hash = win.location.hash;
    if (!hash)
        return;

    var target = doc.getElementById(hash.slice(1));
    if (!target)
        return;

    var parents =
            $(target).parents(".collapse:not(.in)").toArray().reverse();

    function next(parent) {
        var $parent = $(parent);
        $parent.one('shown.bs.collapse', function () {
            if (parents.length) {
                next(parents.shift());
                return;
            }
            target.scrollIntoView(true);
        });
        $parent.collapse('show');
    }
    next(parents.shift());
}
win.addEventListener('popstate', showTarget);
$(root).on('click', 'a[href]:not([data-toggle], [href="#"])',
           function (ev) {
    setTimeout(showTarget, 0);
});
showTarget();

Notes:

  • The selector a[href]:not([data-toggle], [href="#"]) limits event listening only to those a elements that are actually hyperlinks into the rest of the document. Sometimes a is used for other purposes. For instance, those a elements that have a data-toggle attribute or have href="#" are not used for navigating through the page.

  • setTimeout(showTarget, 0) allows the default action for a click on a hyperlink to happen (i.e. the hash changes) first, and then showTarget is called. This works everywhere except FF. A few tests show that showTarget won't see the change on FF unless the timeout is raised. 0ms does not work, 1ms did not, and 10ms works. At any rate, I'd rather not hardcode some FF-specific value that may change in the future so we also listen on popstate` to catch those cases that would not be caught on FF.

  • The explicit call to showTarget() is necessary for cases when the page is loaded with a URL that has a hash.

  • I've tried an implementation that listened only on popstate but it proved unreliable due to how Chrome and FF differ in how they generate popstate. (Chrome generates it whenever a link is clicked, even if the hash does not change. FF generates it only when the hash changes.)

  • The code above has been tested in Chrome (39, 38, 36), FF (31), and IE (10, 11).

Louis
  • 146,715
  • 28
  • 274
  • 320
0

you have set panel-group id=accordion twice. Thats not good. Wrap your two panels into one panel-group-block with one id:

   <div class="panel-group" id="accordion">
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">
                <a class="accordion-toggle collapsed" data-parent="#accordion" href="#collapseOne" data-toggle="collapse">Heading 1</a>
            </h3>
        </div>
        <div class="panel-collapse collapse" id="collapseOne">
            <div class="panel-body">
                <p><a href="#SubTitle2">Test</a></p>
            </div>
        </div>
    </div>
    <!-- SNIP
    </div>
    <div class="panel-group" id="accordion">
    SNAP -->
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">
                <a class="accordion-toggle collapsed" data-parent="#accordion" href="#collapseTwo" data-toggle="collapse">Heading 2</a>
            </h3>
        </div>
        <div class="panel-collapse collapse" id="collapseTwo">
            <div class="panel-body">
                <p id="SubTitle2">Content</p>
            </div>
        </div>
    </div>
    </div>
DirkO
  • 1
  • 3