@@ -15,6 +15,8 @@ describe('ui-select tests', function () {
1515 Escape : 27
1616 } ;
1717
18+ var defaultPlaceholder = 'Pick one...' ;
19+
1820 function isNil ( value ) {
1921 return angular . isUndefined ( value ) || value === null ;
2022 }
@@ -191,6 +193,10 @@ describe('ui-select tests', function () {
191193 return $ ( el ) . find ( '.ui-select-match > span:first > span[ng-transclude]:not(.ng-hide)' ) . text ( ) ;
192194 }
193195
196+ function getMatchPlaceholder ( el ) {
197+ return el . find ( '.ui-select-search' ) . attr ( 'placeholder' )
198+ }
199+
194200 function clickItem ( el , text ) {
195201
196202 if ( ! isDropdownOpened ( el ) ) {
@@ -740,6 +746,28 @@ describe('ui-select tests', function () {
740746 el2 . remove ( ) ;
741747 } ) ;
742748
749+ it ( 'should close an opened select clicking outside with stopPropagation()' , function ( ) {
750+ var el1 = createUiSelect ( ) ;
751+ var el2 = $ ( '<div></div>' ) ;
752+ el1 . appendTo ( document . body ) ;
753+ el2 . appendTo ( document . body ) ;
754+
755+ el2 . on ( 'click' , function ( e ) {
756+ e . stopPropagation ( )
757+ } ) ;
758+
759+ expect ( isDropdownOpened ( el1 ) ) . toEqual ( false ) ;
760+ clickMatch ( el1 ) ;
761+ expect ( isDropdownOpened ( el1 ) ) . toEqual ( true ) ;
762+
763+ // Using a native dom click() to make sure the test fails when it should.
764+ el2 [ 0 ] . click ( ) ;
765+
766+ expect ( isDropdownOpened ( el1 ) ) . toEqual ( false ) ;
767+ el1 . remove ( ) ;
768+ el2 . remove ( ) ;
769+ } ) ;
770+
743771 it ( 'should bind model correctly (with object as source)' , function ( ) {
744772 var el = compileTemplate (
745773 '<ui-select ng-model="selection.selected"> \
@@ -846,6 +874,20 @@ describe('ui-select tests', function () {
846874 expect ( getMatchLabel ( el ) ) . toEqual ( '-- None Selected --' ) ;
847875 } ) ;
848876
877+ it ( 'should not have active option when model cleared' , function ( ) {
878+ var el = createUiSelect ( ) ;
879+
880+ clickItem ( el , 'Samantha' ) ;
881+ expect ( el . scope ( ) . $select . activeIndex ) . toBe ( 5 ) ;
882+
883+ scope . selection . selected = null ;
884+ scope . $digest ( ) ;
885+
886+ el . find ( ".ui-select-toggle" ) . click ( ) ;
887+
888+ expect ( el . scope ( ) . $select . activeIndex ) . toBe ( 0 ) ;
889+ } ) ;
890+
849891 describe ( 'backspace reset option' , function ( ) {
850892 it ( 'should undefined model when pressing BACKSPACE key if backspaceReset=true' , function ( ) {
851893 var el = createUiSelect ( ) ;
@@ -1860,7 +1902,9 @@ describe('ui-select tests', function () {
18601902 function createUiSelectMultiple ( attrs ) {
18611903 var attrsHtml = '' ,
18621904 choicesAttrsHtml = '' ,
1863- matchesAttrsHtml = '' ;
1905+ matchesAttrsHtml = '' ,
1906+ matchesPlaceholder = defaultPlaceholder ;
1907+
18641908 if ( attrs !== undefined ) {
18651909 if ( attrs . disabled !== undefined ) { attrsHtml += ' ng-disabled="' + attrs . disabled + '"' ; }
18661910 if ( attrs . required !== undefined ) { attrsHtml += ' ng-required="' + attrs . required + '"' ; }
@@ -1870,24 +1914,26 @@ describe('ui-select tests', function () {
18701914 if ( attrs . taggingTokens !== undefined ) { attrsHtml += ' tagging-tokens="' + attrs . taggingTokens + '"' ; }
18711915 if ( attrs . taggingLabel !== undefined ) { attrsHtml += ' tagging-label="' + attrs . taggingLabel + '"' ; }
18721916 if ( attrs . inputId !== undefined ) { attrsHtml += ' input-id="' + attrs . inputId + '"' ; }
1873- if ( attrs . groupBy !== undefined ) { choicesAttrsHtml += ' group-by="' + attrs . groupBy + '"' ; }
1874- if ( attrs . uiDisableChoice !== undefined ) { choicesAttrsHtml += ' ui-disable-choice="' + attrs . uiDisableChoice + '"' ; }
1875- if ( attrs . lockChoice !== undefined ) { matchesAttrsHtml += ' ui-lock-choice="' + attrs . lockChoice + '"' ; }
18761917 if ( attrs . removeSelected !== undefined ) { attrsHtml += ' remove-selected="' + attrs . removeSelected + '"' ; }
18771918 if ( attrs . resetSearchInput !== undefined ) { attrsHtml += ' reset-search-input="' + attrs . resetSearchInput + '"' ; }
18781919 if ( attrs . limit !== undefined ) { attrsHtml += ' limit="' + attrs . limit + '"' ; }
18791920 if ( attrs . onSelect !== undefined ) { attrsHtml += ' on-select="' + attrs . onSelect + '"' ; }
18801921 if ( attrs . removeSelected !== undefined ) { attrsHtml += ' remove-selected="' + attrs . removeSelected + '"' ; }
1881- if ( attrs . refresh !== undefined ) { choicesAttrsHtml += ' refresh="' + attrs . refresh + '"' ; }
1882- if ( attrs . refreshDelay !== undefined ) { choicesAttrsHtml += ' refresh-delay="' + attrs . refreshDelay + '"' ; }
18831922 if ( attrs . spinnerEnabled !== undefined ) { attrsHtml += ' spinner-enabled="' + attrs . spinnerEnabled + '"' ; }
18841923 if ( attrs . spinnerClass !== undefined ) { attrsHtml += ' spinner-class="' + attrs . spinnerClass + '"' ; }
1924+ if ( attrs . groupBy !== undefined ) { choicesAttrsHtml += ' group-by="' + attrs . groupBy + '"' ; }
1925+ if ( attrs . uiDisableChoice !== undefined ) { choicesAttrsHtml += ' ui-disable-choice="' + attrs . uiDisableChoice + '"' ; }
1926+ if ( attrs . refresh !== undefined ) { choicesAttrsHtml += ' refresh="' + attrs . refresh + '"' ; }
1927+ if ( attrs . refreshDelay !== undefined ) { choicesAttrsHtml += ' refresh-delay="' + attrs . refreshDelay + '"' ; }
1928+ if ( attrs . lockChoice !== undefined ) { matchesAttrsHtml += ' ui-lock-choice="' + attrs . lockChoice + '"' ; }
18851929 if ( attrs . uiSelectHeaderGroupSelectable !== undefined ) { choicesAttrsHtml += ' ui-select-header-group-selectable' ; }
18861930 }
18871931
1932+ matchesAttrsHtml += ' placeholder="' + matchesPlaceholder + '"' ;
1933+
18881934 return compileTemplate (
18891935 '<ui-select multiple ng-model="selection.selectedMultiple"' + attrsHtml + ' theme="bootstrap" style="width: 800px;"> \
1890- <ui-select-match " ' + matchesAttrsHtml + ' placeholder="Pick one..." >{{$item.name}} <{{$item.email}}></ui-select-match> \
1936+ <ui-select-match ' + matchesAttrsHtml + '>{{$item.name}} <{{$item.email}}></ui-select-match> \
18911937 <ui-select-choices repeat="person in people | filter: $select.search"' + choicesAttrsHtml + '> \
18921938 <div ng-bind-html="person.name | highlight: $select.search"></div> \
18931939 <div ng-bind-html="person.email | highlight: $select.search"></div> \
@@ -2958,6 +3004,65 @@ describe('ui-select tests', function () {
29583004 triggerKeydown ( searchInput , Key . Enter ) ;
29593005 expect ( el . scope ( ) . $select . activeIndex ) . toBe ( 2 ) ;
29603006 } ) ;
3007+
3008+ it ( 'should not display the placeholder when tag is selected (by default)' , function ( ) {
3009+ var placeholderText = defaultPlaceholder ;
3010+
3011+ var el = createUiSelectMultiple ( {
3012+ tagging : '' ,
3013+ taggingLabel : ''
3014+ } ) ;
3015+
3016+ var $select = el . scope ( ) . $select ; // uiSelectCtrl
3017+
3018+ expect ( $select . selected ) . toEqual ( [ ] ) ;
3019+ expect ( $select . getPlaceholder ( ) ) . toEqual ( placeholderText ) ;
3020+ expect ( getMatchPlaceholder ( el ) ) . toEqual ( placeholderText ) ; // get placeholder
3021+
3022+ clickItem ( el , scope . people [ 0 ] . name ) ;
3023+ expect ( $select . selected ) . toEqual ( [ scope . people [ 0 ] ] ) ;
3024+ expect ( getMatchLabel ( el ) ) . toEqual ( '' ) ; // empty text
3025+ expect ( getMatchPlaceholder ( el ) ) . toEqual ( '' ) ; // empty placeholder
3026+
3027+ clickItem ( el , scope . people [ 1 ] . name ) ;
3028+ expect ( $select . selected ) . toEqual ( [ scope . people [ 0 ] , scope . people [ 1 ] ] ) ;
3029+ expect ( getMatchLabel ( el ) ) . toEqual ( '' ) ;
3030+ expect ( getMatchPlaceholder ( el ) ) . toEqual ( '' ) ;
3031+ } ) ;
3032+
3033+ // Could be needed when e.g. tag is shown below the input
3034+ it ( 'should display the placeholder when tag is selected (if user overrides .getPlaceholder())' , function ( ) {
3035+ var placeholderText = defaultPlaceholder ;
3036+
3037+ var el = createUiSelectMultiple ( {
3038+ tagging : '' ,
3039+ taggingLabel : ''
3040+ } ) ;
3041+ var $select = el . scope ( ) . $select ;
3042+
3043+ /**
3044+ * In case user wants to show placeholder when the text is empty - they can override $select.getPlaceholder.
3045+ * Cannot do this with $selectMultiple, bc <ui-select-multiple is appended inside the library
3046+ * This override closes #1796
3047+ */
3048+ $select . getPlaceholder = function ( ) {
3049+ return $select . placeholder ;
3050+ } ;
3051+
3052+ expect ( $select . selected ) . toEqual ( [ ] ) ;
3053+ expect ( getMatchLabel ( el ) ) . toEqual ( '' ) ;
3054+ expect ( getMatchPlaceholder ( el ) ) . toEqual ( placeholderText ) ;
3055+
3056+ clickItem ( el , scope . people [ 0 ] . name ) ;
3057+ expect ( $select . selected ) . toEqual ( [ scope . people [ 0 ] ] ) ;
3058+ expect ( getMatchLabel ( el ) ) . toEqual ( '' ) ; // empty text
3059+ expect ( getMatchPlaceholder ( el ) ) . toEqual ( placeholderText ) ; // show placeholder
3060+
3061+ clickItem ( el , scope . people [ 1 ] . name ) ;
3062+ expect ( $select . selected ) . toEqual ( [ scope . people [ 0 ] , scope . people [ 1 ] ] ) ;
3063+ expect ( getMatchLabel ( el ) ) . toEqual ( '' ) ;
3064+ expect ( getMatchPlaceholder ( el ) ) . toEqual ( placeholderText ) ;
3065+ } ) ;
29613066 } ) ;
29623067
29633068 describe ( 'resetSearchInput option multiple' , function ( ) {
0 commit comments