I am using the accordion directive from http://angular-ui.github.com/bootstrap/ and I need to have more control over when the accordions open and close.
To be more preci
There is the is-open
attribute on the accordion-group
which points to a bindable expression. By using this expression you can control accordion items programatically, ex.:
<div ng-controller="AccordionDemoCtrl">
<accordion>
<accordion-group ng-repeat="group in groups" heading="{{group.title}}" is-open="group.open">
{{group.content}}
</accordion-group>
</accordion>
<button class="btn" ng-click="groups[0].open = !groups[0].open">Toggle first open</button>
<button class="btn" ng-click="groups[1].open = !groups[1].open">Toggle second open</button>
</div>
and the working plunk here: http://plnkr.co/edit/DepnVH?p=preview
For whoever the solution by @pkozlowski.opensource is not working (me for example) you could just force the component to accept the CSS that will close it (without transition that is).
The Theory: The angular directive gets expanded into standard HTML, div elements mainly, where the CSS styles give it the appearance of the accordion. The div with class .panel-collapse
is the body of the accordion-group element. You can swap its second class from .in
to .collapse
along with a few other changes as seen below.
The Code:
$scope.toggleOpen = function(project) {
var id = '<The ID of the accordion-group you want to close>';
var elements = angular.element($document[0].querySelector('#'+id));
var children = elements.children();
for(var i = 0; i < children.length; i++) {
var child = angular.element(children[i]);
if(child.hasClass('panel-collapse')) {
if(child.hasClass('in')) { // it is open
child.removeClass('in');
child.addClass('collapse');
child.css('height', '0px');
} else { // it is closed
child.addClass('in');
child.removeClass('collapse');
child.css('height', 'auto');
}
}
}
};
As we are talking about Angular, it is very possible that you are generating the accordion through an ng-repeat tag. In this case you can also generate the id's for the elements like:
<accordion-group ng-repeat="user in users"
is-disabled="user.projects.length == 0"
id="USER{{user._id}}">
Given a Mongoose model User, notice that the id I am giving is not user._id
but has 'USER' appended in front. This is because Mongoose might generate id's that start numerically and querySelector does not like that ;-) go figure!