Initial commit for OpenECOMP SDN-C OA&M
[sdnc/oam.git] / admportal / public / javascripts / bootstrap-submenu.js
1 /*!
2  * Bootstrap-submenu v2.0.3 (https://vsn4ik.github.io/bootstrap-submenu/)
3  * Copyright 2015 Vasily A. (https://github.com/vsn4ik)
4  * Licensed under the MIT license
5  */
6
7 /**
8  * $.inArray: friends with IE8. Use Array.prototype.indexOf in future.
9  * $.proxy: friends with IE8. Use Function.prototype.bind in future.
10  */
11
12 'use strict';
13
14 (function(factory) {
15   if (typeof define == 'function' && define.amd) {
16     // AMD. Register as an anonymous module
17     define(['jquery'], factory);
18   }
19   else if (typeof exports == 'object') {
20     // Node/CommonJS
21     module.exports = factory(require('jquery'));
22   }
23   else {
24     // Browser globals
25     factory(jQuery);
26   }
27 })(function($) {
28   function Item(element) {
29     this.$element = $(element);
30     this.$menu = this.$element.closest('.dropdown-menu');
31     this.$main = this.$menu.parent();
32     this.$items = this.$menu.children('.dropdown-submenu');
33
34     this.init();
35   }
36
37   Item.prototype = {
38     init: function() {
39       this.$element.on('keydown', $.proxy(this, 'keydown'));
40     },
41     close: function() {
42       this.$main.removeClass('open');
43       this.$items.trigger('hide.bs.submenu');
44     },
45     keydown: function(event) {
46       // 27: Esc
47
48       if (event.keyCode == 27) {
49         event.stopPropagation();
50
51         this.close();
52         this.$main.children('a, button').trigger('focus');
53       }
54     }
55   };
56
57   function SubmenuItem(element) {
58     this.$element = $(element);
59     this.$main = this.$element.parent();
60     this.$menu = this.$main.children('.dropdown-menu');
61     this.$subs = this.$main.siblings('.dropdown-submenu');
62     this.$items = this.$menu.children('.dropdown-submenu');
63
64     this.init();
65   }
66
67   $.extend(SubmenuItem.prototype, Item.prototype, {
68     init: function() {
69       this.$element.on({
70         click: $.proxy(this, 'click'),
71         keydown: $.proxy(this, 'keydown')
72       });
73
74       this.$main.on('hide.bs.submenu', $.proxy(this, 'hide'));
75     },
76     click: function(event) {
77       // Fix a[href="#"]. For community
78       event.preventDefault();
79
80       event.stopPropagation();
81
82       this.toggle();
83     },
84     hide: function(event) {
85       // Stop event bubbling
86       event.stopPropagation();
87
88       this.close();
89     },
90     open: function() {
91       this.$main.addClass('open');
92       this.$subs.trigger('hide.bs.submenu');
93     },
94     toggle: function() {
95       if (this.$main.hasClass('open')) {
96         this.close();
97       }
98       else {
99         this.open();
100       }
101     },
102     keydown: function(event) {
103       // 13: Return, 32: Spacebar
104
105       if (event.keyCode == 32) {
106         // Off vertical scrolling
107         event.preventDefault();
108       }
109
110       if ($.inArray(event.keyCode, [13, 32]) != -1) {
111         this.toggle();
112       }
113     }
114   });
115
116   function Submenupicker(element) {
117     this.$element = $(element);
118     this.$main = this.$element.parent();
119     this.$menu = this.$main.children('.dropdown-menu');
120     this.$items = this.$menu.children('.dropdown-submenu');
121
122     this.init();
123   }
124
125   Submenupicker.prototype = {
126     init: function() {
127       this.$menu.off('keydown.bs.dropdown.data-api');
128       this.$menu.on('keydown', $.proxy(this, 'itemKeydown'));
129
130       this.$menu.find('li > a').each(function() {
131         new Item(this);
132       });
133
134       this.$menu.find('.dropdown-submenu > a').each(function() {
135         new SubmenuItem(this);
136       });
137
138       this.$main.on('hidden.bs.dropdown', $.proxy(this, 'hidden'));
139     },
140     hidden: function() {
141       this.$items.trigger('hide.bs.submenu');
142     },
143     itemKeydown: function(event) {
144       // 38: Arrow up, 40: Arrow down
145
146       if ($.inArray(event.keyCode, [38, 40]) != -1) {
147         // Off vertical scrolling
148         event.preventDefault();
149
150         event.stopPropagation();
151
152         var $items = this.$menu.find('li:not(.disabled):visible > a');
153         var index = $items.index(event.target);
154
155         if (event.keyCode == 38 && index !== 0) {
156           index--;
157         }
158         else if (event.keyCode == 40 && index !== $items.length - 1) {
159           index++;
160         }
161         else {
162           return;
163         }
164
165         $items.eq(index).trigger('focus');
166       }
167     }
168   };
169
170   // For AMD/Node/CommonJS used elements (optional)
171   // http://learn.jquery.com/jquery-ui/environments/amd/
172   return $.fn.submenupicker = function(elements) {
173     var $elements = this instanceof $ ? this : $(elements);
174
175     return $elements.each(function() {
176       var data = $.data(this, 'bs.submenu');
177
178       if (!data) {
179         data = new Submenupicker(this);
180
181         $.data(this, 'bs.submenu', data);
182       }
183     });
184   };
185 });