|
1 | 1 | 'use strict'; |
2 | | -angular.module('uiAccordion',[]); |
3 | | -function fetchFromObject(obj, prop) { |
4 | 2 |
|
5 | | - if(typeof obj === 'undefined' || typeof prop === 'undefined') { |
6 | | - return ; |
| 3 | +(function () { |
| 4 | + function fetchFromObject(obj, prop) { |
| 5 | + if (typeof obj === 'undefined' || typeof prop === 'undefined') { |
| 6 | + return; |
| 7 | + } |
| 8 | + var _index = prop.indexOf('.'); |
| 9 | + if (_index > -1) { |
| 10 | + return fetchFromObject(obj[prop.substring(0, _index)], prop.substr(_index + 1)); |
| 11 | + } |
| 12 | + return obj[prop]; |
7 | 13 | } |
8 | 14 |
|
9 | | - var _index = prop.indexOf('.') |
10 | | - if(_index > -1) { |
11 | | - return fetchFromObject(obj[prop.substring(0, _index)], prop.substr(_index + 1)); |
| 15 | + function getService(name) { |
| 16 | + return angular.injector(['ng']).invoke([name, function (service) { |
| 17 | + return service; |
| 18 | + }]); |
12 | 19 | } |
13 | 20 |
|
14 | | - return obj[prop]; |
15 | | -} |
| 21 | + function noopPromise() { |
| 22 | + var def = getService('$q').defer(); |
| 23 | + def.resolve(); |
| 24 | + return def.promise; |
| 25 | + } |
| 26 | + |
| 27 | + function AccordionGroup() { |
| 28 | + } |
| 29 | + |
| 30 | + function defaultAccordionGroupOptions() { |
| 31 | + return { |
| 32 | + open: false, |
| 33 | + disabled: false, |
| 34 | + beforeOpen: noopPromise, |
| 35 | + beforeHide: noopPromise |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + function Accordion() { |
| 40 | + this.groups = []; |
| 41 | + this.options = { |
| 42 | + closeOthers: true |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + AccordionGroup.prototype.show = function (animationFn) { |
| 47 | + var _self = this; |
| 48 | + getService('$q').when(_self.options.beforeOpen()).then(function () { |
| 49 | + _self.body[animationFn]('slow');//slideDown |
| 50 | + }, function (error) { |
| 51 | + getService('$log').error(error); |
| 52 | + }) |
| 53 | + }; |
| 54 | + AccordionGroup.prototype.hide = function (animationFn) { |
| 55 | + var _self = this; |
| 56 | + getService('$q').when(_self.options.beforeHide()).then(function () { |
| 57 | + _self.body[animationFn]();//slideUp |
| 58 | + }, function (error) { |
| 59 | + getService('$log').error(error); |
| 60 | + }) |
| 61 | + }; |
| 62 | + |
| 63 | + Accordion.prototype.addGroup = function (group) { |
| 64 | + this.groups.push(group); |
| 65 | + }; |
| 66 | + Accordion.prototype.getGroups = function (group) { |
| 67 | + return this.groups; |
| 68 | + }; |
| 69 | + Accordion.prototype.applyState = function (group) { |
| 70 | + if (group) { |
| 71 | + if (group.options.open) { |
| 72 | + group.show('slideDown'); |
| 73 | + this.closeOthers(group); |
| 74 | + } else { |
| 75 | + group.hide('slideUp'); |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + }; |
| 80 | + Accordion.prototype.closeOthers = function (group) { |
| 81 | + if (this.options.closeOthers) { |
| 82 | + for (var a = 0; a < this.groups.length; a++) { |
| 83 | + if (group == this.groups[a]) { |
| 84 | + |
| 85 | + } else { |
| 86 | + this.groups[a].hide('slideUp'); |
| 87 | + } |
| 88 | + } |
| 89 | + } |
| 90 | + }; |
| 91 | + function getDefaultAccordion() { |
| 92 | + return new Accordion(); |
| 93 | + } |
| 94 | + |
| 95 | + var _ngAccordion = function ($q, $log) { |
| 96 | + return { |
| 97 | + restrict: 'A', |
| 98 | + link: function (scope, element, attrs, controller) { |
| 99 | + var options = fetchFromObject(scope, attrs.options); |
| 100 | + if (options) { |
| 101 | + angular.extend(controller.accordion.options, options); |
| 102 | + } |
| 103 | + scope.$watchCollection(attrs.options, function (n, o) { |
| 104 | + if (n && n !== o) { |
| 105 | + angular.extend(controller.accordion.options, n); |
| 106 | + } |
| 107 | + }) |
| 108 | + }, |
| 109 | + controller: function () { |
| 110 | + this.accordion = getDefaultAccordion(); |
| 111 | + } |
| 112 | + }; |
| 113 | + }; |
| 114 | + var _ngAccordionGroup = function ($q, $timeout) { |
| 115 | + return { |
| 116 | + require: ['^ngAccordion', 'ngAccordionGroup'], |
| 117 | + restrict: 'EA', |
| 118 | + controller: function () { |
| 119 | + var headerDef, bodyDef; |
| 120 | + headerDef = $q.defer(); |
| 121 | + bodyDef = $q.defer(); |
| 122 | + this.setHeaderElement = function (element) { |
| 123 | + headerDef.resolve(element); |
| 124 | + }; |
| 125 | + this.getHeaderElement = function () { |
| 126 | + return headerDef.promise; |
| 127 | + }; |
| 128 | + this.setBodyElement = function (element) { |
| 129 | + bodyDef.resolve(element); |
| 130 | + }; |
| 131 | + this.getBodyElement = function () { |
| 132 | + return bodyDef.promise; |
| 133 | + } |
| 134 | + }, |
| 135 | + scope: { |
| 136 | + options: '=' |
| 137 | + }, |
| 138 | + link: function (scope, element, attrs, controllers) { |
| 139 | + var accordionCtrl, controller, accordion, accordionGroup, options; |
| 140 | + controller = controllers[1]; |
| 141 | + accordionCtrl = controllers[0]; |
| 142 | + accordion = accordionCtrl.accordion; |
| 143 | + accordionGroup = new AccordionGroup(); |
| 144 | + if (!scope.options) { |
| 145 | + scope.options = defaultAccordionGroupOptions(); |
| 146 | + } |
| 147 | + accordionGroup.options = angular.extend(defaultAccordionGroupOptions(), scope.options); |
| 148 | + |
| 149 | + scope.$watchCollection('options', function (n, o) { |
| 150 | + accordionGroup.options = angular.extend(defaultAccordionGroupOptions(), n); |
| 151 | + if (n && !n.disabled) { |
| 152 | + accordion.applyState(accordionGroup); |
| 153 | + } |
| 154 | + }, true); |
| 155 | + |
| 156 | + $q.all([controller.getHeaderElement(), controller.getBodyElement()]).then(function (results) { |
| 157 | + accordionGroup.header = results[0]; |
| 158 | + accordionGroup.body = results[1]; |
| 159 | + if (scope.options.open) { |
| 160 | + accordionGroup.show('show'); |
| 161 | + } else { |
| 162 | + accordionGroup.hide('hide'); |
| 163 | + } |
| 164 | + accordionGroup.header.on('click', function () { |
| 165 | + if (!scope.options.disabled) { |
| 166 | + scope.options.open = !scope.options.open; |
| 167 | + } |
| 168 | + $timeout(function () { |
| 169 | + scope.$apply(); |
| 170 | + }); |
| 171 | + }); |
| 172 | + accordion.addGroup(accordionGroup); |
| 173 | + }) |
| 174 | + |
| 175 | + } |
| 176 | + }; |
| 177 | + }; |
| 178 | + var _ngAccordionBody = function () { |
| 179 | + return { |
| 180 | + require: '^ngAccordionGroup', |
| 181 | + restrict: 'EA', |
| 182 | + link: function (scope, element, attrs, accordionCtrl) { |
| 183 | + accordionCtrl.setBodyElement(element); |
| 184 | + } |
| 185 | + }; |
| 186 | + }; |
| 187 | + var _ngAccordionHeading = function () { |
| 188 | + return { |
| 189 | + require: '^ngAccordionGroup', |
| 190 | + restrict: 'EA', |
| 191 | + link: function (scope, element, attrs, accordionCtrl) { |
| 192 | + accordionCtrl.setHeaderElement(element); |
| 193 | + } |
| 194 | + }; |
| 195 | + }; |
| 196 | + angular.module('uiAccordion', []); |
| 197 | + angular.module('uiAccordion').directive('ngAccordion', _ngAccordion); |
| 198 | + angular.module('uiAccordion').directive('ngAccordionGroup', _ngAccordionGroup); |
| 199 | + angular.module('uiAccordion').directive('ngAccordionBody', _ngAccordionBody); |
| 200 | + angular.module('uiAccordion').directive('ngAccordionHeading', _ngAccordionHeading); |
16 | 201 |
|
| 202 | +})(); |
0 commit comments