[CLAMP-1] Initial ONAP CLAMP seed code commit
[clamp.git] / src / main / resources / META-INF / resources / designer / lib / angularjs-dropdown-multiselect-new.js
1 'use strict';
2
3 var directiveModule = angular.module('angularjs-dropdown-multiselect-new', ['vs-repeat']);
4
5 directiveModule.directive('ngDropdownMultiselectNew', ['$filter', '$document', '$compile', '$parse',
6     function ($filter, $document, $compile, $parse) {
7
8         return {
9             restrict: 'AE',
10             scope: {
11                 selectedModel: '=',
12                 options: '=',
13                 extraSettings: '=',
14                 events: '=',
15                 searchFilter: '=?',
16                 translationTexts: '=',
17                 groupBy: '@'
18             },
19             template: function (element, attrs) {
20                 var checkboxes = attrs.checkboxes ? true : false;
21                 var groups = attrs.groupBy ? true : false;
22
23                 var template = '<div class="multiselect-parent btn-group dropdown-multiselect" style="width:100%;">';
24                 template += '<div style="width:100%;" class="dropdown-toggle" ng-class="settings.buttonClasses" ng-click="toggleDropdown()">{{getButtonText()}}&nbsp;<span class="caret"></span></div>';
25                 template += '<ul class="dropdown-menu dropdown-menu-form" ng-style="{display: open ? \'block\' : \'none\', height : settings.scrollable ? settings.scrollableHeight : \'auto\' }" style="overflow: scroll; width:280px;" >';
26                 template += '<li ng-hide="!settings.showCheckAll"><a data-ng-click="selectAll()"><span class="glyphicon glyphicon-ok"></span>  {{texts.checkAll}}</a>';
27                 template += '<li ng-show="settings.showUncheckAll"><a data-ng-click="deselectAll();"><span class="glyphicon glyphicon-remove"></span>   {{texts.uncheckAll}}</a></li>';
28                 template += '<li ng-hide="(!settings.showCheckAll) && !settings.showUncheckAll" class="divider"></li>';
29                 template += '<li ng-show="settings.enableSearch"><div class="dropdown-header"><input type="text" class="form-control" style="width: 100%;" ng-model="searchFilter" placeholder="{{texts.searchPlaceholder}}" /></li>';
30                 template += '<li ng-show="settings.enableSearch" class="divider"></li>';
31                         
32                 template += '<div style="width:98%;" vs-repeat> ';
33                 
34                 if (groups) {
35                     template += '<li ng-repeat-start="option in orderedItems | filter: searchFilter" ng-show="getPropertyForObject(option, settings.groupBy) !== getPropertyForObject(orderedItems[$index - 1], settings.groupBy)" role="presentation" class="dropdown-header">{{ getGroupTitle(getPropertyForObject(option, settings.groupBy)) }}</li>';
36                     template += '<li ng-repeat-end role="presentation">';
37                 } else {
38                     template += '<li role="presentation" ng-repeat="option in options| filter: searchFilter">';
39                 }
40
41                 template += '<a role="menuitem" tabindex="-1" ng-click="setSelectedItem(getPropertyForObject(option,settings.idProp))">';
42
43                 if (checkboxes) {
44                     template += '<div class="checkbox"><label><input class="checkboxInput" type="checkbox" ng-click="checkboxClick($event, getPropertyForObject(option,settings.idProp))" ng-checked="isChecked(getPropertyForObject(option,settings.idProp))" /> {{getPropertyForObject(option, settings.displayProp)}}</label></div></a>';
45                 } else {
46                     template += '<span data-ng-class="{\'glyphicon glyphicon-ok\': isChecked(getPropertyForObject(option,settings.idProp))}"></span> {{getPropertyForObject(option, settings.displayProp)}}</a>';
47                 }
48
49                 template += '</li>';
50                 template += '</div>';
51                 
52
53                 template += '<li class="divider" ng-show="settings.selectionLimit > 1"></li>';
54                 template += '<li role="presentation" ng-show="settings.selectionLimit > 1"><a role="menuitem">{{selectedModel.length}} {{texts.selectionOf}} {{settings.selectionLimit}} {{texts.selectionCount}}</a></li>';
55
56                 template += '</ul>';
57                 template += '</div>';
58
59                 element.html(template);
60             },
61             link: function ($scope, $element, $attrs) {
62                 var $dropdownTrigger = $element.children()[0];
63                 
64                 $scope.toggleDropdown = function () {
65                     $scope.open = !$scope.open;
66                 };
67
68                 $scope.checkboxClick = function ($event, id) {
69                     $scope.setSelectedItem(id);
70                     $event.stopImmediatePropagation();
71                 };
72
73                 $scope.externalEvents = {
74                     onItemSelect: angular.noop,
75                     onItemDeselect: angular.noop,
76                     onSelectAll: angular.noop,
77                     onDeselectAll: angular.noop,
78                     onInitDone: angular.noop,
79                     onMaxSelectionReached: angular.noop
80                 };
81
82                 $scope.settings = {
83                     dynamicTitle: true,
84                     scrollable: false,
85                     scrollableHeight: '300px',
86                     closeOnBlur: true,
87                     displayProp: 'label',
88                     idProp: 'id',
89                     externalIdProp: 'id',
90                     enableSearch: false,
91                     selectionLimit: 0,
92                     showCheckAll: false,
93                     showUncheckAll: false,
94                     closeOnSelect: false,
95                     buttonClasses: 'btn btn-default',
96                     closeOnDeselect: false,
97                     groupBy: $attrs.groupBy || undefined,
98                     groupByTextProvider: null,
99                     smartButtonMaxItems: 0,
100                     smartButtonTextConverter: angular.noop
101                 };
102
103                 $scope.texts = {
104                     checkAll: 'Check All',
105                     uncheckAll: 'Uncheck All',
106                     selectionCount: 'checked',
107                     selectionOf: '/',
108                     searchPlaceholder: 'Search...',
109                     buttonDefaultText: 'Select',
110                     dynamicButtonTextSuffix: 'checked'
111                 };
112
113                 $scope.searchFilter = $scope.searchFilter || '';
114
115                 if (angular.isDefined($scope.settings.groupBy)) {
116                     $scope.$watch('options', function (newValue) {
117                         if (angular.isDefined(newValue)) {
118                             $scope.orderedItems = $filter('orderBy')(newValue, $scope.settings.groupBy);
119                         }
120                     });
121                 }
122
123                 angular.extend($scope.settings, $scope.extraSettings || []);
124                 angular.extend($scope.externalEvents, $scope.events || []);
125                 angular.extend($scope.texts, $scope.translationTexts);
126
127                 $scope.singleSelection = $scope.settings.selectionLimit === 1;
128
129                 function getFindObj(id) {
130                     var findObj = {};
131
132                     if ($scope.settings.externalIdProp === '') {
133                         findObj[$scope.settings.idProp] = id;
134                     } else {
135                         findObj[$scope.settings.externalIdProp] = id;
136                     }
137
138                     return findObj;
139                 }
140
141                 function clearObject(object) {
142                     for (var prop in object) {
143                         delete object[prop];
144                     }
145                 }
146
147                 if ($scope.singleSelection) {
148                     if (angular.isArray($scope.selectedModel) && $scope.selectedModel.length === 0) {
149                         clearObject($scope.selectedModel);
150                     }
151                 }
152
153                 if ($scope.settings.closeOnBlur) {
154                     $document.on('click', function (e) {
155                         var target = e.target.parentElement;
156                         var parentFound = false;
157
158                         while (angular.isDefined(target) && target !== null && !parentFound) {
159                             if (_.contains(target.className.split(' '), 'multiselect-parent') && !parentFound) {
160                                 if(target === $dropdownTrigger) {
161                                     parentFound = true;
162                                 }
163                             }
164                             target = target.parentElement;
165                         }
166
167                         if (!parentFound) {
168                             $scope.$apply(function () {
169                                 $scope.open = false;
170                             });
171                         }
172                     });
173                 }
174
175                 $scope.getGroupTitle = function (groupValue) {
176                     if ($scope.settings.groupByTextProvider !== null) {
177                         return $scope.settings.groupByTextProvider(groupValue);
178                     }
179
180                     return groupValue;
181                 };
182
183                 $scope.getButtonText = function () {
184                     if ($scope.settings.dynamicTitle && ($scope.selectedModel.length > 0 || (angular.isObject($scope.selectedModel) && _.keys($scope.selectedModel).length > 0))) {
185                         if ($scope.settings.smartButtonMaxItems > 0) {
186                             var itemsText = [];
187
188                             angular.forEach($scope.options, function (optionItem) {
189                                 if ($scope.isChecked($scope.getPropertyForObject(optionItem, $scope.settings.idProp))) {
190                                     var displayText = $scope.getPropertyForObject(optionItem, $scope.settings.displayProp);
191                                     var converterResponse = $scope.settings.smartButtonTextConverter(displayText, optionItem);
192
193                                     itemsText.push(converterResponse ? converterResponse : displayText);
194                                 }
195                             });
196
197                             if ($scope.selectedModel.length > $scope.settings.smartButtonMaxItems) {
198                                 itemsText = itemsText.slice(0, $scope.settings.smartButtonMaxItems);
199                                 itemsText.push('...');
200                             }
201
202                             return itemsText.join(', ');
203                         } else {
204                             var totalSelected;
205
206                             if ($scope.singleSelection) {
207                                 totalSelected = ($scope.selectedModel !== null && angular.isDefined($scope.selectedModel[$scope.settings.idProp])) ? 1 : 0;
208                             } else {
209                                 totalSelected = angular.isDefined($scope.selectedModel) ? $scope.selectedModel.length : 0;
210                             }
211
212                             if (totalSelected === 0) {
213                                 return $scope.texts.buttonDefaultText;
214                             } else {
215                                 return totalSelected + ' ' + $scope.texts.dynamicButtonTextSuffix;
216                             }
217                         }
218                     } else {
219                         return $scope.texts.buttonDefaultText;
220                     }
221                 };
222
223                 $scope.getPropertyForObject = function (object, property) {
224                     if (angular.isDefined(object) && object.hasOwnProperty(property)) {
225                         return object[property];
226                     }
227
228                     return '';
229                 };
230
231                 $scope.selectAll = function () {
232                     $scope.deselectAll(false);
233                     $scope.externalEvents.onSelectAll();
234
235                     angular.forEach($scope.options, function (value) {
236                         $scope.setSelectedItem(value[$scope.settings.idProp], true);
237                     });
238                 };
239
240                 $scope.deselectAll = function (sendEvent) {
241                     sendEvent = sendEvent || true;
242
243                     if (sendEvent) {
244                         $scope.externalEvents.onDeselectAll();
245                     }
246
247                     if ($scope.singleSelection) {
248                         clearObject($scope.selectedModel);
249                     } else {
250                         $scope.selectedModel.splice(0, $scope.selectedModel.length);
251                     }
252                 };
253
254                 $scope.setSelectedItem = function (id, dontRemove) {
255                     var findObj = getFindObj(id);
256                     var finalObj = null;
257
258                     if ($scope.settings.externalIdProp === '') {
259                         finalObj = _.find($scope.options, findObj);
260                     } else {
261                         finalObj = findObj;
262                     }
263
264                     if ($scope.singleSelection) {
265                         clearObject($scope.selectedModel);
266                         angular.extend($scope.selectedModel, finalObj);
267                         $scope.externalEvents.onItemSelect(finalObj);
268
269                         return;
270                     }
271
272                     dontRemove = dontRemove || false;
273
274                     var exists = _.findIndex($scope.selectedModel, findObj) !== -1;
275
276                     if (!dontRemove && exists) {
277                         $scope.selectedModel.splice(_.findIndex($scope.selectedModel, findObj), 1);
278                         $scope.externalEvents.onItemDeselect(findObj);
279                     } else if (!exists && ($scope.settings.selectionLimit === 0 || $scope.selectedModel.length < $scope.settings.selectionLimit)) {
280                         $scope.selectedModel.push(finalObj);
281                         $scope.externalEvents.onItemSelect(finalObj);
282                     }
283                 };
284
285                 $scope.isChecked = function (id) {
286                     if ($scope.singleSelection) {
287                         return $scope.selectedModel !== null && angular.isDefined($scope.selectedModel[$scope.settings.idProp]) && $scope.selectedModel[$scope.settings.idProp] === getFindObj(id)[$scope.settings.idProp];
288                     }
289
290                     return _.findIndex($scope.selectedModel, getFindObj(id)) !== -1;
291                 };
292
293                 $scope.externalEvents.onInitDone();
294             }
295         };
296 }]);