angular dropdown directive

20,101

I found a way to make this happen, what i did is i use a class 'active-recent' and than just close all the opened menus expect the one that has this class, and just right after, i remove the recent class, so next time when i press on other dropdown, this last one closes aswell.

myApp.directive('dropdown', function($document) {
    return {
        restrict: "C",
        link: function(scope, elem, attr) {

            elem.bind('click', function() {
                elem.toggleClass('active');
                elem.addClass('active-recent');
            });

            $document.bind('click', function() {
                if(!elem.hasClass('active-recent')) {
                    elem.removeClass('active');
                }
                elem.removeClass('active-recent');
            });

        }
    }
});

http://plnkr.co/edit/wzJkSb0bU53t7liOoVJZ?p=preview

Share:
20,101

Related videos on Youtube

Pacuraru Daniel
Author by

Pacuraru Daniel

Updated on July 09, 2022

Comments

  • Pacuraru Daniel
    Pacuraru Daniel almost 2 years

    i am trying to create a dropdown menu using directives from angularJS and so far it looks like this:

    <div class="dropdown">
      <button class="button">Dropdown</button>
      <ul>
        <li><a>Menu Item 1</a></li>
        <li><a>Menu Item 2</a></li>
      </ul>
    </div>
    

    This is the html layout and this is the directive so far:

    myApp.directive('dropdown', function($parse) {
        return {
            restrict: "C",
            link: function(scope, elem, attr) {
    
                var isDisabled = $parse(attr.ngDisabled);
    
                var toggleMenu = function() {
                    if(!elem.hasClass('dropdown-active') && !isDisabled(scope))
                        elem.addClass('dropdown-active');
                    else
                        elem.removeClass('dropdown-active');
                };
    
                elem.bind('click', toggleMenu);
    
            }
        }
    });
    

    So far it works, when i press on the button, the list opens and when i press again it closes but now i have a problem.. i need to make it to close when i press anywhere outside the dropdown.

    Can i do that without using jQuery? I am trying to do this project with just AngularJS.

    Thank you in advance, Daniel.

    Link to Plunker (here i have a problem, when i press on a dropdown, the other one doesnt close)

    http://plnkr.co/edit/OrfUVg8KsOhAxqLwn1li?p=preview

    • mnsr
      mnsr almost 10 years
      My guess would be you may need to copy jqueryui's technique and create a full page invisible div that sits under the dropdown menu div with an onclick close.
    • aet
      aet almost 10 years
      You should look at the source for the dropdown in ui-bootstrap: github.com/angular-ui/bootstrap/blob/master/src/dropdown/… For example, they close the dropdown if the user hits the ESC key. Perhaps you could model yours after this. Better yet, why not just use their dropdown? You don't actually have to use bootstrap, you can replace or override their templates and just assign your own classes.
    • Zack Argyle
      Zack Argyle almost 10 years
      Bind an event onto the window on toggleIn, and unbind it on toggleOut. In the event check to see if the event target is the directive element, if not, toggleOut
    • Pacuraru Daniel
      Pacuraru Daniel almost 10 years
      how can i see into the target event if it's the element ?
  • Pacuraru Daniel
    Pacuraru Daniel almost 10 years
    the problem with your technique is that i cannot create more dropdowns and reuse the directive in an easy way
  • Pacuraru Daniel
    Pacuraru Daniel almost 10 years
    I tried with $document injector and i wrote $document.bind('click', closeMenu); but i have a problem, when i press outside of menu it works but when i press on other dropdown, the both dropdowns are opened, the other one doesnt close.
  • mnsr
    mnsr almost 10 years
    well like i said, it's a rough idea for you to expand upon. One thing you could do for multiple dropdowns is actually create a div with that overlay css on it inside your directive, and add an ng-show/click thing to it. so when you close it, it destroys that div.
  • bto.rdz
    bto.rdz almost 10 years
    @PacuraruDaniel to reuse that code use isolated scope