@@ -1779,76 +1779,6 @@ describe('NgSelectComponent', () => {
17791779 } ) ;
17801780 } ) ;
17811781
1782- describe ( 'tab' , ( ) => {
1783- it ( 'should close dropdown when there are no items' , fakeAsync ( ( ) => {
1784- select . filter ( 'random stuff' ) ;
1785- tick ( 200 ) ;
1786- triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Space ) ;
1787- triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
1788- expect ( select . isOpen ) . toBeFalsy ( ) ;
1789- } ) ) ;
1790-
1791- it ( 'should close dropdown when [selectOnTab]="false"' , fakeAsync ( ( ) => {
1792- fixture . componentInstance . selectOnTab = false ;
1793- tickAndDetectChanges ( fixture ) ;
1794- triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Space ) ;
1795- triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
1796- expect ( select . selectedItems ) . toEqual ( [ ] ) ;
1797- expect ( select . isOpen ) . toBeFalsy ( ) ;
1798- } ) ) ;
1799-
1800- it ( 'should close dropdown and keep selected value' , fakeAsync ( ( ) => {
1801- fixture . componentInstance . selectedCity = fixture . componentInstance . cities [ 0 ] ;
1802- tickAndDetectChanges ( fixture ) ;
1803- triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Space ) ;
1804- triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
1805- tickAndDetectChanges ( fixture ) ;
1806- const result = [
1807- jasmine . objectContaining ( {
1808- value : fixture . componentInstance . cities [ 0 ] ,
1809- } ) ,
1810- ] ;
1811- expect ( select . selectedItems ) . toEqual ( result ) ;
1812- expect ( select . isOpen ) . toBeFalsy ( ) ;
1813- } ) ) ;
1814-
1815- it ( 'should mark first item on filter when tab' , fakeAsync ( ( ) => {
1816- tick ( 200 ) ;
1817- fixture . componentInstance . select . filter ( 'pab' ) ;
1818- tick ( 200 ) ;
1819-
1820- const result = jasmine . objectContaining ( {
1821- value : fixture . componentInstance . cities [ 2 ] ,
1822- } ) ;
1823- expect ( fixture . componentInstance . select . itemsList . markedItem ) . toEqual ( result ) ;
1824- triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
1825- expect ( fixture . componentInstance . select . selectedItems ) . toEqual ( [ result ] ) ;
1826- } ) ) ;
1827-
1828- it ( 'should focus on clear button when tab pressed while not opened and clear showing' , fakeAsync ( ( ) => {
1829- selectOption ( fixture , KeyCode . ArrowDown , 0 ) ;
1830- tickAndDetectChanges ( fixture ) ;
1831- expect ( select . showClear ( ) ) . toBeTruthy ( ) ;
1832-
1833- select . searchInput . nativeElement . focus ( ) ;
1834- const focusOnClear = spyOn ( select , 'focusOnClear' ) ;
1835- triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
1836- expect ( focusOnClear ) . toHaveBeenCalled ( ) ;
1837- } ) ) ;
1838-
1839- it ( 'should not focus on clear button when tab pressed if [tabFocusOnClearButton]="false"' , fakeAsync ( ( ) => {
1840- fixture . componentInstance . tabFocusOnClearButton = false ;
1841- selectOption ( fixture , KeyCode . ArrowDown , 0 ) ;
1842- tickAndDetectChanges ( fixture ) ;
1843- expect ( select . showClear ( ) ) . toBeTruthy ( ) ;
1844-
1845- select . searchInput . nativeElement . focus ( ) ;
1846- const focusOnClear = spyOn ( select , 'focusOnClear' ) ;
1847- triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
1848- expect ( focusOnClear ) . not . toHaveBeenCalled ( ) ;
1849- } ) ) ;
1850- } ) ;
1851-
18521782 describe ( 'backspace' , ( ) => {
18531783 it ( 'should remove selected value' , fakeAsync ( ( ) => {
18541784 fixture . componentInstance . selectedCity = fixture . componentInstance . cities [ 0 ] ;
@@ -2000,6 +1930,244 @@ describe('NgSelectComponent', () => {
20001930 } ) ;
20011931 } ) ;
20021932
1933+ describe ( 'Keyboard events (tab)' , ( ) => {
1934+ function genericFixture ( ) {
1935+ const fixture = createTestingModule (
1936+ NgSelectTestComponent ,
1937+ `<ng-select [items]="cities"
1938+ bindLabel="name"
1939+ [loading]="citiesLoading"
1940+ [selectOnTab]="selectOnTab"
1941+ [multiple]="multiple"
1942+ [tabFocusOnClearButton]="tabFocusOnClearButton"
1943+ [(ngModel)]="selectedCity">
1944+ </ng-select>` ,
1945+ ) ;
1946+ const select = fixture . componentInstance . select ;
1947+ return { fixture, select } ;
1948+ }
1949+
1950+ it ( 'should close dropdown when there are no items' , fakeAsync ( ( ) => {
1951+ const { fixture, select } = genericFixture ( ) ;
1952+ select . filter ( 'random stuff' ) ;
1953+ tick ( 200 ) ;
1954+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Space ) ;
1955+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
1956+ expect ( select . isOpen ) . toBeFalsy ( ) ;
1957+ } ) ) ;
1958+
1959+ it ( 'should close dropdown when [selectOnTab]="false"' , fakeAsync ( ( ) => {
1960+ const { fixture, select } = genericFixture ( ) ;
1961+ fixture . componentInstance . selectOnTab = false ;
1962+ tickAndDetectChanges ( fixture ) ;
1963+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Space ) ;
1964+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
1965+ expect ( select . selectedItems ) . toEqual ( [ ] ) ;
1966+ expect ( select . isOpen ) . toBeFalsy ( ) ;
1967+ } ) ) ;
1968+
1969+ it ( 'should close dropdown and keep selected value' , fakeAsync ( ( ) => {
1970+ const { fixture, select } = genericFixture ( ) ;
1971+ fixture . componentInstance . selectedCity = fixture . componentInstance . cities [ 0 ] ;
1972+ tickAndDetectChanges ( fixture ) ;
1973+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Space ) ;
1974+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
1975+ tickAndDetectChanges ( fixture ) ;
1976+ const result = [
1977+ jasmine . objectContaining ( {
1978+ value : fixture . componentInstance . cities [ 0 ] ,
1979+ } ) ,
1980+ ] ;
1981+ expect ( select . selectedItems ) . toEqual ( result ) ;
1982+ expect ( select . isOpen ) . toBeFalsy ( ) ;
1983+ } ) ) ;
1984+
1985+ it ( 'should mark first item on filter when tab' , fakeAsync ( ( ) => {
1986+ const { fixture } = genericFixture ( ) ;
1987+ tick ( 200 ) ;
1988+ fixture . componentInstance . select . filter ( 'pab' ) ;
1989+ tick ( 200 ) ;
1990+
1991+ const result = jasmine . objectContaining ( {
1992+ value : fixture . componentInstance . cities [ 2 ] ,
1993+ } ) ;
1994+ expect ( fixture . componentInstance . select . itemsList . markedItem ) . toEqual ( result ) ;
1995+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
1996+ expect ( fixture . componentInstance . select . selectedItems ) . toEqual ( [ result ] ) ;
1997+ } ) ) ;
1998+
1999+ it ( 'should focus on clear button when tab pressed while not opened and clear showing' , fakeAsync ( ( ) => {
2000+ const { fixture, select } = genericFixture ( ) ;
2001+ fixture . componentInstance . tabFocusOnClearButton = true ;
2002+ selectOption ( fixture , KeyCode . ArrowDown , 0 ) ;
2003+ tickAndDetectChanges ( fixture ) ;
2004+ expect ( select . showClear ( ) ) . toBeTruthy ( ) ;
2005+
2006+ select . searchInput . nativeElement . focus ( ) ;
2007+ const focusOnClear = spyOn ( select , 'focusOnClear' ) ;
2008+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
2009+ expect ( focusOnClear ) . toHaveBeenCalled ( ) ;
2010+ } ) ) ;
2011+
2012+ it ( 'should not focus on clear button when tab pressed if global flag is false and [tabFocusOnClearButton]="false"' , fakeAsync ( ( ) => {
2013+ const config = new NgSelectConfig ( ) ;
2014+ config . tabFocusOnClear = false ;
2015+ const fixture = createTestingModule (
2016+ NgSelectTestComponent ,
2017+ `<ng-select [items]="cities"
2018+ bindLabel="name"
2019+ [loading]="citiesLoading"
2020+ [selectOnTab]="selectOnTab"
2021+ [multiple]="multiple"
2022+ [tabFocusOnClearButton]="tabFocusOnClearButton"
2023+ [(ngModel)]="selectedCity">
2024+ </ng-select>` ,
2025+ config ,
2026+ ) ;
2027+ const select = fixture . componentInstance . select ;
2028+ fixture . componentInstance . tabFocusOnClearButton = false ;
2029+ selectOption ( fixture , KeyCode . ArrowDown , 0 ) ;
2030+ tickAndDetectChanges ( fixture ) ;
2031+ expect ( select . showClear ( ) ) . toBeTruthy ( ) ;
2032+
2033+ select . searchInput . nativeElement . focus ( ) ;
2034+ const focusOnClear = spyOn ( select , 'focusOnClear' ) ;
2035+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
2036+ expect ( focusOnClear ) . not . toHaveBeenCalled ( ) ;
2037+ } ) ) ;
2038+
2039+ it ( 'should not focus on clear button when tab pressed if global flag is true and [tabFocusOnClearButton]="false"' , fakeAsync ( ( ) => {
2040+ const config = new NgSelectConfig ( ) ;
2041+ config . tabFocusOnClear = true ;
2042+ const fixture = createTestingModule (
2043+ NgSelectTestComponent ,
2044+ `<ng-select [items]="cities"
2045+ bindLabel="name"
2046+ [loading]="citiesLoading"
2047+ [selectOnTab]="selectOnTab"
2048+ [multiple]="multiple"
2049+ [tabFocusOnClearButton]="tabFocusOnClearButton"
2050+ [(ngModel)]="selectedCity">
2051+ </ng-select>` ,
2052+ config ,
2053+ ) ;
2054+ const select = fixture . componentInstance . select ;
2055+ fixture . componentInstance . tabFocusOnClearButton = false ;
2056+ selectOption ( fixture , KeyCode . ArrowDown , 0 ) ;
2057+ tickAndDetectChanges ( fixture ) ;
2058+ expect ( select . showClear ( ) ) . toBeTruthy ( ) ;
2059+
2060+ select . searchInput . nativeElement . focus ( ) ;
2061+ const focusOnClear = spyOn ( select , 'focusOnClear' ) ;
2062+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
2063+ expect ( focusOnClear ) . not . toHaveBeenCalled ( ) ;
2064+ } ) ) ;
2065+
2066+ it ( 'should focus on clear button when tab pressed if global flag is false and [tabFocusOnClearButton]="true"' , fakeAsync ( ( ) => {
2067+ const config = new NgSelectConfig ( ) ;
2068+ config . tabFocusOnClear = false ;
2069+ const fixture = createTestingModule (
2070+ NgSelectTestComponent ,
2071+ `<ng-select [items]="cities"
2072+ bindLabel="name"
2073+ [loading]="citiesLoading"
2074+ [selectOnTab]="selectOnTab"
2075+ [multiple]="multiple"
2076+ [tabFocusOnClearButton]="tabFocusOnClearButton"
2077+ [(ngModel)]="selectedCity">
2078+ </ng-select>` ,
2079+ config ,
2080+ ) ;
2081+ const select = fixture . componentInstance . select ;
2082+ fixture . componentInstance . tabFocusOnClearButton = true ;
2083+ selectOption ( fixture , KeyCode . ArrowDown , 0 ) ;
2084+ tickAndDetectChanges ( fixture ) ;
2085+ expect ( select . showClear ( ) ) . toBeTruthy ( ) ;
2086+
2087+ select . searchInput . nativeElement . focus ( ) ;
2088+ const focusOnClear = spyOn ( select , 'focusOnClear' ) ;
2089+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
2090+ expect ( focusOnClear ) . toHaveBeenCalled ( ) ;
2091+ } ) ) ;
2092+
2093+ it ( 'should focus on clear button when tab pressed if global flag is true and [tabFocusOnClearButton]="true"' , fakeAsync ( ( ) => {
2094+ const config = new NgSelectConfig ( ) ;
2095+ config . tabFocusOnClear = true ;
2096+ const fixture = createTestingModule (
2097+ NgSelectTestComponent ,
2098+ `<ng-select [items]="cities"
2099+ bindLabel="name"
2100+ [loading]="citiesLoading"
2101+ [selectOnTab]="selectOnTab"
2102+ [multiple]="multiple"
2103+ [tabFocusOnClearButton]="tabFocusOnClearButton"
2104+ [(ngModel)]="selectedCity">
2105+ </ng-select>` ,
2106+ config ,
2107+ ) ;
2108+ const select = fixture . componentInstance . select ;
2109+ fixture . componentInstance . tabFocusOnClearButton = true ;
2110+ selectOption ( fixture , KeyCode . ArrowDown , 0 ) ;
2111+ tickAndDetectChanges ( fixture ) ;
2112+ expect ( select . showClear ( ) ) . toBeTruthy ( ) ;
2113+
2114+ select . searchInput . nativeElement . focus ( ) ;
2115+ const focusOnClear = spyOn ( select , 'focusOnClear' ) ;
2116+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
2117+ expect ( focusOnClear ) . toHaveBeenCalled ( ) ;
2118+ } ) ) ;
2119+
2120+ it ( 'should not focus on clear button when tab pressed if global flag is false and [tabFocusOnClearButton] is not provided' , fakeAsync ( ( ) => {
2121+ const config = new NgSelectConfig ( ) ;
2122+ config . tabFocusOnClear = false ;
2123+ const fixture = createTestingModule (
2124+ NgSelectTestComponent ,
2125+ `<ng-select [items]="cities"
2126+ bindLabel="name"
2127+ [loading]="citiesLoading"
2128+ [selectOnTab]="selectOnTab"
2129+ [multiple]="multiple"
2130+ [(ngModel)]="selectedCity">
2131+ </ng-select>` ,
2132+ config ,
2133+ ) ;
2134+ const select = fixture . componentInstance . select ;
2135+ selectOption ( fixture , KeyCode . ArrowDown , 0 ) ;
2136+ tickAndDetectChanges ( fixture ) ;
2137+ expect ( select . showClear ( ) ) . toBeTruthy ( ) ;
2138+
2139+ select . searchInput . nativeElement . focus ( ) ;
2140+ const focusOnClear = spyOn ( select , 'focusOnClear' ) ;
2141+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
2142+ expect ( focusOnClear ) . not . toHaveBeenCalled ( ) ;
2143+ } ) ) ;
2144+
2145+ it ( 'should focus on clear button when tab pressed if global flag is true and [tabFocusOnClearButton] is not provided' , fakeAsync ( ( ) => {
2146+ const config = new NgSelectConfig ( ) ;
2147+ config . tabFocusOnClear = true ;
2148+ const fixture = createTestingModule (
2149+ NgSelectTestComponent ,
2150+ `<ng-select [items]="cities"
2151+ bindLabel="name"
2152+ [loading]="citiesLoading"
2153+ [selectOnTab]="selectOnTab"
2154+ [multiple]="multiple"
2155+ [(ngModel)]="selectedCity">
2156+ </ng-select>` ,
2157+ config ,
2158+ ) ;
2159+ const select = fixture . componentInstance . select ;
2160+ selectOption ( fixture , KeyCode . ArrowDown , 0 ) ;
2161+ tickAndDetectChanges ( fixture ) ;
2162+ expect ( select . showClear ( ) ) . toBeTruthy ( ) ;
2163+
2164+ select . searchInput . nativeElement . focus ( ) ;
2165+ const focusOnClear = spyOn ( select , 'focusOnClear' ) ;
2166+ triggerKeyDownEvent ( getNgSelectElement ( fixture ) , KeyCode . Tab ) ;
2167+ expect ( focusOnClear ) . toHaveBeenCalled ( ) ;
2168+ } ) ) ;
2169+ } ) ;
2170+
20032171 describe ( 'Outside click' , ( ) => {
20042172 let fixture : ComponentFixture < NgSelectTestComponent > ;
20052173 let select : NgSelectComponent ;
@@ -4876,7 +5044,7 @@ class NgSelectTestComponent {
48765044 filter = new Subject < string > ( ) ;
48775045 searchFn : ( term : string , item : any ) => boolean = null ;
48785046 selectOnTab = true ;
4879- tabFocusOnClearButton = true ;
5047+ tabFocusOnClearButton : boolean ;
48805048 hideSelected = false ;
48815049 citiesLoading = false ;
48825050 selectedCityId : number ;
0 commit comments