Using Angular, how do I bind a click event to an element and on click, slide a sibling element down and up?

Michael Lynch picture Michael Lynch · Mar 12, 2014 · Viewed 58.2k times · Source

I'm working with Angular and I'm having trouble doing something that I normally use jQuery for.

I want to bind a click event to an element and on click, slide a sibling element down and up.

This is what the jQuery would look like:

$('element').click(function() {
    $(this).siblings('element').slideToggle();
});

Using Angular I have added an ng-click attribute with a function in my markup:

<div ng-click="events.displaySibling()"></div>

And this is what my controller looks like:

app.controller('myController', ['$scope', function($scope) {

    $scope.events = {};

    $scope.events.displaySibling = function() {
        console.log('clicked');
    }

}]);

So far this is working as expected but I don't know how to accomplish the slide. Any help is very much appreciated.

Update

I have replaced what I had with a directive.

My markup now looks like this:

<div class="wrapper padding myevent"></div>

I have removed what I had in my controller and have created a new directive.

app.directive('myevent', function() {
    return {
        restrict: 'C',
        link: function(scope, element, attrs) {
            element.bind('click', function($event) {
                element.parent().children('ul').slideToggle();
            });
        }
    }
});

However, I still can't get the slide toggle to work. I don't believe slideToggle() is supported by Angular. Any suggestions?

Answer

Ed Hinchliffe picture Ed Hinchliffe · Mar 12, 2014

I'm not sure exactly on the behaviour that you're talking about, but I would encourage you to think in a slightly different way. Less jQuery, more angular.

That is, have your html something like this:

<div ng-click="visible = !visible"></div>
<div ng-show="visible">I am the sibling!</div>

You can then use the build in ng-animate to make the sibling slide - yearofmoo has an excellent overview of how $animate works.

This example is simple enough that you can put the display logic in the html, but I would otherwise encourage you to as a rule to put it into the controller, like this:

<div ng-click="toggleSibling()"></div>
<div ng-show="visible"></div>

Controller:

app.controller('SiblingExample', function($scope){

  $scope.visible = false;

  $scope.toggleSibling = function(){
    $scope.visible = !$scope.visible;
  }

});

This kind of component is also a prime candidate for a directive, which would package it all up neatly.