Skip to content

Commit a229839

Browse files
authored
Merge branch 'vNext' into nav-drawer-hierarchical
2 parents 586f9e1 + 674dccd commit a229839

7 files changed

Lines changed: 218 additions & 3 deletions

live-editing/configs/HierarchicalGridConfigGenerator.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,21 @@ export class HierarchicalGridConfigGenerator implements IConfigGenerator {
958958
component: 'HGridColumnAutoSizingSampleComponent'
959959
}));
960960

961+
962+
configs.push(new Config({
963+
component: 'HierarchicalGridValidatorServiceCrossCellComponent',
964+
additionalFiles: [
965+
'/src/app/directives/prevent-scroll.directive.ts',
966+
'/src/app/data/hierarchical-data.ts'
967+
968+
],
969+
appModuleConfig: new AppModuleConfig({
970+
imports: ['HierarchicalGridValidatorServiceCrossCellComponent', 'IgxHierarchicalGridModule', 'IgxPreventDocumentScrollModule'],
971+
ngDeclarations: ['HierarchicalGridValidatorServiceCrossCellComponent'],
972+
ngImports: ['IgxPreventDocumentScrollModule', 'IgxHierarchicalGridModule', 'IgxTooltipModule']
973+
})
974+
}));
975+
961976
return configs;
962977
}
963978
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<div class="grid__wrapper">
2+
<igx-hierarchical-grid (formGroupCreated)='formCreateCustomerHandler($event)' igxPreventDocumentScroll [primaryKey]="'CustomerID'" [rowEditable]="true" [batchEditing]='true' #hierarchicalGrid [data]="localdata" [height]="'470px'" [width]="'100%'" displayDensity="compact">
3+
<igx-column field="row_valid" header=" " [editable]="false" [dataType]="'number'" [pinned]="true" [width]="'50px'">
4+
<ng-template igxCell let-cell="cell">
5+
<div *ngIf="isRowValid(cell)" [igxTooltipTarget]="tooltipRef"
6+
>
7+
<img width="18" src="assets/images/grid/active.png"/>
8+
</div>
9+
<div *ngIf="!isRowValid(cell)" [igxTooltipTarget]="tooltipRef"
10+
>
11+
<img width="18" src="assets/images/grid/expired.png"/>
12+
</div>
13+
<div #tooltipRef="tooltip" igxTooltip [style.width]="'max-content'">
14+
<div *ngFor="let message of stateMessage(cell)">
15+
{{message}}
16+
</div>
17+
</div>
18+
</ng-template>
19+
</igx-column>
20+
<igx-column field="CustomerID" [hidden]='true'></igx-column>
21+
<igx-column field="ContactName" editable='true' required></igx-column>
22+
<igx-column field="ContactTitle" editable='true' required></igx-column>
23+
<igx-column field="City" editable='true'>
24+
<ng-template igxCellEditor let-cell="cell" let-value let-fc='formControl'>
25+
<igx-select [formControl]="fc" [igxFocus]="true">
26+
<igx-select-item *ngFor="let city of cities" [value]="city">
27+
{{ city }}
28+
</igx-select-item>
29+
</igx-select>
30+
</ng-template>
31+
</igx-column>
32+
<igx-column field="Country" editable='true'>
33+
<ng-template igxCellEditor let-cell="cell" let-value let-fc='formControl'>
34+
<igx-select [formControl]="fc" [igxFocus]="true">
35+
<igx-select-item *ngFor="let country of countries" [value]="country">
36+
{{ country }}
37+
</igx-select-item>
38+
</igx-select>
39+
</ng-template>
40+
</igx-column>
41+
42+
<igx-column field="PostalCode" editable='true' required></igx-column>
43+
<igx-column field="Phone" editable='true' required></igx-column>
44+
<igx-row-island (formGroupCreated)='formCreateOrderHandler($event)' [primaryKey]="'OrderID'" [height]="null" [key]="'Orders'" [autoGenerate]="false" [rowEditable]="true">
45+
<igx-grid-toolbar [grid]="grid" *igxGridToolbar="let grid">
46+
<button igxButton [disabled]="grid.transactions.getAggregatedChanges(false).length < 1" (click)="commit(grid)">Commit</button>
47+
</igx-grid-toolbar>
48+
<igx-column field="OrderID" [hidden]='true'></igx-column>
49+
<igx-column field="EmployeeID" [hidden]='true'></igx-column>
50+
<igx-column field="row_valid" header=" " [editable]="false" [dataType]="'number'" [pinned]="true" [width]="'50px'">
51+
<ng-template igxCell let-cell="cell">
52+
<div *ngIf="isRowValid(cell)" [igxTooltipTarget]="tooltipRef"
53+
>
54+
<img width="18" src="assets/images/grid/active.png"/>
55+
</div>
56+
<div *ngIf="!isRowValid(cell)" [igxTooltipTarget]="tooltipRef"
57+
>
58+
<img width="18" src="assets/images/grid/expired.png"/>
59+
</div>
60+
<div #tooltipRef="tooltip" igxTooltip [style.width]="'max-content'">
61+
<div *ngFor="let message of stateMessage(cell)">
62+
{{message}}
63+
</div>
64+
</div>
65+
</ng-template>
66+
</igx-column>
67+
<igx-column field="OrderDate" [dataType]="'date'" editable='true' required></igx-column>
68+
<igx-column field="ShippedDate" [dataType]="'date'" editable='true' required></igx-column>
69+
<igx-column field="ShipVia" editable='true' required></igx-column>
70+
<igx-column field="Freight" editable='true' required></igx-column>
71+
<igx-column field="ShipName" editable='true' required></igx-column>
72+
</igx-row-island>
73+
</igx-hierarchical-grid>
74+
<button igxButton [disabled]="hierarchicalGrid.transactions.getAggregatedChanges(false).length < 1" (click)="commit(hierarchicalGrid)">Commit</button>
75+
</div>
76+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
.grid__wrapper {
3+
padding: 16px;
4+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { Component, OnInit, ViewChild } from '@angular/core';
2+
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
3+
import { IgxGridCell, IgxHierarchicalGridComponent } from 'igniteui-angular';
4+
import { IGridFormGroupCreatedEventArgs } from 'igniteui-angular/lib/grids/common/grid.interface';
5+
import { CUSTOMERS } from '../../data/hierarchical-data';
6+
7+
@Component({
8+
selector: 'hierarchical-grid-cross-field-validation',
9+
styleUrls: ['./hierarchical-grid-cross-field-validation.component.scss'],
10+
templateUrl: 'hierarchical-grid-cross-field-validation.component.html'
11+
})
12+
13+
export class HierarchicalGridValidatorServiceCrossCellComponent implements OnInit {
14+
public localdata;
15+
public countryData: Map<string, object>;
16+
public countries = [];
17+
public cities = [];
18+
19+
@ViewChild('hierarchicalGrid', { read: IgxHierarchicalGridComponent })
20+
public grid: IgxHierarchicalGridComponent;
21+
22+
constructor() {
23+
24+
}
25+
public ngOnInit(): void {
26+
this.localdata = CUSTOMERS.filter((rec, index, arr) => arr.findIndex(x => x.CustomerID === rec.CustomerID) === index);
27+
this.countryData = new Map(this.localdata.map(i => [i.Country, {}]));
28+
this.localdata.forEach(rec => {
29+
const country = rec.Country;
30+
const city = rec.City;
31+
this.countryData.get(country)[city] = city;
32+
});
33+
this.countries = [...new Set(this.localdata.map(x => x.Country))];
34+
this.cities = [...new Set(this.localdata.map(x => x.City))];
35+
}
36+
37+
public formCreateCustomerHandler(event: IGridFormGroupCreatedEventArgs) {
38+
const formGroup = event.formGroup;
39+
formGroup.addValidators(this.addressValidator());
40+
}
41+
42+
public formCreateOrderHandler(event: IGridFormGroupCreatedEventArgs) {
43+
const formGroup = event.formGroup;
44+
formGroup.addValidators(this.dateValidator());
45+
}
46+
47+
public addressValidator(): ValidatorFn {
48+
return (control: AbstractControl): ValidationErrors | null => {
49+
const formGroup = control;
50+
let returnObject = {};
51+
const city = formGroup.get('City');
52+
const country = formGroup.get('Country');
53+
const validCities = this.countryData.get(country.value);
54+
if (!validCities || !validCities[city.value]) {
55+
returnObject['invalidAddress'] = true;
56+
}
57+
return returnObject;
58+
}
59+
}
60+
61+
public dateValidator(): ValidatorFn {
62+
return (control: AbstractControl): ValidationErrors | null => {
63+
const formGroup = control;
64+
let returnObject = {};
65+
const orderDate = formGroup.get('OrderDate').value;
66+
const shippedDate = formGroup.get('ShippedDate').value;
67+
if (new Date(shippedDate) < new Date(orderDate)) {
68+
returnObject['invalidRange'] = true;
69+
}
70+
return returnObject;
71+
}
72+
}
73+
74+
public isRowValid(cell: IgxGridCell) {
75+
const hasErrors = !!cell.row.validation.errors || cell.row.cells.some(x => !!x.validation.errors);
76+
return !hasErrors;
77+
}
78+
79+
public stateMessage(cell: IgxGridCell) {
80+
const messages = [];
81+
const row = cell.row;
82+
if (row.validation.errors?.invalidAddress) {
83+
messages.push('The address information is invalid. City does not match the Country.');
84+
}
85+
if (row.validation.errors?.invalidRange) {
86+
messages.push('The ShippedDate cannot be before the OrderDate.');
87+
}
88+
const cellValidationErrors = row.cells.filter(x => !!x.validation.errors);
89+
if (cellValidationErrors && cellValidationErrors.length > 0) {
90+
const fields = cellValidationErrors.map(x => x.column.field).join(',');
91+
messages.push('The following fields are required: ' + fields);
92+
}
93+
94+
if (messages.length === 0) {
95+
// no errors
96+
return ['Valid'];
97+
}
98+
return messages;
99+
}
100+
101+
public commit(grid: IgxHierarchicalGridComponent) {
102+
const invalidTransactions = grid.validation.getInvalid();
103+
if (invalidTransactions.length > 0 && !confirm('You\'re commiting invalid transactions. Are you sure?')) {
104+
return;
105+
}
106+
107+
grid.transactions.commit(grid.data);
108+
grid.validation.clear();
109+
}
110+
}

src/app/hierarchical-grid/hierarchical-grid-routes-data.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,6 @@ export const hierarchicalGridRoutesData = {
8181
'hGrid-row-styles': { displayName: 'HGrid RowStyles', parentName: 'Hierarchical Grid' },
8282
'hGrid-action-strip': { displayName: 'HGrid with Action Strip', parentName: 'Hierarchical Grid' },
8383
'hierarchical-grid-validator-service': { displayName: 'Hierarchical Grid Validator Service', parentName: 'Hierarchical Grid' },
84-
'hGrid-columnAutosizing-sample': { displayName: 'HGrid Column Autosizing Sample', parentName: 'Hierarchical Grid' }
84+
'hGrid-columnAutosizing-sample': { displayName: 'HGrid Column Autosizing Sample', parentName: 'Hierarchical Grid' },
85+
'hierarchical-grid-cross-field-validation': { displayName: 'Hierarchical Grid Cross-field Validation', parentName: 'Hierarchical Grid' }
8586
};

src/app/hierarchical-grid/hierarchical-grid-routing.module.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ import { HGridActionStripSampleComponent } from './hierarchical-grid-action-stri
9898
import { HGridSummaryTemplateComponent } from './hgrid-summary-template/hgrid-summary-template.component';
9999
import { HierarchicalGridValidatorServiceComponent } from './hierarchical-grid-validator-service/hierarchical-grid-validator-service.component';
100100
import { HGridColumnAutoSizingSampleComponent } from './hgrid-column-autosizing/hgrid-column-autosizing.component';
101+
import { HierarchicalGridValidatorServiceCrossCellComponent } from './hierarchical-grid-cross-field-validation/hierarchical-grid-cross-field-validation.component';
101102

102103
export const hierarchicalGridRoutes: Routes = [
103104
{
@@ -553,6 +554,11 @@ export const hierarchicalGridRoutes: Routes = [
553554
component: HGridColumnAutoSizingSampleComponent,
554555
data: hierarchicalGridRoutesData['hGrid-columnAutosizing-sample'],
555556
path: 'hGrid-columnAutosizing-sample'
557+
},
558+
{
559+
component: HierarchicalGridValidatorServiceCrossCellComponent,
560+
data: hierarchicalGridRoutesData['hierarchical-grid-cross-field-validation'],
561+
path: 'hierarchical-grid-cross-field-validation'
556562
}
557563
];
558564

src/app/hierarchical-grid/hierarchical-grid.module.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { CommonModule } from '@angular/common';
44
import { HttpClientModule } from '@angular/common/http';
55
import { NgModule } from '@angular/core';
6-
import { FormsModule } from '@angular/forms';
6+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
77
import { IgxActionStripModule, IgxAvatarModule, IgxBadgeModule, IgxBannerModule, IgxButtonGroupModule, IgxButtonModule, IgxCheckboxModule,
88
IgxChipsModule, IgxComboModule, IgxDatePickerModule, IgxDialogModule,
99
IgxFocusModule, IgxGridModule, IgxHierarchicalGridModule, IgxIconModule, IgxInputGroupModule,
@@ -93,6 +93,7 @@ import { HGridActionStripSampleComponent } from './hierarchical-grid-action-stri
9393
import { HGridSummaryTemplateComponent } from './hgrid-summary-template/hgrid-summary-template.component';
9494
import { HierarchicalGridValidatorServiceComponent } from './hierarchical-grid-validator-service/hierarchical-grid-validator-service.component';
9595
import { HGridColumnAutoSizingSampleComponent } from './hgrid-column-autosizing/hgrid-column-autosizing.component';
96+
import { HierarchicalGridValidatorServiceCrossCellComponent } from './hierarchical-grid-cross-field-validation/hierarchical-grid-cross-field-validation.component';
9697

9798
@NgModule({
9899
declarations: [
@@ -178,11 +179,13 @@ import { HGridColumnAutoSizingSampleComponent } from './hgrid-column-autosizing/
178179
HGridRowClassesSampleComponent,
179180
HGridActionStripSampleComponent,
180181
HierarchicalGridValidatorServiceComponent,
181-
HGridColumnAutoSizingSampleComponent
182+
HGridColumnAutoSizingSampleComponent,
183+
HierarchicalGridValidatorServiceCrossCellComponent
182184
],
183185
imports: [
184186
CommonModule,
185187
FormsModule,
188+
ReactiveFormsModule,
186189
HttpClientModule,
187190
HierarchicalGridRoutingModule,
188191
IgxPreventDocumentScrollModule,

0 commit comments

Comments
 (0)