Skip to content

Commit f470209

Browse files
committed
Merge branch 'master' of https://github.com/IgniteUI/igniteui-angular into ddincheva/rowStyling
2 parents bb4b3be + 5000fff commit f470209

File tree

13 files changed

+324
-28
lines changed

13 files changed

+324
-28
lines changed

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ All notable changes for each version of this project will be documented in this
1010

1111
### New Features
1212
- `igxGrid`, `igxHierarchicalGrid`, `igxTreeGrid`
13+
- Added two public methods that spawn the add row UI for an arbitrary record in the current data view. One that accepts a rowID to use as the row the UI spawns under and the other accepting an index that has a distinct implementation for `IgxTreeGrid`. Please, refer to the official documentation for more information:[Grid Row Adding](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/row-adding) and [Tree Grid Row Adding](https://www.infragistics.com/products/ignite-ui-angular/angular/components/treegrid/row-adding).
14+
15+
_Note:_ That the new record is still added at the end of the data view, after the end-user submits it.
16+
```typescript
17+
this.grid.beginAddRowById('ALFKI'); // spawns the add row UI under the row with PK 'ALFKI'
18+
this.grid.beginAddRowById(null); // spawns the add row UI as the first record
19+
this.grid.beginAddRowByIndex(10); // spawns the add row UI at index 10
20+
this.grid.beginAddRowByIndex(0); // spawns the add row UI as the first record
21+
this.treeGrid.beginAddRowById('ALFKI', true); // spawns the add row UI to add a child for the row with PK 'ALFKI'
22+
this.treeGrid.beginAddRowByIndex(10, true); // spawns the add row UI to add a child for the row at index 10
23+
this.treeGrid.beginAddRowByIndex(null); // spawns the add row UI as the first record
24+
```
1325
- Added capability to restore the state of multi column headers with `IgxGridStateDirective`.
1426
- Introduced new 'rowStyles' and 'rowClasses' grid properties which allows to define a custom styling on each grid row
1527

@@ -74,7 +86,7 @@ All notable changes for each version of this project will be documented in this
7486
- `IgxGridCellComponent`, `IgxTreeGridCellComponent`, `IgxHierarchicalGridCellComponent` are no longer exposed in the public API. Instead, a new class `IgxGridCell` replaces all of these. It is a facade class which exposes only the public API of the above mentioned. Automatic migration will change these imports with `CellType`, which is the interface implemented by `IgxGridCell`
7587
- **Behavioral changes**
7688
- `getCellByKey`, `getCellByColumn`, `getCellByColumnVisibleIndex`, `row.cells`, `column.cells`, `grid.selectedCells` now return an `IgxGridCell` the `CellType` interface.
77-
- `cell` in `IGridCellEventArgs` is now `CellType`. `IGridCellEventArgs` are emitetd in `cellClick`, `selected`, `contextMenu` and `doubleClick` events.
89+
- `cell` in `IGridCellEventArgs` is now `CellType`. `IGridCellEventArgs` are emitted in `cellClick`, `selected`, `contextMenu` and `doubleClick` events.
7890
- `let-cell` property in cell template is now `CellType`.
7991
- `getCellByColumnVisibleIndex` is now deprecated and will be removed in next major version. Use `getCellByKey`, `getCellByColumn` instead.
8092

projects/igniteui-angular-i18n/src/i18n/DA/grid-resources.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const GridResourceStringsDA_: ExpandRequire<IGridResourceStrings> = {
66
igx_grid_groupByArea_select_message: 'Vælg alle rækker i gruppen med navnet {0} og værdi {1}.',
77
igx_grid_groupByArea_deselect_message: 'Fravælg alle rækker i gruppen med navnet {0} og værdi {1}.',
88
igx_grid_emptyFilteredGrid_message: 'Ingen poster fundet',
9-
igx_grid_emptyGrid_message: 'Gitter har ingen data',
9+
igx_grid_emptyGrid_message: 'Tabel har ingen data',
1010
igx_grid_filter: 'Filter',
1111
igx_grid_filter_row_close: 'Luk',
1212
igx_grid_filter_row_reset: 'Nulstil',

projects/igniteui-angular/src/lib/grids/api.service.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,21 @@ export class GridBaseAPIService<T extends IgxGridBaseDirective & GridType> {
9696
return this.grid.rowList.find((row) => row.index === rowIndex);
9797
}
9898

99+
/**
100+
* Gets the rowID of the record at the specified data view index
101+
*
102+
* @param index
103+
* @param dataCollection
104+
*/
105+
public get_rec_id_by_index(index: number, dataCollection?: any[]): any {
106+
dataCollection = dataCollection || this.grid.data;
107+
if (index >= 0 && index < dataCollection.length) {
108+
const rec = dataCollection[index];
109+
return this.grid.primaryKey ? rec[this.grid.primaryKey] : rec;
110+
}
111+
return null;
112+
}
113+
99114
public get_cell_by_key(rowSelector: any, field: string): IgxGridCellComponent {
100115
const row = this.get_row_by_key(rowSelector);
101116
if (row && row.cells) {
@@ -393,6 +408,17 @@ export class GridBaseAPIService<T extends IgxGridBaseDirective & GridType> {
393408
return this.grid.primaryKey ? this.getRowData(rowID) : rowID;
394409
}
395410

411+
/**
412+
* Returns the index of the record in the data view by pk or -1 if not found or primaryKey is not set.
413+
*
414+
* @param pk
415+
* @param dataCollection
416+
*/
417+
public get_rec_index_by_id(pk: string | number, dataCollection?: any[]): number {
418+
dataCollection = dataCollection || this.grid.data;
419+
return this.grid.primaryKey ? dataCollection.findIndex(rec => rec[this.grid.primaryKey] === pk) : -1;
420+
}
421+
396422
public allow_expansion_state_change(rowID, expanded) {
397423
return this.grid.expansionStates.get(rowID) !== expanded;
398424
}

projects/igniteui-angular/src/lib/grids/common/crud.service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,8 @@ export class IgxRowAddCrudState extends IgxRowCrudState {
436436
* @hidden @internal
437437
*/
438438
public createAddRowParent(row: IgxRowDirective<IgxGridBaseDirective & GridType>, newRowAsChild?: boolean) {
439-
const rowIndex = row ? row.index : this.grid.rowList.length - 1;
440-
const rowId = row ? row.rowID : (rowIndex >= 0 ? this.grid.rowList.last.rowID : null);
441-
439+
const rowIndex = row ? row.index : -1;
440+
const rowId = row ? row.rowID : null;
442441
const isInPinnedArea = this.grid.isRecordPinnedByViewIndex(rowIndex);
443442
const pinIndex = this.grid.pinnedRecords.findIndex(x => x[this.primaryKey] === rowId);
444443
const unpinIndex = this.grid.getUnpinnedIndexById(rowId);
@@ -580,6 +579,7 @@ export class IgxGridCRUDService extends IgxRowAddCrudState {
580579
this.grid.navigateTo(this.row.index, -1);
581580
const dummyRow = this.grid.gridAPI.get_row_by_index(this.row.index);
582581
dummyRow.triggerAddAnimation();
582+
dummyRow.cdr.detectChanges();
583583
dummyRow.addAnimationEnd.pipe(first()).subscribe(() => {
584584
const cell = dummyRow.cells.find(c => c.editable);
585585
if (cell) {

projects/igniteui-angular/src/lib/grids/grid-base.directive.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6005,6 +6005,92 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
60056005
this.crudService.endEdit(commit, event);
60066006
}
60076007

6008+
/**
6009+
* Enters add mode by spawning the UI under the specified row by rowID.
6010+
*
6011+
* @remarks
6012+
* If null is passed as rowID, the row adding UI is spawned as the first record in the data view
6013+
* @remarks
6014+
* Spawning the UI to add a child for a record only works if you provide a rowID
6015+
* @example
6016+
* ```typescript
6017+
* this.grid.beginAddRowById('ALFKI');
6018+
* this.grid.beginAddRowById('ALFKI', true);
6019+
* this.grid.beginAddRowById(null);
6020+
* ```
6021+
* @param rowID - The rowID to spawn the add row UI for, or null to spawn it as the first record in the data view
6022+
* @param asChild - Whether the record should be added as a child. Only applicable to igxTreeGrid.
6023+
*/
6024+
public beginAddRowById(rowID: any, asChild?: boolean): void {
6025+
let index = rowID;
6026+
if (rowID == null) {
6027+
if (asChild) {
6028+
console.warn('The record cannot be added as a child to an unspecified record.');
6029+
return;
6030+
}
6031+
index = 0;
6032+
} else {
6033+
// find the index of the record with that PK
6034+
index = this.gridAPI.get_rec_index_by_id(rowID, this.dataView);
6035+
rowID = index;
6036+
if (index === -1) {
6037+
console.warn('No row with the specified ID was found.');
6038+
return;
6039+
}
6040+
}
6041+
if (!this.dataView.length) {
6042+
this.beginAddRowForIndex(rowID, asChild);
6043+
return;
6044+
}
6045+
// check if the index is valid - won't support anything outside the data view
6046+
if (index >= 0 && index < this.dataView.length) {
6047+
// check if the index is in the view port
6048+
if ((index < this.virtualizationState.startIndex ||
6049+
index >= this.virtualizationState.startIndex + this.virtualizationState.chunkSize) &&
6050+
!this.isRecordPinnedByViewIndex(index)) {
6051+
this.verticalScrollContainer.chunkLoad
6052+
.pipe(first(), takeUntil(this.destroy$))
6053+
.subscribe(() => {
6054+
this.beginAddRowForIndex(rowID, asChild);
6055+
});
6056+
this.navigateTo(index);
6057+
this.notifyChanges(true);
6058+
return;
6059+
}
6060+
this.beginAddRowForIndex(rowID, asChild);
6061+
} else {
6062+
console.warn('The row with the specified PK or index is outside of the current data view.');
6063+
}
6064+
}
6065+
6066+
/**
6067+
* Enters add mode by spawning the UI at the specified index.
6068+
*
6069+
* @remarks
6070+
* Accepted values for index are integers from 0 to this.grid.dataView.length
6071+
* @example
6072+
* ```typescript
6073+
* this.grid.beginAddRowByIndex(0);
6074+
* ```
6075+
* @param index - The index to spawn the UI at. Accepts integers from 0 to this.grid.dataView.length
6076+
*/
6077+
public beginAddRowByIndex(index: number): void {
6078+
if (index === 0) {
6079+
return this.beginAddRowById(null);
6080+
}
6081+
return this.beginAddRowById(this.gridAPI.get_rec_id_by_index(index - 1, this.dataView));
6082+
}
6083+
6084+
protected beginAddRowForIndex(index: number, asChild: boolean = false) {
6085+
const row: IgxRowDirective<IgxGridBaseDirective & GridType> = index == null ?
6086+
null : this.rowList.find(r => r.index === index);
6087+
if (row !== undefined) {
6088+
this.crudService.enterAddRowMode(row, asChild);
6089+
} else {
6090+
console.warn('No row with the specified PK or index was found.');
6091+
}
6092+
}
6093+
60086094
protected switchTransactionService(val: boolean) {
60096095
if (val) {
60106096
this._transactions = this.transactionFactory.create(TRANSACTION_TYPE.Base);

projects/igniteui-angular/src/lib/grids/grid/grid-add-row.spec.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { IgxGridModule, IgxGridComponent } from './public_api';
22
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
3-
import { TestBed, fakeAsync } from '@angular/core/testing';
3+
import { TestBed, fakeAsync, tick } from '@angular/core/testing';
44
import { configureTestSuite } from '../../test-utils/configure-suite';
55
import { DebugElement } from '@angular/core';
66
import { GridFunctions, GridSummaryFunctions } from '../../test-utils/grid-functions.spec';
@@ -22,6 +22,8 @@ import { IgxGridRowComponent } from './grid-row.component';
2222
import { takeUntil, first } from 'rxjs/operators';
2323
import { Subject } from 'rxjs';
2424

25+
const DEBOUNCETIME = 30;
26+
2527
describe('IgxGrid - Row Adding #grid', () => {
2628
const GRID_ROW = 'igx-grid-row';
2729
const DISPLAY_CONTAINER = 'igx-display-container';
@@ -479,6 +481,35 @@ describe('IgxGrid - Row Adding #grid', () => {
479481

480482
expect(grid.gridAPI.get_row_by_index(1).addRowUI).toBeTrue();
481483
});
484+
485+
it('Should scroll and start adding a row as the first one when using the public API method', async () => {
486+
await wait(DEBOUNCETIME);
487+
fixture.detectChanges();
488+
489+
grid.navigateTo(20, 0);
490+
491+
await wait(DEBOUNCETIME);
492+
fixture.detectChanges();
493+
494+
grid.beginAddRowById(null);
495+
496+
await wait(DEBOUNCETIME);
497+
fixture.detectChanges();
498+
499+
expect(grid.gridAPI.get_row_by_index(0).addRowUI).toBeTrue();
500+
});
501+
502+
xit('Should scroll and start adding a row as for a row that is not in view', async () => {
503+
await wait(DEBOUNCETIME);
504+
fixture.detectChanges();
505+
506+
grid.beginAddRowById('FAMIA');
507+
508+
await wait(DEBOUNCETIME);
509+
fixture.detectChanges();
510+
511+
expect(grid.gridAPI.get_row_by_index(8).addRowUI).toBeTrue();
512+
});
482513
});
483514

484515
describe('Exit add row mode tests', () => {

projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-api.service.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,32 @@ export class IgxTreeGridAPIService extends GridBaseAPIService<IgxTreeGridCompone
169169
return this.grid.records.get(rowID);
170170
}
171171

172+
/**
173+
* Gets the rowID of the record at the specified data view index
174+
*
175+
* @param index
176+
* @param dataCollection
177+
*/
178+
public get_rec_id_by_index(index: number, dataCollection?: any[]): any {
179+
dataCollection = dataCollection || this.grid.data;
180+
if (index >= 0 && index < dataCollection.length) {
181+
const rec = dataCollection[index];
182+
return this.grid.primaryKey ? rec.data[this.grid.primaryKey] : rec.data;
183+
}
184+
return null;
185+
}
186+
187+
/**
188+
* Returns the index of the record in the data view by pk or -1 if not found or primaryKey is not set.
189+
*
190+
* @param pk
191+
* @param dataCollection
192+
*/
193+
public get_rec_index_by_id(pk: string | number, dataCollection?: any[]): number {
194+
dataCollection = dataCollection || this.grid.data;
195+
return this.grid.primaryKey ? dataCollection.findIndex(rec => rec.data[this.grid.primaryKey] === pk) : -1;
196+
}
197+
172198
public addRowToData(data: any, parentRowID?: any) {
173199
if (parentRowID !== undefined && parentRowID !== null) {
174200

projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,32 @@ export class IgxTreeGridComponent extends IgxGridBaseDirective implements GridTy
605605
this.notifyChanges();
606606
}
607607

608+
/**
609+
* Enters add mode by spawning the UI with the context of the specified row by index.
610+
*
611+
* @remarks
612+
* Accepted values for index are integers from 0 to this.grid.dataView.length
613+
* @remarks
614+
* When adding the row as a child, the parent row is the specified row.
615+
* @remarks
616+
* To spawn the UI on top, call the function with index = null or a negative number.
617+
* In this case trying to add this row as a child will result in error.
618+
* @example
619+
* ```typescript
620+
* this.grid.beginAddRowByIndex(10);
621+
* this.grid.beginAddRowByIndex(10, true);
622+
* this.grid.beginAddRowByIndex(null);
623+
* ```
624+
* @param index - The index to spawn the UI at. Accepts integers from 0 to this.grid.dataView.length
625+
* @param asChild - Whether the record should be added as a child. Only applicable to igxTreeGrid.
626+
*/
627+
public beginAddRowByIndex(index: number, asChild?: boolean): void {
628+
if (index === null || index < 0) {
629+
return this.beginAddRowById(null, asChild);
630+
}
631+
return this.beginAddRowById(this.gridAPI.get_rec_id_by_index(index, this.dataView), asChild);
632+
}
633+
608634
/**
609635
* @hidden
610636
*/

src/app/grid-add-row/grid-add-row.sample.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ <h1 igxCardHeaderTitle>Settings</h1>
4343
<igx-select [(ngModel)]="perPage">
4444
<igx-select-item *ngFor="let value of selectOptions" [value]="value">{{value}}</igx-select-item>
4545
</igx-select>
46+
<button igxButton="raised" (click)="beginAddRowAtIndex(indexInput.value)">Add Row At Index</button>
47+
<igx-input-group>
48+
<input igxInput name="index" type="number" #indexInput/>
49+
<label igxLabel for="index">Index</label>
50+
</igx-input-group>
51+
<button igxButton="raised" (click)="beginAddRowStart()">Add Row At Start</button>
52+
<igx-input-group>
53+
<input igxInput name="string" type="string" #stringInput value="CENTC"/>
54+
<label igxLabel for="string">PK</label>
55+
</igx-input-group>
56+
<button igxButton="raised" (click)="beginAddRowById(stringInput.value)">Add Row For ID</button>
4657
</igx-card-content>
4758
</igx-card>
4859
</div>

src/app/grid-add-row/grid-add-row.sample.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
import { Component, OnInit } from '@angular/core';
1+
import { Component, OnInit, ViewChild } from '@angular/core';
2+
import { IgxGridComponent } from 'igniteui-angular';
23

34
@Component({
45
selector: 'app-grid-add-row',
56
styleUrls: ['grid-add-row.sample.scss'],
67
templateUrl: `grid-add-row.sample.html`
78
})
89
export class GridAddRowSampleComponent implements OnInit {
10+
11+
@ViewChild(IgxGridComponent)
12+
public grid: IgxGridComponent;
13+
914
public data: any[];
1015
public dataFull: any[];
1116
public columns: any[];
@@ -69,4 +74,17 @@ export class GridAddRowSampleComponent implements OnInit {
6974
this.data = [];
7075
/* eslint-enable max-len */
7176
}
77+
78+
public beginAddRowAtIndex(index: string) {
79+
const numeric = parseInt(index, 10);
80+
this.grid.beginAddRowByIndex(numeric);
81+
}
82+
83+
public beginAddRowStart() {
84+
this.grid.beginAddRowById(null);
85+
}
86+
87+
public beginAddRowById(string: string) {
88+
this.grid.beginAddRowById(string);
89+
}
7290
}

0 commit comments

Comments
 (0)