Skip to content

Commit fcdba88

Browse files
committed
feat(add-row): implementing context-free beginAddRow method #9675
1 parent 2e08303 commit fcdba88

File tree

7 files changed

+139
-4
lines changed

7 files changed

+139
-4
lines changed

Diff for: CHANGELOG.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@
22

33
All notable changes for each version of this project will be documented in this file.
44

5+
6+
## 12.1.5
7+
8+
### New Features
9+
- `igxGrid`, `igxHierarchicalGrid`, `igxTreeGrid`
10+
- Added a public method that spawns the add row UI for an arbitrary record in the current data view. It accepts a rowID (PK when one is defined, index otherwise). You can also pass `null` to spawn the UI as the very first record. Please, note that the new record is still added at the end of the data view, after the end-user submits it.
11+
```typescript
12+
this.grid.beginAddRow('ALFKI'); // spawns the add row UI under the row with PK 'ALFKI'
13+
this.grid.beginAddRow(null); // spawns the add row UI as the first record
14+
```
15+
516
## 12.1.3
617

718
### New Features
819
- `igxGrid`
920
- Added `headerStyles` and `headerGroupStyles` inputs to the column component.
1021
Similar to `cellStyles` is exposes a way to bind CSS properties and style the grid headers.
1122

23+
1224
## 12.1.2
1325
- `igxGrid`
1426
- The column formatter callback signature now accepts the row data as an additional argument:
@@ -60,7 +72,7 @@ All notable changes for each version of this project will be documented in this
6072
- `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`
6173
- **Behavioral changes**
6274
- `getCellByKey`, `getCellByColumn`, `getCellByColumnVisibleIndex`, `row.cells`, `column.cells`, `grid.selectedCells` now return an `IgxGridCell` the `CellType` interface.
63-
- `cell` in `IGridCellEventArgs` is now `CellType`. `IGridCellEventArgs` are emitetd in `cellClick`, `selected`, `contextMenu` and `doubleClick` events.
75+
- `cell` in `IGridCellEventArgs` is now `CellType`. `IGridCellEventArgs` are emitted in `cellClick`, `selected`, `contextMenu` and `doubleClick` events.
6476
- `let-cell` property in cell template is now `CellType`.
6577
- `getCellByColumnVisibleIndex` is now deprecated and will be removed in next major version. Use `getCellByKey`, `getCellByColumn` instead.
6678

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

+8
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,14 @@ export class GridBaseAPIService<T extends IgxGridBaseDirective & GridType> {
393393
return this.grid.primaryKey ? this.getRowData(rowID) : rowID;
394394
}
395395

396+
/**
397+
* Returns the index of the record in the data view by pk or -1 if not found or primaryKey is not set.
398+
* @param pk
399+
*/
400+
public get_rec_index_by_id(pk: string | number): number {
401+
return this.grid.primaryKey ? this.grid.dataView.findIndex(rec => rec[this.grid.primaryKey] === pk) : -1;
402+
}
403+
396404
public allow_expansion_state_change(rowID, expanded) {
397405
return this.grid.expansionStates.get(rowID) !== expanded;
398406
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ 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;
439+
const rowIndex = row ? row.index : -1;
440440
const rowId = row ? row.rowID : (rowIndex >= 0 ? this.grid.rowList.last.rowID : null);
441441

442442
const isInPinnedArea = this.grid.isRecordPinnedByViewIndex(rowIndex);
@@ -580,6 +580,7 @@ export class IgxGridCRUDService extends IgxRowAddCrudState {
580580
this.grid.navigateTo(this.row.index, -1);
581581
const dummyRow = this.grid.gridAPI.get_row_by_index(this.row.index);
582582
dummyRow.triggerAddAnimation();
583+
dummyRow.cdr.detectChanges();
583584
dummyRow.addAnimationEnd.pipe(first()).subscribe(() => {
584585
const cell = dummyRow.cells.find(c => c.editable);
585586
if (cell) {

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

+62
Original file line numberDiff line numberDiff line change
@@ -5957,6 +5957,68 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
59575957
this.crudService.endEdit(commit, event);
59585958
}
59595959

5960+
/**
5961+
* Enters add mode for the specified rowID (primary key if one is defined, index otherwise)
5962+
*
5963+
* @remarks
5964+
* If null is passed as rowID, the row adding UI is spawned as the first record in the data view
5965+
* @remarks
5966+
* Spawning the UI to add a child for a record only works if you provide a rowID
5967+
* @example
5968+
* ```typescript
5969+
* this.grid.beginAddRow('ALFKI');
5970+
* this.grid.beginAddRow(null);
5971+
* ```
5972+
* @param rowID - The PK or index to spawn the add row UI for, or null to spawn it as the first record in the data view
5973+
* @param asChild - Whether the record should be added as a child. Only applicable to igxTreeGrid.
5974+
*/
5975+
public beginAddRow(rowID: any, asChild?: boolean): void {
5976+
let index = rowID;
5977+
if (rowID == null) {
5978+
if (asChild) {
5979+
console.warn("The record cannot be added as a child to an unspecified record.");
5980+
return;
5981+
}
5982+
index = 0;
5983+
} else if (this.primaryKey !== null) {
5984+
// find the index of the record with that PK
5985+
index = this.gridAPI.get_rec_index_by_id(rowID);
5986+
rowID = index;
5987+
if (index == -1) {
5988+
console.warn("No row with the specified PK was found.");
5989+
return;
5990+
}
5991+
}
5992+
// check if the index is valid - won't support anything outside the data view
5993+
if (index >= 0 && index < this.dataView.length) {
5994+
// check if the index is in the view port
5995+
if (index < this.virtualizationState.startIndex ||
5996+
index >= this.virtualizationState.startIndex + this.virtualizationState.chunkSize) {
5997+
this.verticalScrollContainer.chunkLoad
5998+
.pipe(first(), takeUntil(this.destroy$))
5999+
.subscribe(() => {
6000+
this.beginAddRowForIndex(rowID, asChild);
6001+
});
6002+
this.navigateTo(index);
6003+
this.notifyChanges(true);
6004+
return;
6005+
}
6006+
this.beginAddRowForIndex(rowID, asChild);
6007+
} else {
6008+
console.warn("The row with the specified PK or index is outside of the current data view.");
6009+
}
6010+
}
6011+
6012+
protected beginAddRowForIndex(index: number, asChild: boolean = false) {
6013+
const row: IgxRowDirective<IgxGridBaseDirective & GridType> = index == null ?
6014+
null : this.rowList.find(r => r.index === index);
6015+
if (row !== undefined) {
6016+
this.crudService.enterAddRowMode(row, asChild);
6017+
} else {
6018+
console.warn("No row with the specified PK or index was found.");
6019+
}
6020+
}
6021+
59606022
protected switchTransactionService(val: boolean) {
59616023
if (val) {
59626024
this._transactions = this.transactionFactory.create(TRANSACTION_TYPE.Base);

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

+32-1
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.beginAddRow(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.beginAddRow('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', () => {

Diff for: src/app/grid-add-row/grid-add-row.sample.html

+6
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ <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>
4652
</igx-card-content>
4753
</igx-card>
4854
</div>

Diff for: src/app/grid-add-row/grid-add-row.sample.ts

+16-1
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,14 @@ 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+
const PK = this.grid.dataView[numeric]['ID'];
81+
this.grid.beginAddRow(PK);
82+
}
83+
84+
public beginAddRowStart() {
85+
this.grid.beginAddRow(null);
86+
}
7287
}

0 commit comments

Comments
 (0)