Reputation: 584
I have placed accordion inside tabs using Angular Bootstrap but I am unable to handle the expand event of accordion pane. Here is the fiddle: http://jsfiddle.net/vruqw9s8/
$(function () {
$('accordion').on('show.bs.collapse', function () {
alert('accordion change');
});
});
Upvotes: 2
Views: 4214
Reputation: 17374
The is-open attribute on the UI Bootstrap accordion-group directive points to a bindable expression. The expression must be a boolean that resolves to either true or false. If the value is true, the accordion group is opened.
The is-open attribute is a two-way binding, meaning that whenever the parent scope property changes, the corresponding isolated scope property of the accordion-group also changes, and vice versa. As a result, you can use it to monitor whether the accordion is opened or closed with a $watch
function.
So, in order to make your Fiddle demo work, you need to do a couple of things:
Binding the is-open attribute to a scope property in the controller is simple. In this case I just created $scope.status as an object with one property called open and gave it a value of false. That value is just going to be the initial value so that the accordion is closed when you first run your demo. The important thing here is that status must be an object because that's how two-way binding works. If you make status a string, (e.g., $scope.status = true
), and bind is-open to status (i.e., is-open="status"
) in your markup, it will only be one-bound. In this case it will initialize the accordion-group as open, but won't update the scope when you click on the element to open and close it.
So, your controller for this part, you'd have:
$scope.status = {
open: false
};
and in your markup, you'll have:
<accordion-group heading="Accordion 2" is-open="status.open">
Accordian 2 content.
</accordion-group>
Now the last part is the $watch function. The $watch function has a couple of key parts. First, you have to tell it what to watch, so in this case you'd pass in status.open
. That's the thing on the scope that we want to monitor and see if it changes. Next, there's the listener function.
There are two values that always get passed to the listener function. The first is the new value of the thing that you're watching. The second is the old value of the thing that you're watching. The order of these arguments matters here. No matter what you call it, the first value is always going to be the new value. So, now this $watch function should make sense:
$scope.$watch('status.open', function(newval, oldval){
if(oldval !== newval) {
var state = newval ? 'opening' : 'closing';
alert('Accordion 2 is '+state);
}
});
In the if statement, I'm checking if the value of status.open actually changed by comparing the old value with the new value. If the old and new values don't equal each other, then you can do your thing. In this case, I created a variable called state and used a ternary operator to check the new value, if it's true, I set the value of state to 'opening' and if not, it's set to 'closing'. Then, I just call the alert.
This is already way too long, so I'll just mention that there's a third value in the $watch function that is the object equality. Ben Nadel has a great (short) little experiment video that explains how and when you use object equality. I also created this Plunker for you, which shows how to use this kind of deep value checking on dynamically created accordion-groups.
Hope this helps solve your challenge.
Upvotes: 2