1
- import { Component , ViewChild , EventEmitter } from '@angular/core' ;
1
+ import { Component , ViewChild , EventEmitter , OnInit } from '@angular/core' ;
2
2
import { async , TestBed , ComponentFixture } from '@angular/core/testing' ;
3
3
import { configureTestSuite } from '../../test-utils/configure-suite' ;
4
4
import { NoopAnimationsModule } from '@angular/platform-browser/animations' ;
@@ -12,6 +12,7 @@ import { GridFunctions } from '../../test-utils/grid-functions.spec';
12
12
13
13
const COLLAPSED_ICON_NAME = 'chevron_right' ;
14
14
const EXPANDED_ICON_NAME = 'expand_more' ;
15
+ const DEBOUNCETIME = 30 ;
15
16
16
17
describe ( 'IgxGrid Master Detail' , ( ) => {
17
18
let fix : ComponentFixture < any > ;
@@ -130,6 +131,106 @@ describe('IgxGrid Master Detail', () => {
130
131
} ) ;
131
132
} ) ;
132
133
134
+ describe ( 'Keyboard Navigation ' , ( ) => {
135
+ configureTestSuite ( ) ;
136
+ beforeEach ( async ( ( ) => {
137
+ TestBed . configureTestingModule ( {
138
+ declarations : [
139
+ DefaultGridMasterDetailComponent ,
140
+ AllExpandedGridMasterDetailComponent
141
+ ] ,
142
+ imports : [ IgxGridModule , NoopAnimationsModule ]
143
+ } ) . compileComponents ( ) ;
144
+ } ) ) ;
145
+
146
+ beforeEach ( async ( ( ) => {
147
+ fix = TestBed . createComponent ( AllExpandedGridMasterDetailComponent ) ;
148
+ fix . detectChanges ( ) ;
149
+ grid = fix . componentInstance . grid ;
150
+ } ) ) ;
151
+
152
+ it ( 'Should navigate down through a detail view by focusing the whole row and continuing onto the next with arrow down.' ,
153
+ async ( ) => {
154
+ const targetCellElement = grid . getCellByColumn ( 0 , 'ContactName' ) ;
155
+ UIInteractions . triggerKeyDownEvtUponElem ( 'arrowdown' , targetCellElement , true ) ;
156
+ await wait ( DEBOUNCETIME ) ;
157
+ fix . detectChanges ( ) ;
158
+ const firstRowDetail = GridFunctions . getMasterRowDetail ( grid . rowList . first ) ;
159
+ expect ( document . activeElement ) . toBe ( firstRowDetail ) ;
160
+ UIInteractions . triggerKeyDownEvtUponElem ( 'arrowdown' , firstRowDetail , true ) ;
161
+ await wait ( DEBOUNCETIME ) ;
162
+ fix . detectChanges ( ) ;
163
+ expect ( grid . getCellByColumn ( 2 , 'ContactName' ) . selected ) . toBeTruthy ( ) ;
164
+ } ) ;
165
+
166
+ it ( 'Should navigate down through a detail view partially out of view by scrolling it so it becomes fully visible.' , async ( ) => {
167
+ const row = grid . getRowByIndex ( 4 ) as IgxGridRowComponent ;
168
+ const targetCellElement = grid . getCellByColumn ( 4 , 'ContactName' ) ;
169
+ UIInteractions . triggerKeyDownEvtUponElem ( 'arrowdown' , targetCellElement , true ) ;
170
+ await wait ( DEBOUNCETIME ) ;
171
+ fix . detectChanges ( ) ;
172
+ const detailRow = GridFunctions . getMasterRowDetail ( row ) ;
173
+ expect ( document . activeElement ) . toBe ( detailRow ) ;
174
+ expect ( GridFunctions . elementInGridView ( grid , detailRow ) ) . toBeTruthy ( ) ;
175
+ } ) ;
176
+
177
+ it ( 'Should navigate down through a detail view completely out of view by scrolling to it.' , async ( ) => {
178
+ grid . navigateTo ( 6 , 0 ) ;
179
+ await wait ( DEBOUNCETIME ) ;
180
+ fix . detectChanges ( ) ;
181
+ const row = grid . getRowByIndex ( 6 ) as IgxGridRowComponent ;
182
+ const targetCellElement = grid . getCellByColumn ( 6 , 'ContactName' ) ;
183
+ UIInteractions . triggerKeyDownEvtUponElem ( 'arrowdown' , targetCellElement , true ) ;
184
+ await wait ( DEBOUNCETIME ) ;
185
+ fix . detectChanges ( ) ;
186
+ const detailRow = GridFunctions . getMasterRowDetail ( row ) ;
187
+ expect ( document . activeElement ) . toBe ( detailRow ) ;
188
+ expect ( GridFunctions . elementInGridView ( grid , detailRow ) ) . toBeTruthy ( ) ;
189
+ } ) ;
190
+
191
+ it ( 'Should navigate up through a detail view by focusing the whole row and continuing onto the next with arrow up.' , async ( ) => {
192
+ const prevRow = grid . getRowByIndex ( 0 ) as IgxGridRowComponent ;
193
+ const targetCellElement = grid . getCellByColumn ( 2 , 'ContactName' ) ;
194
+ UIInteractions . triggerKeyDownEvtUponElem ( 'arrowup' , targetCellElement , true ) ;
195
+ await wait ( DEBOUNCETIME ) ;
196
+ fix . detectChanges ( ) ;
197
+ const detailRow = GridFunctions . getMasterRowDetail ( prevRow ) ;
198
+ expect ( document . activeElement ) . toBe ( detailRow ) ;
199
+ UIInteractions . triggerKeyDownEvtUponElem ( 'arrowup' , detailRow , true ) ;
200
+ await wait ( DEBOUNCETIME ) ;
201
+ fix . detectChanges ( ) ;
202
+ expect ( prevRow . cells . toArray ( ) [ 0 ] . selected ) . toBeTruthy ( ) ;
203
+ } ) ;
204
+
205
+ it ( 'Should navigate up through a detail view partially out of view by scrolling it so it becomes fully visible.' , async ( ) => {
206
+ grid . verticalScrollContainer . addScrollTop ( 90 ) ;
207
+ await wait ( DEBOUNCETIME ) ;
208
+ fix . detectChanges ( ) ;
209
+ const row = grid . getRowByIndex ( 2 ) ;
210
+ const targetCellElement = grid . getCellByColumn ( 2 , 'ContactName' ) ;
211
+ UIInteractions . triggerKeyDownEvtUponElem ( 'arrowup' , targetCellElement , true ) ;
212
+ await wait ( DEBOUNCETIME ) ;
213
+ fix . detectChanges ( ) ;
214
+ const detailRow = row . element . nativeElement . previousElementSibling ;
215
+ expect ( document . activeElement ) . toBe ( detailRow ) ;
216
+ expect ( GridFunctions . elementInGridView ( grid , detailRow ) ) . toBeTruthy ( ) ;
217
+ } ) ;
218
+
219
+ it ( 'Should navigate up through a detail view completely out of view by scrolling to it.' , async ( ) => {
220
+ grid . verticalScrollContainer . addScrollTop ( 170 ) ;
221
+ await wait ( DEBOUNCETIME ) ;
222
+ fix . detectChanges ( ) ;
223
+ const row = grid . getRowByIndex ( 2 ) ;
224
+ const targetCellElement = grid . getCellByColumn ( 2 , 'ContactName' ) ;
225
+ UIInteractions . triggerKeyDownEvtUponElem ( 'arrowup' , targetCellElement , true ) ;
226
+ await wait ( DEBOUNCETIME ) ;
227
+ fix . detectChanges ( ) ;
228
+ const detailRow = row . element . nativeElement . previousElementSibling ;
229
+ expect ( document . activeElement ) . toBe ( detailRow ) ;
230
+ expect ( GridFunctions . elementInGridView ( grid , detailRow ) ) . toBeTruthy ( ) ;
231
+ } ) ;
232
+ } ) ;
233
+
133
234
describe ( 'Integration' , ( ) => {
134
235
configureTestSuite ( ) ;
135
236
beforeEach ( async ( ( ) => {
@@ -224,3 +325,36 @@ export class DefaultGridMasterDetailComponent {
224
325
this . checkboxChanged . emit ( { event : event , context : context } ) ;
225
326
}
226
327
}
328
+
329
+ @Component ( {
330
+ template : `
331
+ <igx-grid [data]="data" [expansionStates]='expStates'
332
+ [width]="width" [height]="height" [primaryKey]="'ID'" [paging]="paging" [rowSelectable]="rowSelectable">
333
+ <igx-column *ngFor="let c of columns" [field]="c.field" [header]="c.field" [width]="c.width" [dataType]='c.dataType'
334
+ [hidden]='c.hidden' [sortable]="c.sortable" [movable]='c.movable' [groupable]='c.groupable' [editable]="c.editable"
335
+ [hasSummary]="c.hasSummary" [pinned]='c.pinned'>
336
+ </igx-column>
337
+
338
+ <ng-template igxGridDetail let-dataItem>
339
+ <div>
340
+ <div class="checkboxArea">
341
+ <igx-checkbox (change)="onCheckboxClicked($event, dataItem)" [disableRipple]="true"></igx-checkbox>
342
+ <span style="font-weight: 600">Available</span>
343
+ </div>
344
+ <div class="addressArea">{{dataItem.Address}}</div>
345
+ <div class="inputArea"><input type="text" name="Comment"></div>
346
+ </div>
347
+ </ng-template>
348
+ </igx-grid>
349
+ `
350
+ } )
351
+ export class AllExpandedGridMasterDetailComponent extends DefaultGridMasterDetailComponent implements OnInit {
352
+ public expStates = new Map < any , boolean > ( ) ;
353
+ ngOnInit ( ) : void {
354
+ const allExpanded = new Map < any , boolean > ( ) ;
355
+ this . data . forEach ( item => {
356
+ allExpanded . set ( item [ 'ID' ] , true ) ;
357
+ } ) ;
358
+ this . expStates = allExpanded ;
359
+ }
360
+ }
0 commit comments