3131 * --------------------------------------------------------------------------------
3232 */
3333
34- angular . module ( 'multi-select' , [ 'ng' ] ) . directive ( 'multiSelect' , [ '$sce' , function ( $sce ) {
34+ angular . module ( 'multi-select' , [ 'ng' ] ) . directive ( 'multiSelect' , [ '$sce' , '$filter' , function ( $sce , $filter ) {
3535 return {
3636 restrict :
3737 'AE' ,
@@ -52,47 +52,93 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
5252 maxLabels : '@' ,
5353 isDisabled : '=' ,
5454 directiveId : '@' ,
55- // JH DotComIt Added 5/8/2014
56- onPopupopen : '&onPopupopen' ,
57- onPopupclose : '&onPopupclose'
55+ helperElements : '@' ,
56+ onOpen : '&' ,
57+ onClose : '&' ,
58+ onBlur : '&' ,
59+ onFocus : '&'
5860 } ,
5961
6062 template :
61- '<span class="multiSelect inlineBlock">' +
62- '<button type="button" class="multiSelect button multiSelectButton" ng-click="toggleCheckboxes( $event ); refreshSelectedItems();" ng-bind-html="varButtonLabel">' +
63+ '<span class="multiSelect inlineBlock" >' +
64+ '<button type="button" class="multiSelect button multiSelectButton" ng-click="toggleCheckboxes( $event ); refreshSelectedItems();" ng-bind-html="varButtonLabel" ng-focus="onFocus()" ng-blur="onBlur()" >' +
6365 '</button>' +
6466 '<div class="multiSelect checkboxLayer hide">' +
6567 '<div class="multiSelect line">' +
66- '<span ng-if="!isDisabled">Select: </span>' +
67- '<button type="button" ng-click="select( \'all\' )" class="multiSelect helperButton" ng-if="!isDisabled && selectionMode.toUpperCase() != \'SINGLE\' ">All</button> ' +
68- '<button type="button" ng-click="select( \'none\' )" class="multiSelect helperButton" ng-if="!isDisabled && selectionMode.toUpperCase() != \'SINGLE\' ">None</button> ' +
69- '<button type="button" ng-click="select( \'reset\' )" class="multiSelect helperButton" ng-if="!isDisabled">Reset</button>' +
68+ '<span ng-if="!isDisabled && ( displayHelper( \'all\' ) || displayHelper( \'none\' ) || displayHelper( \'reset\' )) ">Select: </span>' +
69+ '<button type="button" ng-click="select( \'all\' )" class="multiSelect helperButton" ng-if="!isDisabled && displayHelper( \'all\' ) ">All</button> ' +
70+ '<button type="button" ng-click="select( \'none\' )" class="multiSelect helperButton" ng-if="!isDisabled && displayHelper( \'none\' ) ">None</button> ' +
71+ '<button type="button" ng-click="select( \'reset\' )" class="multiSelect helperButton" ng-if="!isDisabled && displayHelper( \'reset\' ) ">Reset</button>' +
7072 '</div>' +
71- '<div class="multiSelect line">' +
73+ '<div class="multiSelect line" ng-show="displayHelper( \'filter\' )" >' +
7274 'Filter: <input class="multiSelect" type="text" ng-model="labelFilter" />' +
7375 ' <button type="button" class="multiSelect helperButton" ng-click="labelFilter=\'\'">Clear</button>' +
7476 '</div>' +
75- '<div ng-repeat="item in inputModel | filter:labelFilter" ng-class="orientation" class="multiSelect multiSelectItem">' +
77+ '<div ng-repeat="item in (filteredModel = ( inputModel | filter:labelFilter )) " ng-class="orientation" class="multiSelect multiSelectItem">' +
7678 '<div class="multiSelect acol">' +
7779 '<div class="multiSelect" ng-show="item[ tickProperty ]">✔</div>' +
7880 '</div>' +
7981 '<div class="multiSelect acol">' +
8082 '<label class="multiSelect" ng-class="{checkboxSelected:item[ tickProperty ]}">' +
81- '<input class="multiSelect checkbox" type="checkbox" ng-disabled="itemIsDisabled( item )" ng-checked="item[ tickProperty ]" ng-click="syncItems( item, $event )" />' +
82- '<span class="multiSelect" ng-class="{disabled:itemIsDisabled( item )}" ng-bind-html="writeLabel( item, \'itemLabel\' )"></span>' +
83+ '<input class="multiSelect checkbox" type="checkbox" ng-disabled="itemIsDisabled( item )" ng-checked="item[ tickProperty ]" ng-click="syncItems( item, $event )"/>' +
84+ '<span class="multiSelect" ng-class="{disabled:itemIsDisabled( item )}" ng-bind-html="writeLabel( item, \'itemLabel\' )"></span>' +
8385 '</label> ' +
8486 '</div>' +
8587 '</div>' +
8688 '</div>' +
8789 '</span>' ,
8890
89- link : function ( $scope , element , attrs ) {
91+ link : function ( $scope , element , attrs ) {
9092
9193 $scope . selectedItems = [ ] ;
9294 $scope . backUp = [ ] ;
93- $scope . varButtonLabel = '' ;
95+ $scope . varButtonLabel = '' ;
96+ $scope . tabIndex = 0 ;
97+ $scope . tabables = null ;
98+ $scope . currentButton = null ;
99+
100+ // Show or hide a helper element
101+ $scope . displayHelper = function ( elementString ) {
102+ if ( typeof attrs . helperElements === 'undefined' ) {
103+ return true ;
104+ }
105+ switch ( elementString . toUpperCase ( ) ) {
106+ case 'ALL' :
107+ if ( attrs . selectionMode && $scope . selectionMode . toUpperCase ( ) === 'SINGLE' ) {
108+ return false ;
109+ }
110+ else {
111+ if ( attrs . helperElements && $scope . helperElements . toUpperCase ( ) . indexOf ( 'ALL' ) >= 0 ) {
112+ return true ;
113+ }
114+ }
115+ break ;
116+ case 'NONE' :
117+ if ( attrs . selectionMode && $scope . selectionMode . toUpperCase ( ) === 'SINGLE' ) {
118+ return false ;
119+ }
120+ else {
121+ if ( attrs . helperElements && $scope . helperElements . toUpperCase ( ) . indexOf ( 'NONE' ) >= 0 ) {
122+ return true ;
123+ }
124+ }
125+ break ;
126+ case 'RESET' :
127+ if ( attrs . helperElements && $scope . helperElements . toUpperCase ( ) . indexOf ( 'RESET' ) >= 0 ) {
128+ return true ;
129+ }
130+ break ;
131+ case 'FILTER' :
132+ if ( attrs . helperElements && $scope . helperElements . toUpperCase ( ) . indexOf ( 'FILTER' ) >= 0 ) {
133+ return true ;
134+ }
135+ break ;
136+ default :
137+ break ;
138+ }
139+ }
94140
95- // Checkbox is ticked
141+ // Call this function when a checkbox is ticked...
96142 $scope . syncItems = function ( item , e ) {
97143 index = $scope . inputModel . indexOf ( item ) ;
98144 $scope . inputModel [ index ] [ $scope . tickProperty ] = ! $scope . inputModel [ index ] [ $scope . tickProperty ] ;
@@ -107,8 +153,9 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
107153 }
108154 $scope . toggleCheckboxes ( e ) ;
109155 }
110-
111- $scope . refreshSelectedItems ( ) ;
156+
157+ $scope . refreshSelectedItems ( ) ;
158+ e . target . focus ( ) ;
112159 }
113160
114161 // 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
199246 return $sce . trustAsHtml ( label ) ;
200247 }
201248
202- // UI operations to show/hide checkboxes
249+ // UI operations to show/hide checkboxes based on click event..
203250 $scope . toggleCheckboxes = function ( e ) {
204251
205252 if ( e . target ) {
@@ -238,20 +285,19 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
238285 for ( i = 0 ; i < checkboxes . length ; i ++ ) {
239286 if ( i != multiSelectIndex ) {
240287 checkboxes [ i ] . className = 'multiSelect checkboxLayer hide' ;
241- // JH DotComIt 5/8/2014 Added method handler for closing the popup
242- $scope . onPopupclose ( ) ;
243288 }
244289 }
245290
246291 if ( checkboxes [ multiSelectIndex ] . className == 'multiSelect checkboxLayer hide' ) {
292+ $scope . currentButton = multiSelectButtons [ multiSelectIndex ] ;
247293 checkboxes [ multiSelectIndex ] . className = 'multiSelect checkboxLayer show' ;
248- // JH DotComIt 5/8/2014 Added method handler for opening the popup
249- $scope . onPopupopen ( ) ;
294+ // https://github.com/isteven/angular-multi-select/pull/5 - On open callback
295+ $scope . onOpen ( ) ;
250296 }
251297 else if ( checkboxes [ multiSelectIndex ] . className == 'multiSelect checkboxLayer show' ) {
252298 checkboxes [ multiSelectIndex ] . className = 'multiSelect checkboxLayer hide' ;
253- // JH DotComIt 5/8/2014 Added method handler for closing the popup
254- $scope . onPopupclose ( ) ;
299+ // https://github.com/isteven/angular-multi-select/pull/5 - On close callback
300+ $scope . onClose ( ) ;
255301 }
256302 }
257303 }
@@ -289,8 +335,8 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
289335 }
290336 } ) ;
291337 break ;
292- case 'RESET' :
293- $scope . inputModel = angular . copy ( $scope . backUp ) ;
338+ case 'RESET' :
339+ $scope . inputModel = angular . copy ( $scope . backUp ) ;
294340 break ;
295341 default :
296342 }
@@ -299,6 +345,7 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
299345
300346
301347 // Generic validation for required attributes
348+ // Might give false positives so just ignore if everything's alright.
302349 validate = function ( ) {
303350 if ( ! ( 'inputModel' in attrs ) ) {
304351 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
337384 } ) ;
338385 if ( notThere === true ) {
339386 console . log ( 'Multi-select error: property "' + missingLabel + '" is not available in the input model. (Name: ' + $scope . directiveId + ')' ) ;
340- }
341-
342- }
387+ }
388+ }
343389
344390 ///////////////////////
345391 // Logic starts here
346392 ///////////////////////
347393
348394 validate ( ) ;
349- $scope . refreshSelectedItems ( ) ;
350-
395+ $scope . refreshSelectedItems ( ) ;
396+
351397 // Watch for changes in input model (allow dynamic input)
352398 $scope . $watch ( 'inputModel' , function ( oldVal , newVal ) {
353399 if ( $scope . inputModel !== 'undefined' ) {
@@ -368,14 +414,12 @@ angular.module( 'multi-select', ['ng'] ).directive( 'multiSelect' , [ '$sce', fu
368414 var checkboxes = document . querySelectorAll ( '.checkboxLayer' ) ;
369415 if ( e . target . className . indexOf ( 'multiSelect' ) === - 1 ) {
370416 for ( i = 0 ; i < checkboxes . length ; i ++ ) {
371- checkboxes [ i ] . className = 'multiSelect checkboxLayer hide' ;
372- // JH DotComIt 5/8/2014 Added method handler for closing the popup
373- $scope . onPopupclose ( ) ;
417+ checkboxes [ i ] . className = 'multiSelect checkboxLayer hide' ;
374418 }
375419 e . stopPropagation ( ) ;
376420 }
377- } ) ;
378-
421+ } ) ;
422+
379423 // For IE8, perhaps. Not sure if this is really executed.
380424 if ( ! Array . prototype . indexOf ) {
381425 Array . prototype . indexOf = function ( what , i ) {
0 commit comments