Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Firstly, a similar question has been answered before, however the aforementioned does not resolve my issue.

I'd like to - from within my js, not within my html - be able to close the current accordion and open the next. Please note that this action will be triggered from the js from within a controller which is not the accordion controller (yes, I can use a factory function and make $scope available to other controllers, which I'm doing already). Also important is that the accordions are hard-coded so, they're not within a loop.

EDIT: Adding code

Ok, on my accordionCtrl is empty (at the moment as I don't need to add any code it for now), so all the action is happening on another controller:

    var CustomerFormCtrl = function($scope, mainObj, $http, $timeout) {

    $scope.saveCustomer = true;

    $scope.master = {};

    $scope.update = function(customer) {

        $scope.master = angular.copy(customer);
        mainObj.customer[customer.name] = customer;

        // Saving customer
        if($scope.saveCustomer === true) {

            $http({

                method: 'POST',
                url: '/customers/create',
                data: $.param(mainObj.customer),
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' }

            })
            .success(function(data) {

                $scope.SavedCustomer = true;
                $scope.Message = "Customer saved";

                $timeout(function() { $scope.SavedCustomer = false }, 2000);

            });

        }

    };

    $scope.reset = function() {

        $scope.customer = angular.copy($scope.master);

    };

    $scope.reset();

}

And here's my accordion (in jade rather than html)

div(ng-controller="accordionCtrl")

    accordion(close-others="false")

        // Customer accordion
        accordion-group(heading="Step 1 - Customer details" is-open="true")

            div.col-md-6

                h4 Search a customer

                div(class="container-fluid", ng-controller="SearchCustomerCtrl")

                    input(type="text", ng-model="asyncSelected", placeholder="Search customer", typeahead="address for address in getLocation($viewValue) | filter:$viewValue" typeahead-loading="loadingLocations" class="form-control")
                    i(ng-show="loadingLocations" class="glyphicon glyphicon-refresh")

            div.col-md-6

                h4 Customer details

                div(ng-controller="CustomerFormCtrl")

                    div(ng-show="SavedCustomer")

                        alert(type="success") {{Message}}

                    form(name="CustomerDetails", class="", role="form", novalidate)

                        div.form-group

                            // my form here

        // Order accordion
        accordion-group(heading="Step 2 - Placing the order")

            p Order

        // Checkout accordion
        accordion-group(heading="Step 3 - Checkout")

            p Checkout

On $http({...}).success(function(data) {...} I'd like to add some code that'd close the Step 1 accordion and open Step 2.

If I was using jQuery (which I can do, but I'd rather not) I could select the aforementioned accordion through it' id/class something along these lines:

$('.boot-tab').find('li.active')
                .next()
                .find('a[data-toggle="tab"]')
                .click();

But with Angular I've no idea how to make this work. Thanks for your help.

share|improve this question
 
Is there any code we can see, like an attempt? –  dcodesmith Jan 5 at 23:42
add comment

1 Answer

up vote 1 down vote accepted

Sure - the easiest way is instead of setting is-open to true, set it to a property on your scope.

accordion-group(heading="Step 1 - Customer details" is-open="$parent.step1open")

if you want to, you can put the init inline there too:

accordion-group(heading="Step 1 - Customer details" is-open="$parent.step1open" ng-init="step1open = false")

Then in your JS, set $scope.step1open = true in your success function. I assume you're doing this in the accordianCtl - if you're not, you'll soon have followup questions about scope visiblity and inheritance.

Here's a plunker with an example.

share|improve this answer
 
Hi Philip. I did try as said, having changed the controller so everything now is within accordionCtrl to avoid using $broadcast but unfortunately it doesn't work. I got $scope.step1 = true; $scope.step2 = false; $scope.step3 = false; at the beginning of my controller and $scope.step2 = true in my success function. If I console.log($scope.step2) it'll log true, but nothing happens with the accordion. Any ideas? –  WagnerMatosUK Jan 6 at 22:02
 
Can you narrow it down to a Plunker (or similar)? Actual code goes a long way. –  Philip Rieck Jan 6 at 22:49
 
Here's the plunker I've created. You'll notice that I've added $scope.step1 = true at the beginning of my controller. In this plunker, all accordions start (after loading page) closed, however on my local machine, the first accordion starts open (as expected as I've set the step1 to true. –  WagnerMatosUK Jan 6 at 23:20
 
See the plunker I forked from yours (linked in the answer). Yours had two problems: First no ng-controller listed. And the second and less obvious is that the accordian creates a nested scope - that's why you see the $parent.step1 rather than just step1. –  Philip Rieck Jan 7 at 1:03
1  
The plunkr you have doesn't work because the controller is not still not there, and even if update contains imports that don't exist in the plunker. If you look here you can see how it can work. Note that the $parent portion I mentioned is in the HTML, not in the controller code. –  Philip Rieck Jan 7 at 17:20
show 4 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.