Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open collapse element does not close when calling $.collapse('show') on sibling #16360

Closed
benjarwar opened this issue Apr 24, 2015 · 7 comments
Closed

Comments

@benjarwar
Copy link

Given a Collapse Accordion, where only one item should be open at a time:

  1. Click to open Item A
  2. Use $.collapse('show') to open Item B, a sibling item in the same accordion
  3. Note that both Items A and B are open

Expected behavior:
Only Item B should be open.

To test:
Using the Collapse Accordion example. Click the first item, then enter $('#collapseTwo').collapse('show') in your browser console.

Browser: Mac OSX Chrome 42.0.2311.90

@cvrebert
Copy link
Collaborator

Based on #9933 (comment) and #8400 (comment) , and the lack of a unit test to the contrary, my guess is that this is working as intended. Getting mutex accordion-style behavior requires emitting a click event on the trigger element (typically an <a>) rather than invoking the show method.
Assuming that's correct, it definitely needs to be documented better.

@benjarwar
Copy link
Author

That's a little counter-intuitive, but I understand wanting to keep discrete show/hide methods public without making assumptions about maintaining the click behavior. Triggering a click event is a decent work-around, but I wish there were a way to achieve the behavior programmatically without deferring to the click handler. I may have other events bound to the click event that shouldn't fire at the moment I'm calling $.collapse('show').

@cvrebert
Copy link
Collaborator

I agree it's not the best design, but I think we'd probably need to break backward compatibility to sanely fix it. I'll add an entry to our "Consider for Bootstrap v4" list.

@benjarwar
Copy link
Author

Another option would be allowing a callback function to be passed as a second argument to $.collapse(). Then you could do something like close all items first, then open the target item.

$('.panel-collapse.in').collapse('hide', function() {
  $('#collapseOne').collapse('show');
});

This would be a nice to have for all of the Bootstrap methods.

@cvrebert
Copy link
Collaborator

We use Events for such things instead; e.g. http://getbootstrap.com/javascript/#collapse-events

@benjarwar
Copy link
Author

Right, but then I'd need to set up an event that drills up a level from the target .panel-collapse that is being shown, find all its .panel siblings, then drill back down to hide the siblings' child .panel-collapse elements. A little ugly:

$('.panel-collapse').on('show.bs.collapse', function (e) {
  $(e.target).closest('.panel').siblings().find('.panel-collapse').collapse('hide');
});

@fat
Copy link
Member

fat commented Apr 25, 2015

Actually there is a bit easier solution.

If you are using the javascript api you can simply initialize the elements as an accordion first with the following code:

$('#accordion .panel-collapse').collapse({ 
  parent: '#accordion', 
  toggle: false 
})

This will let all the targets know that they have a parent to worry about.

Now when you run your initial code:

$('#collapseTwo').collapse('show')

You get the expected behavior.

The problem is that if you're relying on just the data api, the api lazy instantiates, something which .collapse('show') doesn't take into account.

That should address your problem, please reopen the issue if you have any more questions, etc.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants