Angular Customizable Dropdown

Introduction

The Angular Customizable Dropdown is a somewhat simple yet flexible dropdown component. The aim of this component is to uncouple your data and its representation from basic functionality. What this component provides is a skeleton for a dropdown, how you wish to style it and what you wish to use it for is up to you. It provides the basic functionality of showing, hiding, selecting and dismissing the dropdown content. What happens inside the dropdown content is all up to you.

Example usages could be:

Basically anything goes. Wherever you need to open something and close something you can use this component as a base.

How to use

Simply include the ac-dropdown.min.js to your HTML and add the AngularCustomizableDropdown module as a dependency to your Angular app, like:

    
angular.module('Example', ['ngAnimate', 'AngularCustomizableDropdown']);
    

Now you're ready to start using it. Just add it as a ac-dropdown element or attribute.

Simple example

Perhaps the simplest case, uses the default functionality provided by the component. The visible selected text is bound to a function in the controller (it could just as well simply be a scope variable, or basically anything) and the DOM element with the directive contains the dropdown items (transcluded) inside it. By default the dropdown handles showing and hiding the content itself by showing the items when the dropdown gets clicked and hides them when any element inside or outside the dropdown gets clicked.

Note that clicking an item does nothing by default. This is by design. The component takes no interest in your data or its structure or what it's supposed to do when an item is selected - the shown selected text is simply a data binding and you'll need to define what actually happens when you select an item (it may or may not affect the displayed text - therefore the component takes no part in this). In this example we have bound ng-click to call a function in the controller that sets the selected item.



Source HTML & JS:

    
<div ac-dropdown selected-text="example.getSelectedChoice()">
  <ul class="dropdown-content">
    <li ng-repeat="c in example.choices" ng-bind="c.name" ng-click="example.selectChoice(c)"></li>
  </ul>
</div>
    
    
this.choices = [
{
  'name': 'Coca-Cola',
  'value': 'coke'
},
{
  'name': 'Pepsi Cola',
  'value': 'pepsi'
},
{
  'name': 'Mountain Dew',
  'value': 'mountain-dew'
},
{
  'name': 'API-IPA',
  'value': 'api-ipa'
}
];

this.selectedChoice = this.choices[0];

this.selectChoice = function(choice) {
  this.selectedChoice = choice;
};

this.getSelectedChoice = function() {
  return "Selected: " + this.selectedChoice.name;
};
    

Complex example

Sometimes with complex structures there comes a need for a dropdown/popup that has its content not directly under it but placed in who knows where in the DOM tree. Since we favor customization we can easily do this using a selector attribute. In addition since your implementation may be complex the dropdown logic leaves the details on how to show and hide the content to you - statements bound to onOpened and onClosed attributes will be $scope.eval'd when the dropdown element gets clicked so you'll need to create the implementations for showing and hiding your dropdown content.

Normally once you click outside the dropdown content the dropdown will close. In addition to this you also have the option of disabling the automatic closing and triggering the closing anywhere you choose from by sending an event angular-customizable-dropdown/<dropdown name>/close to the dropdown. This requires you to add a name attribute to the dropdown element in order to direct the message to it. The following example utilizes all of these features.



Source HTML & JS:

    
<div ac-dropdown selected-text="example.getSelectedChoice()" content-selector="#my-external-dropdown-content" name="externalDropdown"
  on-opened="example.externalDropdownVisible = true" on-closed="example.externalDropdownVisible = false" close-on-content-click="false">
</div>

<div id="my-external-dropdown-content" ng-show="example.externalDropdownVisible">
  <h3>External dropdown content</h3>
  <ul>
    <li ng-repeat="c in example.choices" ng-bind="c.name" ng-click="example.selectChoice(c)"></li>
  </ul>
  <button ng-click="example.dismissExternalDropdown()">Close me</button>
</div>
    
    
this.dismissExternalDropdown = function() {
  $scope.$broadcast('angular-customizable-dropdown/externalDropdown/close');
};
    

External dropdown content

Hovering

Additionally the opening of the dropdown can be triggered by mouse hover with the openOnHover attribute. The duration of the dropdown staying open after the mouse moves outside the dropdown or the dropdown content area can be set with the hoverTimeout attribute. Example:



Source HTML

    
<div ac-dropdown selected-text="example.getSelectedChoice()" open-on-hover="true" mouse-leave-timeout="300">
  <ul class="dropdown-content">
    <li ng-repeat="c in example.choices" ng-bind="c.name" ng-click="example.selectChoice(c)"></li>
  </ul>
</div>
    

Styling

The component does not come with any built-in or forced styles - it's entirely up to you how you want to style your dropdowns.

The dropdown template has two classes and elements: .customizable-dropdown and .customizable-dropdown__content. customizable-dropdown class represents the closed dropdown and customizable-dropdown__content is the content element inside the dropdown. The transcluded HTML will be placed inside it.