summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--angular-multi-select.css23
-rw-r--r--angular-multi-select.js120
-rw-r--r--angular-multi-select.min.js2
4 files changed, 102 insertions, 47 deletions
diff --git a/README.md b/README.md
index eb7c24d..3d6ccfe 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-Angular Multi Select
-====================
+Angular MultiSelect
+==
An AngularJS directive which creates a dropdown button with multiple or single selections.
Allows you to customize your labels and use some HTML tags in the data. Fully configurable through element attributes and CSS.
Doesn't require jQuery and works well with other Javascript libraries.
diff --git a/angular-multi-select.css b/angular-multi-select.css
index 7895301..9f4c564 100644
--- a/angular-multi-select.css
+++ b/angular-multi-select.css
@@ -74,7 +74,7 @@
border-top: 4px solid #333;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
- border-bottom: 0 dotted;
+ border-bottom: 0 dotted;
}
.multiSelect.multiSelectItem {
@@ -110,11 +110,6 @@ label.multiSelect span {
user-select: none;
}
-label.multiSelect span:hover{
- cursor: pointer;
- color: #333;
-}
-
/* hide the checkbox away */
.multiSelect .checkbox {
position: absolute;
@@ -138,6 +133,22 @@ label.multiSelect span:hover{
margin-left: 1px;
}
+/* On mouse over and focus */
+label.multiSelect input:focus ~ span::after,
+label.multiSelect span:focus::after,
+label.multiSelect span:hover::after {
+ /* Enable this if you want some arrow pointer */
+ /* content: ' \00AB'; */
+}
+
+label.multiSelect input:focus ~ span,
+label.multiSelect span:hover {
+ color: #333;
+ cursor: pointer;
+ /* Enable this if you want some arrow pointer */
+ /* content: ' \00AB'; */
+}
+
/* for checkboxes currently selected */
.multiSelect .checkboxSelected {
color: #000;
diff --git a/angular-multi-select.js b/angular-multi-select.js
index fdb1bed..1197874 100644
--- a/angular-multi-select.js
+++ b/angular-multi-select.js
@@ -31,7 +31,7 @@
* --------------------------------------------------------------------------------
*/
-angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', function ( $sce ) {
+angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', '$filter', function ( $sce, $filter ) {
return {
restrict:
'AE',
@@ -52,47 +52,93 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
maxLabels : '@',
isDisabled : '=',
directiveId : '@',
- // JH DotComIt Added 5/8/2014
- onPopupopen: '&onPopupopen',
- onPopupclose: '&onPopupclose'
+ helperElements : '@',
+ onOpen : '&',
+ onClose : '&',
+ onBlur : '&',
+ onFocus : '&'
},
template:
- '<span class="multiSelect inlineBlock">' +
- '<button type="button" class="multiSelect button multiSelectButton" ng-click="toggleCheckboxes( $event ); refreshSelectedItems();" ng-bind-html="varButtonLabel">' +
+ '<span class="multiSelect inlineBlock" >' +
+ '<button type="button" class="multiSelect button multiSelectButton" ng-click="toggleCheckboxes( $event ); refreshSelectedItems();" ng-bind-html="varButtonLabel" ng-focus="onFocus()" ng-blur="onBlur()">' +
'</button>' +
'<div class="multiSelect checkboxLayer hide">' +
'<div class="multiSelect line">' +
- '<span ng-if="!isDisabled">Select: &nbsp;</span>' +
- '<button type="button" ng-click="select( \'all\' )" class="multiSelect helperButton" ng-if="!isDisabled && selectionMode.toUpperCase() != \'SINGLE\'">All</button> ' +
- '<button type="button" ng-click="select( \'none\' )" class="multiSelect helperButton" ng-if="!isDisabled && selectionMode.toUpperCase() != \'SINGLE\'">None</button> ' +
- '<button type="button" ng-click="select( \'reset\' )" class="multiSelect helperButton" ng-if="!isDisabled">Reset</button>' +
+ '<span ng-if="!isDisabled && ( displayHelper( \'all\' ) || displayHelper( \'none\' ) || displayHelper( \'reset\' ))">Select: &nbsp;</span>' +
+ '<button type="button" ng-click="select( \'all\' )" class="multiSelect helperButton" ng-if="!isDisabled && displayHelper( \'all\' )">All</button> ' +
+ '<button type="button" ng-click="select( \'none\' )" class="multiSelect helperButton" ng-if="!isDisabled && displayHelper( \'none\' )">None</button> ' +
+ '<button type="button" ng-click="select( \'reset\' )" class="multiSelect helperButton" ng-if="!isDisabled && displayHelper( \'reset\' )">Reset</button>' +
'</div>' +
- '<div class="multiSelect line">' +
+ '<div class="multiSelect line" ng-show="displayHelper( \'filter\' )">' +
'Filter: <input class="multiSelect" type="text" ng-model="labelFilter" />' +
'&nbsp;<button type="button" class="multiSelect helperButton" ng-click="labelFilter=\'\'">Clear</button>' +
'</div>' +
- '<div ng-repeat="item in inputModel | filter:labelFilter" ng-class="orientation" class="multiSelect multiSelectItem">' +
+ '<div ng-repeat="item in (filteredModel = (inputModel | filter:labelFilter ))" ng-class="orientation" class="multiSelect multiSelectItem">' +
'<div class="multiSelect acol">' +
'<div class="multiSelect" ng-show="item[ tickProperty ]">&#10004;</div>' +
'</div>' +
'<div class="multiSelect acol">' +
'<label class="multiSelect" ng-class="{checkboxSelected:item[ tickProperty ]}">' +
- '<input class="multiSelect checkbox" type="checkbox" ng-disabled="itemIsDisabled( item )" ng-checked="item[ tickProperty ]" ng-click="syncItems( item, $event )" />' +
- '<span class="multiSelect" ng-class="{disabled:itemIsDisabled( item )}" ng-bind-html="writeLabel( item, \'itemLabel\' )"></span>' +
+ '<input class="multiSelect checkbox" type="checkbox" ng-disabled="itemIsDisabled( item )" ng-checked="item[ tickProperty ]" ng-click="syncItems( item, $event )"/>' +
+ '<span class="multiSelect" ng-class="{disabled:itemIsDisabled( item )}" ng-bind-html="writeLabel( item, \'itemLabel\' )"></span>' +
'</label>&nbsp;&nbsp;' +
'</div>' +
'</div>' +
'</div>' +
'</span>',
- link: function ( $scope, element, attrs ) {
+ link: function ( $scope, element, attrs ) {
$scope.selectedItems = [];
$scope.backUp = [];
- $scope.varButtonLabel = '';
+ $scope.varButtonLabel = '';
+ $scope.tabIndex = 0;
+ $scope.tabables = null;
+ $scope.currentButton = null;
+
+ // Show or hide a helper element
+ $scope.displayHelper = function( elementString ) {
+ if ( typeof attrs.helperElements === 'undefined' ) {
+ return true;
+ }
+ switch( elementString.toUpperCase() ) {
+ case 'ALL':
+ if ( attrs.selectionMode && $scope.selectionMode.toUpperCase() === 'SINGLE' ) {
+ return false;
+ }
+ else {
+ if ( attrs.helperElements && $scope.helperElements.toUpperCase().indexOf( 'ALL' ) >= 0 ) {
+ return true;
+ }
+ }
+ break;
+ case 'NONE':
+ if ( attrs.selectionMode && $scope.selectionMode.toUpperCase() === 'SINGLE' ) {
+ return false;
+ }
+ else {
+ if ( attrs.helperElements && $scope.helperElements.toUpperCase().indexOf( 'NONE' ) >= 0 ) {
+ return true;
+ }
+ }
+ break;
+ case 'RESET':
+ if ( attrs.helperElements && $scope.helperElements.toUpperCase().indexOf( 'RESET' ) >= 0 ) {
+ return true;
+ }
+ break;
+ case 'FILTER':
+ if ( attrs.helperElements && $scope.helperElements.toUpperCase().indexOf( 'FILTER' ) >= 0 ) {
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
- // Checkbox is ticked
+ // Call this function when a checkbox is ticked...
$scope.syncItems = function( item, e ) {
index = $scope.inputModel.indexOf( item );
$scope.inputModel[ index ][ $scope.tickProperty ] = !$scope.inputModel[ index ][ $scope.tickProperty ];
@@ -107,8 +153,9 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
}
$scope.toggleCheckboxes( e );
}
-
- $scope.refreshSelectedItems();
+
+ $scope.refreshSelectedItems();
+ e.target.focus();
}
// Refresh the button to display the selected items and push into output model if specified
@@ -199,7 +246,7 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
return $sce.trustAsHtml( label );
}
- // UI operations to show/hide checkboxes
+ // UI operations to show/hide checkboxes based on click event..
$scope.toggleCheckboxes = function( e ) {
if ( e.target ) {
@@ -238,20 +285,19 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
for( i=0; i < checkboxes.length; i++ ) {
if ( i != multiSelectIndex ) {
checkboxes[i].className = 'multiSelect checkboxLayer hide';
- // JH DotComIt 5/8/2014 Added method handler for closing the popup
- $scope.onPopupclose();
}
}
if ( checkboxes[ multiSelectIndex ].className == 'multiSelect checkboxLayer hide' ) {
+ $scope.currentButton = multiSelectButtons[ multiSelectIndex ];
checkboxes[ multiSelectIndex ].className = 'multiSelect checkboxLayer show';
- // JH DotComIt 5/8/2014 Added method handler for opening the popup
- $scope.onPopupopen();
+ // https://github.com/isteven/angular-multi-select/pull/5 - On open callback
+ $scope.onOpen();
}
else if ( checkboxes[ multiSelectIndex ].className == 'multiSelect checkboxLayer show' ) {
checkboxes[ multiSelectIndex ].className = 'multiSelect checkboxLayer hide';
- // JH DotComIt 5/8/2014 Added method handler for closing the popup
- $scope.onPopupclose();
+ // https://github.com/isteven/angular-multi-select/pull/5 - On close callback
+ $scope.onClose();
}
}
}
@@ -289,8 +335,8 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
}
});
break;
- case 'RESET':
- $scope.inputModel = angular.copy( $scope.backUp );
+ case 'RESET':
+ $scope.inputModel = angular.copy( $scope.backUp );
break;
default:
}
@@ -299,6 +345,7 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
// Generic validation for required attributes
+ // Might give false positives so just ignore if everything's alright.
validate = function() {
if ( !( 'inputModel' in attrs )) {
console.log( 'Multi-select error: input-model is not defined! (ID: ' + $scope.directiveId + ')' );
@@ -337,17 +384,16 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
});
if ( notThere === true ) {
console.log( 'Multi-select error: property "' + missingLabel + '" is not available in the input model. (Name: ' + $scope.directiveId + ')' );
- }
-
- }
+ }
+ }
///////////////////////
// Logic starts here
///////////////////////
validate();
- $scope.refreshSelectedItems();
-
+ $scope.refreshSelectedItems();
+
// Watch for changes in input model (allow dynamic input)
$scope.$watch( 'inputModel' , function( oldVal, newVal ) {
if ( $scope.inputModel !== 'undefined' ) {
@@ -368,14 +414,12 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
var checkboxes = document.querySelectorAll( '.checkboxLayer' );
if ( e.target.className.indexOf( 'multiSelect' ) === -1 ) {
for( i=0; i < checkboxes.length; i++ ) {
- checkboxes[i].className = 'multiSelect checkboxLayer hide';
- // JH DotComIt 5/8/2014 Added method handler for closing the popup
- $scope.onPopupclose();
+ checkboxes[i].className = 'multiSelect checkboxLayer hide';
}
e.stopPropagation();
}
- });
-
+ });
+
// For IE8, perhaps. Not sure if this is really executed.
if ( !Array.prototype.indexOf ) {
Array.prototype.indexOf = function(what, i) {
diff --git a/angular-multi-select.min.js b/angular-multi-select.min.js
index 14d1292..d2b7980 100644
--- a/angular-multi-select.min.js
+++ b/angular-multi-select.min.js
@@ -4,4 +4,4 @@
* http://github.com/isteven/angular-multi-select
* Copyright (c) 2014 Ignatius Steven
*/
-angular.module("multi-select",["ng"]).directive("multiSelect",["$sce",function(a){return{restrict:"AE",replace:true,scope:{inputModel:"=",outputModel:"=",buttonLabel:"@",selectionMode:"@",itemLabel:"@",tickProperty:"@",disableProperty:"@",orientation:"@",maxLabels:"@",isDisabled:"=",directiveId:"@"},template:'<span class="multiSelect inlineBlock"><button type="button" class="multiSelect button multiSelectButton" ng-click="toggleCheckboxes( $event ); refreshSelectedItems();" ng-bind-html="varButtonLabel"></button><div class="multiSelect checkboxLayer hide"><div class="multiSelect line"><span ng-if="!isDisabled">Select: &nbsp;</span><button type="button" ng-click="select( \'all\' )" class="multiSelect helperButton" ng-if="!isDisabled && selectionMode.toUpperCase() != \'SINGLE\'">All</button> <button type="button" ng-click="select( \'none\' )" class="multiSelect helperButton" ng-if="!isDisabled && selectionMode.toUpperCase() != \'SINGLE\'">None</button> <button type="button" ng-click="select( \'reset\' )" class="multiSelect helperButton" ng-if="!isDisabled">Reset</button></div><div class="multiSelect line">Filter: <input class="multiSelect" type="text" ng-model="labelFilter" />&nbsp;<button type="button" class="multiSelect helperButton" ng-click="labelFilter=\'\'">Clear</button></div><div ng-repeat="item in inputModel | filter:labelFilter" ng-class="orientation" class="multiSelect multiSelectItem"><div class="multiSelect acol"><div class="multiSelect" ng-show="item[ tickProperty ]">&#10004;</div></div><div class="multiSelect acol"><label class="multiSelect" ng-class="{checkboxSelected:item[ tickProperty ]}"><input class="multiSelect checkbox" type="checkbox" ng-disabled="itemIsDisabled( item )" ng-checked="item[ tickProperty ]" ng-click="syncItems( item, $event )" /><span class="multiSelect" ng-class="{disabled:itemIsDisabled( item )}" ng-bind-html="writeLabel( item, \'itemLabel\' )"></span></label>&nbsp;&nbsp;</div></div></div></span>',link:function(b,d,c){b.selectedItems=[];b.backUp=[];b.varButtonLabel="";b.syncItems=function(f,g){index=b.inputModel.indexOf(f);b.inputModel[index][b.tickProperty]=!b.inputModel[index][b.tickProperty];if(c.selectionMode&&b.selectionMode.toUpperCase()==="SINGLE"){b.inputModel[index][b.tickProperty]=true;for(i=0;i<b.inputModel.length;i++){if(i!==index){b.inputModel[i][b.tickProperty]=false}}b.toggleCheckboxes(g)}b.refreshSelectedItems()};b.refreshSelectedItems=function(){b.varButtonLabel="";b.selectedItems=[];ctr=0;angular.forEach(b.inputModel,function(g,f){if(typeof g!=="undefined"){if(g[b.tickProperty]===true||g[b.tickProperty]==="true"){b.selectedItems.push(g)}}});if(typeof c.outputModel!=="undefined"){b.outputModel=angular.copy(b.selectedItems)}if(b.selectedItems.length===0){b.varButtonLabel="None selected"}else{var e=b.selectedItems.length;if(typeof b.maxLabels!=="undefined"&&b.maxLabels!==""&&b.maxLabels!=="0"){e=b.maxLabels}if(b.selectedItems.length>e){b.more=true}else{b.more=false}angular.forEach(b.selectedItems,function(g,f){if(typeof g!=="undefined"){if(ctr<e){b.varButtonLabel+=(b.varButtonLabel.length>0?", ":"")+b.writeLabel(g,"buttonLabel")}ctr++}});if(b.more===true){b.varButtonLabel+=", ... (Total: "+b.selectedItems.length+")"}}b.varButtonLabel=a.trustAsHtml(b.varButtonLabel+'<span class="multiSelect caret"></span>')};b.itemIsDisabled=function(e){if(e[b.disableProperty]===true){return true}else{if(b.isDisabled===true){return true}else{return false}}};b.writeLabel=function(h,g){var f="";var e=b[g].split(" ");angular.forEach(e,function(j,k){if(typeof j!=="undefined"){angular.forEach(h,function(l,m){if(m==j){f+=" "+l}})}});return a.trustAsHtml(f)};b.toggleCheckboxes=function(j){if(j.target){if(j.target.tagName.toUpperCase()!=="BUTTON"&&j.target.className.indexOf("multiSelectButton")<0){if(c.selectionMode&&b.selectionMode.toUpperCase()==="SINGLE"){if(j.target.tagName.toUpperCase()==="INPUT"){j=b.findUpTag(j.target,"div","checkboxLayer");j=j.previousSibling}}else{j=b.findUpTag(j.target,"button","multiSelectButton")}}else{j=j.target}}b.labelFilter="";var g=-1;var h=document.querySelectorAll(".checkboxLayer");var f=document.querySelectorAll(".multiSelectButton");for(i=0;i<f.length;i++){if(j===f[i]){g=i;break}}if(g>-1){for(i=0;i<h.length;i++){if(i!=g){h[i].className="multiSelect checkboxLayer hide"}}if(h[g].className=="multiSelect checkboxLayer hide"){h[g].className="multiSelect checkboxLayer show"}else{if(h[g].className=="multiSelect checkboxLayer show"){h[g].className="multiSelect checkboxLayer hide"}}}};b.findUpTag=function(g,e,f){while(g.parentNode){g=g.parentNode;if(typeof g.tagName!=="undefined"){if(g.tagName.toUpperCase()===e.toUpperCase()&&g.className.indexOf(f)>-1){return g}}}return null};b.select=function(f){var e=[];switch(f.toUpperCase()){case"ALL":angular.forEach(b.inputModel,function(h,g){if(typeof h!=="undefined"&&h[b.disableProperty]!==true){h[b.tickProperty]=true}});break;case"NONE":angular.forEach(b.inputModel,function(h,g){if(typeof h!=="undefined"&&h[b.disableProperty]!==true){h[b.tickProperty]=false}});break;case"RESET":b.inputModel=angular.copy(b.backUp);break;default:}b.refreshSelectedItems()};validate=function(){if(!("inputModel" in c)){console.log("Multi-select error: input-model is not defined! (ID: "+b.directiveId+")")}if(!("buttonLabel" in c)){console.log("Multi-select error: button-label is not defined! (ID: "+b.directiveId+")")}if(!("itemLabel" in c)){console.log("Multi-select error: item-label is not defined! (ID: "+b.directiveId+")")}if(!("tickProperty" in c)){console.log("Multi-select error: tick-property is not defined! (ID: "+b.directiveId+")")}};validateProperties=function(f,h){var g=false;var e="";angular.forEach(f,function(j,k){if(typeof j!=="undefined"){var l=true;angular.forEach(h,function(m,n){if(typeof m!=="undefined"&&l){if(!(j in m)){g=true;l=false;missingLabel=j}}})}});if(g===true){console.log('Multi-select error: property "'+missingLabel+'" is not available in the input model. (Name: '+b.directiveId+")")}};validate();b.refreshSelectedItems();b.$watch("inputModel",function(e,f){if(b.inputModel!=="undefined"){validateProperties(b.itemLabel.split(" "),b.inputModel);validateProperties(new Array(b.tickProperty),b.inputModel)}b.backUp=angular.copy(b.inputModel);b.refreshSelectedItems()});b.$watch("isDisabled",function(e){b.isDisabled=e});angular.element(document).bind("click",function(g){var f=document.querySelectorAll(".checkboxLayer");if(g.target.className.indexOf("multiSelect")===-1){for(i=0;i<f.length;i++){f[i].className="multiSelect checkboxLayer hide"}g.stopPropagation()}});if(!Array.prototype.indexOf){Array.prototype.indexOf=function(g,f){f=f||0;var e=this.length;while(f<e){if(this[f]===g){return f}++f}return -1}}}}}]);
+angular.module("multi-select",["ng"]).directive("multiSelect",["$sce","$filter",function(e,t){return{restrict:"AE",replace:true,scope:{inputModel:"=",outputModel:"=",buttonLabel:"@",selectionMode:"@",itemLabel:"@",tickProperty:"@",disableProperty:"@",orientation:"@",maxLabels:"@",isDisabled:"=",directiveId:"@",helperElements:"@",onOpen:"&",onClose:"&",onBlur:"&",onFocus:"&"},template:'<span class="multiSelect inlineBlock" >'+'<button type="button" class="multiSelect button multiSelectButton" ng-click="toggleCheckboxes( $event ); refreshSelectedItems();" ng-bind-html="varButtonLabel" ng-focus="onFocus()" ng-blur="onBlur()">'+"</button>"+'<div class="multiSelect checkboxLayer hide">'+'<div class="multiSelect line">'+"<span ng-if=\"!isDisabled && ( displayHelper( 'all' ) || displayHelper( 'none' ) || displayHelper( 'reset' ))\">Select: &nbsp;</span>"+'<button type="button" ng-click="select( \'all\' )" class="multiSelect helperButton" ng-if="!isDisabled && displayHelper( \'all\' )">All</button> '+'<button type="button" ng-click="select( \'none\' )" class="multiSelect helperButton" ng-if="!isDisabled && displayHelper( \'none\' )">None</button> '+'<button type="button" ng-click="select( \'reset\' )" class="multiSelect helperButton" ng-if="!isDisabled && displayHelper( \'reset\' )">Reset</button>'+"</div>"+'<div class="multiSelect line" ng-show="displayHelper( \'filter\' )">'+'Filter: <input class="multiSelect" type="text" ng-model="labelFilter" />'+'&nbsp;<button type="button" class="multiSelect helperButton" ng-click="labelFilter=\'\'">Clear</button>'+"</div>"+'<div ng-repeat="item in (filteredModel = (inputModel | filter:labelFilter ))" ng-class="orientation" class="multiSelect multiSelectItem">'+'<div class="multiSelect acol">'+'<div class="multiSelect" ng-show="item[ tickProperty ]">&#10004;</div>'+"</div>"+'<div class="multiSelect acol">'+'<label class="multiSelect" ng-class="{checkboxSelected:item[ tickProperty ]}">'+'<input class="multiSelect checkbox" type="checkbox" ng-disabled="itemIsDisabled( item )" ng-checked="item[ tickProperty ]" ng-click="syncItems( item, $event )"/>'+'<span class="multiSelect" ng-class="{disabled:itemIsDisabled( item )}" ng-bind-html="writeLabel( item, \'itemLabel\' )"></span>'+"</label>&nbsp;&nbsp;"+"</div>"+"</div>"+"</div>"+"</span>",link:function(t,n,r){t.selectedItems=[];t.backUp=[];t.varButtonLabel="";t.tabIndex=0;t.tabables=null;t.currentButton=null;t.displayHelper=function(e){if(typeof r.helperElements==="undefined"){return true}switch(e.toUpperCase()){case"ALL":if(r.selectionMode&&t.selectionMode.toUpperCase()==="SINGLE"){return false}else{if(r.helperElements&&t.helperElements.toUpperCase().indexOf("ALL")>=0){return true}}break;case"NONE":if(r.selectionMode&&t.selectionMode.toUpperCase()==="SINGLE"){return false}else{if(r.helperElements&&t.helperElements.toUpperCase().indexOf("NONE")>=0){return true}}break;case"RESET":if(r.helperElements&&t.helperElements.toUpperCase().indexOf("RESET")>=0){return true}break;case"FILTER":if(r.helperElements&&t.helperElements.toUpperCase().indexOf("FILTER")>=0){return true}break;default:break}};t.syncItems=function(e,n){index=t.inputModel.indexOf(e);t.inputModel[index][t.tickProperty]=!t.inputModel[index][t.tickProperty];if(r.selectionMode&&t.selectionMode.toUpperCase()==="SINGLE"){t.inputModel[index][t.tickProperty]=true;for(i=0;i<t.inputModel.length;i++){if(i!==index){t.inputModel[i][t.tickProperty]=false}}t.toggleCheckboxes(n)}t.refreshSelectedItems();n.target.focus()};t.refreshSelectedItems=function(){t.varButtonLabel="";t.selectedItems=[];ctr=0;angular.forEach(t.inputModel,function(e,n){if(typeof e!=="undefined"){if(e[t.tickProperty]===true||e[t.tickProperty]==="true"){t.selectedItems.push(e)}}});if(typeof r.outputModel!=="undefined"){t.outputModel=angular.copy(t.selectedItems)}if(t.selectedItems.length===0){t.varButtonLabel="None selected"}else{var n=t.selectedItems.length;if(typeof t.maxLabels!=="undefined"&&t.maxLabels!==""&&t.maxLabels!=="0"){n=t.maxLabels}if(t.selectedItems.length>n){t.more=true}else{t.more=false}angular.forEach(t.selectedItems,function(e,r){if(typeof e!=="undefined"){if(ctr<n){t.varButtonLabel+=(t.varButtonLabel.length>0?", ":"")+t.writeLabel(e,"buttonLabel")}ctr++}});if(t.more===true){t.varButtonLabel+=", ... (Total: "+t.selectedItems.length+")"}}t.varButtonLabel=e.trustAsHtml(t.varButtonLabel+'<span class="multiSelect caret"></span>')};t.itemIsDisabled=function(e){if(e[t.disableProperty]===true){return true}else{if(t.isDisabled===true){return true}else{return false}}};t.writeLabel=function(n,r){var i="";var s=t[r].split(" ");angular.forEach(s,function(e,t){if(typeof e!=="undefined"){angular.forEach(n,function(t,n){if(n==e){i+=" "+t}})}});return e.trustAsHtml(i)};t.toggleCheckboxes=function(e){if(e.target){if(e.target.tagName.toUpperCase()!=="BUTTON"&&e.target.className.indexOf("multiSelectButton")<0){if(r.selectionMode&&t.selectionMode.toUpperCase()==="SINGLE"){if(e.target.tagName.toUpperCase()==="INPUT"){e=t.findUpTag(e.target,"div","checkboxLayer");e=e.previousSibling}}else{e=t.findUpTag(e.target,"button","multiSelectButton")}}else{e=e.target}}t.labelFilter="";var n=-1;var s=document.querySelectorAll(".checkboxLayer");var o=document.querySelectorAll(".multiSelectButton");for(i=0;i<o.length;i++){if(e===o[i]){n=i;break}}if(n>-1){for(i=0;i<s.length;i++){if(i!=n){s[i].className="multiSelect checkboxLayer hide"}}if(s[n].className=="multiSelect checkboxLayer hide"){t.currentButton=o[n];s[n].className="multiSelect checkboxLayer show";t.onOpen()}else if(s[n].className=="multiSelect checkboxLayer show"){s[n].className="multiSelect checkboxLayer hide";t.onClose()}}};t.findUpTag=function(e,t,n){while(e.parentNode){e=e.parentNode;if(typeof e.tagName!=="undefined"){if(e.tagName.toUpperCase()===t.toUpperCase()&&e.className.indexOf(n)>-1){return e}}}return null};t.select=function(e){var n=[];switch(e.toUpperCase()){case"ALL":angular.forEach(t.inputModel,function(e,n){if(typeof e!=="undefined"&&e[t.disableProperty]!==true){e[t.tickProperty]=true}});break;case"NONE":angular.forEach(t.inputModel,function(e,n){if(typeof e!=="undefined"&&e[t.disableProperty]!==true){e[t.tickProperty]=false}});break;case"RESET":t.inputModel=angular.copy(t.backUp);break;default:}t.refreshSelectedItems()};validate=function(){if(!("inputModel"in r)){console.log("Multi-select error: input-model is not defined! (ID: "+t.directiveId+")")}if(!("buttonLabel"in r)){console.log("Multi-select error: button-label is not defined! (ID: "+t.directiveId+")")}if(!("itemLabel"in r)){console.log("Multi-select error: item-label is not defined! (ID: "+t.directiveId+")")}if(!("tickProperty"in r)){console.log("Multi-select error: tick-property is not defined! (ID: "+t.directiveId+")")}};validateProperties=function(e,n){var r=false;var i="";angular.forEach(e,function(e,t){if(typeof e!=="undefined"){var i=true;angular.forEach(n,function(t,n){if(typeof t!=="undefined"&&i){if(!(e in t)){r=true;i=false;missingLabel=e}}})}});if(r===true){console.log('Multi-select error: property "'+missingLabel+'" is not available in the input model. (Name: '+t.directiveId+")")}};validate();t.refreshSelectedItems();t.$watch("inputModel",function(e,n){if(t.inputModel!=="undefined"){validateProperties(t.itemLabel.split(" "),t.inputModel);validateProperties(new Array(t.tickProperty),t.inputModel)}t.backUp=angular.copy(t.inputModel);t.refreshSelectedItems()});t.$watch("isDisabled",function(e){t.isDisabled=e});angular.element(document).bind("click",function(e){var t=document.querySelectorAll(".checkboxLayer");if(e.target.className.indexOf("multiSelect")===-1){for(i=0;i<t.length;i++){t[i].className="multiSelect checkboxLayer hide"}e.stopPropagation()}});if(!Array.prototype.indexOf){Array.prototype.indexOf=function(e,t){t=t||0;var n=this.length;while(t<n){if(this[t]===e)return t;++t}return-1}}}}}])