3 var directiveModule = angular.module('angularjs-dropdown-multiselect-new', ['vs-repeat']);
5 directiveModule.directive('ngDropdownMultiselectNew', ['$filter', '$document', '$compile', '$parse',
6 function ($filter, $document, $compile, $parse) {
16 translationTexts: '=',
19 template: function (element, attrs) {
20 var checkboxes = attrs.checkboxes ? true : false;
21 var groups = attrs.groupBy ? true : false;
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()}} <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>';
32 template += '<div style="width:98%;" vs-repeat> ';
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">';
38 template += '<li role="presentation" ng-repeat="option in options| filter: searchFilter">';
41 template += '<a role="menuitem" tabindex="-1" ng-click="setSelectedItem(getPropertyForObject(option,settings.idProp))">';
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>';
46 template += '<span data-ng-class="{\'glyphicon glyphicon-ok\': isChecked(getPropertyForObject(option,settings.idProp))}"></span> {{getPropertyForObject(option, settings.displayProp)}}</a>';
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>';
59 element.html(template);
61 link: function ($scope, $element, $attrs) {
62 var $dropdownTrigger = $element.children()[0];
64 $scope.toggleDropdown = function () {
65 $scope.open = !$scope.open;
68 $scope.checkboxClick = function ($event, id) {
69 $scope.setSelectedItem(id);
70 $event.stopImmediatePropagation();
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
85 scrollableHeight: '300px',
93 showUncheckAll: false,
95 buttonClasses: 'btn btn-default',
96 closeOnDeselect: false,
97 groupBy: $attrs.groupBy || undefined,
98 groupByTextProvider: null,
99 smartButtonMaxItems: 0,
100 smartButtonTextConverter: angular.noop
104 checkAll: 'Check All',
105 uncheckAll: 'Uncheck All',
106 selectionCount: 'checked',
108 searchPlaceholder: 'Search...',
109 buttonDefaultText: 'Select',
110 dynamicButtonTextSuffix: 'checked'
113 $scope.searchFilter = $scope.searchFilter || '';
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);
123 angular.extend($scope.settings, $scope.extraSettings || []);
124 angular.extend($scope.externalEvents, $scope.events || []);
125 angular.extend($scope.texts, $scope.translationTexts);
127 $scope.singleSelection = $scope.settings.selectionLimit === 1;
129 function getFindObj(id) {
132 if ($scope.settings.externalIdProp === '') {
133 findObj[$scope.settings.idProp] = id;
135 findObj[$scope.settings.externalIdProp] = id;
141 function clearObject(object) {
142 for (var prop in object) {
147 if ($scope.singleSelection) {
148 if (angular.isArray($scope.selectedModel) && $scope.selectedModel.length === 0) {
149 clearObject($scope.selectedModel);
153 if ($scope.settings.closeOnBlur) {
154 $document.on('click', function (e) {
155 var target = e.target.parentElement;
156 var parentFound = false;
158 while (angular.isDefined(target) && target !== null && !parentFound) {
159 if (_.contains(target.className.split(' '), 'multiselect-parent') && !parentFound) {
160 if(target === $dropdownTrigger) {
164 target = target.parentElement;
168 $scope.$apply(function () {
175 $scope.getGroupTitle = function (groupValue) {
176 if ($scope.settings.groupByTextProvider !== null) {
177 return $scope.settings.groupByTextProvider(groupValue);
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) {
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);
193 itemsText.push(converterResponse ? converterResponse : displayText);
197 if ($scope.selectedModel.length > $scope.settings.smartButtonMaxItems) {
198 itemsText = itemsText.slice(0, $scope.settings.smartButtonMaxItems);
199 itemsText.push('...');
202 return itemsText.join(', ');
206 if ($scope.singleSelection) {
207 totalSelected = ($scope.selectedModel !== null && angular.isDefined($scope.selectedModel[$scope.settings.idProp])) ? 1 : 0;
209 totalSelected = angular.isDefined($scope.selectedModel) ? $scope.selectedModel.length : 0;
212 if (totalSelected === 0) {
213 return $scope.texts.buttonDefaultText;
215 return totalSelected + ' ' + $scope.texts.dynamicButtonTextSuffix;
219 return $scope.texts.buttonDefaultText;
223 $scope.getPropertyForObject = function (object, property) {
224 if (angular.isDefined(object) && object.hasOwnProperty(property)) {
225 return object[property];
231 $scope.selectAll = function () {
232 $scope.deselectAll(false);
233 $scope.externalEvents.onSelectAll();
235 angular.forEach($scope.options, function (value) {
236 $scope.setSelectedItem(value[$scope.settings.idProp], true);
240 $scope.deselectAll = function (sendEvent) {
241 sendEvent = sendEvent || true;
244 $scope.externalEvents.onDeselectAll();
247 if ($scope.singleSelection) {
248 clearObject($scope.selectedModel);
250 $scope.selectedModel.splice(0, $scope.selectedModel.length);
254 $scope.setSelectedItem = function (id, dontRemove) {
255 var findObj = getFindObj(id);
258 if ($scope.settings.externalIdProp === '') {
259 finalObj = _.find($scope.options, findObj);
264 if ($scope.singleSelection) {
265 clearObject($scope.selectedModel);
266 angular.extend($scope.selectedModel, finalObj);
267 $scope.externalEvents.onItemSelect(finalObj);
272 dontRemove = dontRemove || false;
274 var exists = _.findIndex($scope.selectedModel, findObj) !== -1;
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);
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];
290 return _.findIndex($scope.selectedModel, getFindObj(id)) !== -1;
293 $scope.externalEvents.onInitDone();