React Tree Grid 셀 편집
트리 그리드의 Ignite UI for React 셀 편집 React React 트리 그리드 구성 요소 내의 개별 셀 내용에 대한 뛰어난 데이터 조작 기능을 제공하며 React CRUD 작업을 위한 강력한 API와 함께 제공됩니다. 스프레드시트, 데이터 테이블 및 데이터 그리드와 같은 앱의 기본 기능으로, 사용자가 특정 셀 내에서 데이터를 추가, 편집 또는 업데이트할 수 있습니다. 기본적으로 Ignite UI for React의 그리드는 셀 편집에 사용됩니다. 그리고 때문에 기본 셀 편집 템플릿, 열 데이터 유형 Top of Form에 따라 다른 편집기가 있습니다.
또한 데이터 업데이트 작업에 대한 사용자 정의 템플릿을 정의하고 변경 사항 커밋 및 삭제에 대한 기본 동작을 재정의할 수 있습니다.
React Tree Grid 셀 편집 및 편집 템플릿 예제
export class EmployeesNestedTreeDataItem {
public constructor(init: Partial<EmployeesNestedTreeDataItem>) {
Object.assign(this, init);
}
public Age: number;
public HireDate: string;
public ID: number;
public Name: string;
public Phone: string;
public OnPTO: boolean;
public ParentID: number;
public Title: string;
}
export class EmployeesNestedTreeData extends Array<EmployeesNestedTreeDataItem> {
public constructor(items: Array<EmployeesNestedTreeDataItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new EmployeesNestedTreeDataItem({ Age: 55, HireDate: `2008-03-20`, ID: 1, Name: `Johnathan Winchester`, Phone: `0251-031259`, OnPTO: false, ParentID: -1, Title: `Development Manager` }),
new EmployeesNestedTreeDataItem({ Age: 42, HireDate: `2014-01-22`, ID: 4, Name: `Ana Sanders`, Phone: `(21) 555-0091`, OnPTO: true, ParentID: -1, Title: `CEO` }),
new EmployeesNestedTreeDataItem({ Age: 49, HireDate: `2014-01-22`, ID: 18, Name: `Victoria Lincoln`, Phone: `(071) 23 67 22 20`, OnPTO: true, ParentID: -1, Title: `Accounting Manager` }),
new EmployeesNestedTreeDataItem({ Age: 61, HireDate: `2010-01-01`, ID: 10, Name: `Yang Wang`, Phone: `(21) 555-0091`, OnPTO: false, ParentID: -1, Title: `Localization Manager` }),
new EmployeesNestedTreeDataItem({ Age: 43, HireDate: `2011-06-03`, ID: 3, Name: `Michael Burke`, Phone: `0452-076545`, OnPTO: true, ParentID: 1, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 29, HireDate: `2009-06-19`, ID: 2, Name: `Thomas Anderson`, Phone: `(14) 555-8122`, OnPTO: false, ParentID: 1, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 31, HireDate: `2014-08-18`, ID: 11, Name: `Monica Reyes`, Phone: `7675-3425`, OnPTO: false, ParentID: 1, Title: `Software Development Team Lead` }),
new EmployeesNestedTreeDataItem({ Age: 35, HireDate: `2015-09-17`, ID: 6, Name: `Roland Mendel`, Phone: `(505) 555-5939`, OnPTO: false, ParentID: 11, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 44, HireDate: `2009-10-11`, ID: 12, Name: `Sven Cooper`, Phone: `0695-34 67 21`, OnPTO: true, ParentID: 11, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 44, HireDate: `2014-04-04`, ID: 14, Name: `Laurence Johnson`, Phone: `981-443655`, OnPTO: false, ParentID: 4, Title: `Director` }),
new EmployeesNestedTreeDataItem({ Age: 25, HireDate: `2017-11-09`, ID: 5, Name: `Elizabeth Richards`, Phone: `(2) 283-2951`, OnPTO: true, ParentID: 4, Title: `Vice President` }),
new EmployeesNestedTreeDataItem({ Age: 39, HireDate: `2010-03-22`, ID: 13, Name: `Trevor Ashworth`, Phone: `981-443655`, OnPTO: true, ParentID: 5, Title: `Director` }),
new EmployeesNestedTreeDataItem({ Age: 44, HireDate: `2014-04-04`, ID: 17, Name: `Antonio Moreno`, Phone: `(505) 555-5939`, OnPTO: false, ParentID: 18, Title: `Senior Accountant` }),
new EmployeesNestedTreeDataItem({ Age: 50, HireDate: `2007-11-18`, ID: 7, Name: `Pedro Rodriguez`, Phone: `035-640230`, OnPTO: false, ParentID: 10, Title: `Senior Localization Developer` }),
new EmployeesNestedTreeDataItem({ Age: 27, HireDate: `2016-02-19`, ID: 8, Name: `Casey Harper`, Phone: `0342-023176`, OnPTO: true, ParentID: 10, Title: `Senior Localization` }),
new EmployeesNestedTreeDataItem({ Age: 25, HireDate: `2017-11-09`, ID: 15, Name: `Patricia Simpson`, Phone: `069-0245984`, OnPTO: false, ParentID: 7, Title: `Localization Intern` }),
new EmployeesNestedTreeDataItem({ Age: 39, HireDate: `2010-03-22`, ID: 9, Name: `Francisco Chang`, Phone: `(91) 745 6200`, OnPTO: false, ParentID: 7, Title: `Localization Intern` }),
new EmployeesNestedTreeDataItem({ Age: 25, HireDate: `2018-03-18`, ID: 16, Name: `Peter Lewis`, Phone: `069-0245984`, OnPTO: true, ParentID: 7, Title: `Localization Intern` }),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrPaginatorModule, IgrTreeGridModule } from "@infragistics/igniteui-react-grids";
import { IgrTreeGrid, IgrPaginator, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebPaginatorDescriptionModule, WebTreeGridDescriptionModule } from "@infragistics/igniteui-react-core";
import { EmployeesNestedTreeDataItem, EmployeesNestedTreeData } from './EmployeesNestedTreeData';
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrPaginatorModule,
IgrTreeGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.treeGridRef = this.treeGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrTreeGrid
autoGenerate={false}
ref={this.treeGridRef}
id="treeGrid"
data={this.employeesNestedTreeData}
primaryKey="ID"
allowFiltering={true}
foreignKey="ParentID">
<IgrPaginator
perPage={10}>
</IgrPaginator>
<IgrColumn
field="Name"
dataType="string"
editable={true}
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Title"
dataType="string"
editable={true}
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Age"
dataType="number"
editable={true}
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="HireDate"
dataType="date"
editable={true}
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="OnPTO"
dataType="boolean"
editable={true}
hasSummary={true}
width="130px">
</IgrColumn>
</IgrTreeGrid>
</div>
</div>
);
}
private _employeesNestedTreeData: EmployeesNestedTreeData = null;
public get employeesNestedTreeData(): EmployeesNestedTreeData {
if (this._employeesNestedTreeData == null)
{
this._employeesNestedTreeData = new EmployeesNestedTreeData();
}
return this._employeesNestedTreeData;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebPaginatorDescriptionModule.register(context);
WebTreeGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
셀 편집
UI를 통한 편집
다음 방법 중 하나로 편집 가능한 셀에 초점이 맞춰지면 특정 셀에 대한 편집 모드로 들어갈 수 있습니다.
- 두 번 클릭하면;
- 한 번 클릭 시 - 이전에 선택한 셀이 편집 모드이고 현재 선택한 셀이 편집 가능한 경우에만 한 번 클릭하면 편집 모드로 들어갑니다. 이전에 선택한 셀이 편집 모드가 아닌 경우 한 번 클릭하면 편집 모드로 들어가지 않고 셀이 선택됩니다.
- on key press ENTER;
- 키를 누르면 F2;
다음 방법 중 하나로 변경 사항을 커밋하지 않고 편집 모드를 종료할 수 있습니다.
- 키를 누를 때 Escape;
- 정렬, 필터링, 검색 및 숨기기 작업을 수행할 때
다음 방법 중 하나로 편집 모드를 종료하고 변경 사항을 커밋 할 수 있습니다.
- on key press ENTER;
- 키를 누르면 F2;
- on key press TAB;
- 다른 셀을 한 번 클릭할 때 - 에서
IgrTreeGrid
다른 셀을 클릭하면 변경 사항이 제출됩니다. - 페이징, 크기 조정, 고정 또는 이동과 같은 작업을 수행하면 편집 모드가 종료되고 변경 사항이 제출됩니다.
셀은 세로 또는 가로로 스크롤하거나 IgrTreeGrid 외부를 클릭할 때 편집 모드로 유지됩니다. 이는 셀 편집과 행 편집 모두에 유효합니다.
API를 통한 편집
API를 통해 IgrTreeGrid
셀 값을 수정할 수도 있지만 기본 키가 정의된 경우에만 수정할 수 있습니다.
public updateCell() {
this.treeGrid.updateCell(newValue, rowID, 'Age');
}
typescript
셀을 업데이트하는 또 다른 방법은 다음과 같은 방법을 사용하는 Update
것입니다. Cell
public updateCell() {
const cell = this.treeGrid.getCellByColumn(rowIndex, 'Age');
// You can also get cell by rowID if primary key is defined
// const cell = this.treeGrid.getCellByKey(rowID, 'Age');
cell.update(9999);
}
typescript
셀 편집 템플릿
일반 편집 항목에서 기본 셀 편집 템플릿에 대해 자세히 알아보고 확인할 수 있습니다.
셀에 적용될 사용자 정의 템플릿을 제공하려는 경우 해당 템플릿을 셀 자체나 헤더에 전달할 수 있습니다. 먼저 평소와 같이 열을 만듭니다.
<IgrColumn
field="race"
header="Race"
dataType="string"
editable={true}
inlineEditorTemplate={this.webGridCellEditCellTemplate}>
</IgrColumn>
tsx
index.ts 파일의 이 열에 템플릿을 전달합니다.
public webGridCellEditCellTemplate = (e: IgrCellTemplateContext) => {
let cellValues: any = [];
let uniqueValues: any = [];
const cell = e.cell;
const colIndex = cell.id.columnID;
const field: string = this.grid1.getColumnByVisibleIndex(colIndex).field;
let index = 0;
for (const i of this.roleplayDataStats as any) {
if (uniqueValues.indexOf(i[field]) === -1) {
cellValues.push(
<>
<IgrSelectItem
selected={e.cell.value == i[field]}
value={i[field]}
>
<div>{i[field]}</div>
</IgrSelectItem>
</>
);
uniqueValues.push(i[field]);
}
index++;
}
return (
<>
<IgrSelect
onChange={(x: any) => {
setTimeout(() => {
cell.editValue = x.target.value;
});
}}
>
{cellValues}
</IgrSelect>
</>
);
};
typescript
추가 참조를 위해 위의 작업 샘플을 여기에서 찾을 수 있습니다.
export class RoleplayTreeGridDataItem {
public constructor(init: Partial<RoleplayTreeGridDataItem>) {
Object.assign(this, init);
}
public ID: number;
public ParentID: number;
public Name: string;
public Age: string;
public Alignment: string;
public Race: string;
public Class: string;
}
export class RoleplayTreeGridData extends Array<RoleplayTreeGridDataItem> {
public constructor(items: Array<RoleplayTreeGridDataItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new RoleplayTreeGridDataItem({ ID: 1, ParentID: 8, Name: `Stredo`, Age: `244`, Alignment: `💜 Lawful evil`, Race: `👩 Human`, Class: `🎻 Bard` }),
new RoleplayTreeGridDataItem({ ID: 2, ParentID: 7, Name: `Haluun`, Age: `40`, Alignment: `🤍 Unaligned`, Race: `🧒🏻 Hafling`, Class: `🙏🏻 Monk` }),
new RoleplayTreeGridDataItem({ ID: 3, ParentID: 9, Name: `Ivellios`, Age: `244`, Alignment: `🧡 Chaotic good`, Race: `👩 Human`, Class: `⚔️ Paladin` }),
new RoleplayTreeGridDataItem({ ID: 4, ParentID: -1, Name: `Tes`, Age: `35`, Alignment: `💜 Lawful evil`, Race: `🎭 Changeling`, Class: `🧙♂️ Wizard` }),
new RoleplayTreeGridDataItem({ ID: 5, ParentID: 3, Name: `Kalla`, Age: `47`, Alignment: `🤎 Neutral evil`, Race: `🤖 Warforged`, Class: `🦹♂️ Sorcerer` }),
new RoleplayTreeGridDataItem({ ID: 6, ParentID: 2, Name: `Halimath Dundragon`, Age: `149`, Alignment: `🤍 Unaligned`, Race: `🐲 Dragonborn`, Class: `⚔️ Paladin` }),
new RoleplayTreeGridDataItem({ ID: 7, ParentID: 5, Name: `Iriphawa`, Age: `39`, Alignment: `💛 Lawful neutral`, Race: `🧝🏻♂️ Half-Elf`, Class: `🏹 Ranger` }),
new RoleplayTreeGridDataItem({ ID: 8, ParentID: 6, Name: `Quaf`, Age: `25`, Alignment: `💚 Neutral`, Race: `👩 Human`, Class: `🥊 Fighter` }),
new RoleplayTreeGridDataItem({ ID: 9, ParentID: 10, Name: `Rat Scratch`, Age: `15`, Alignment: `🤎 Neutral evil`, Race: `🐡 Locathah`, Class: `🍁 Druid` }),
new RoleplayTreeGridDataItem({ ID: 10, ParentID: 4, Name: `Slicer`, Age: `57`, Alignment: `💜 Lawful evil`, Race: `🐡 Locathah`, Class: `💪 Barbarian` }),
new RoleplayTreeGridDataItem({ ID: 11, ParentID: 7, Name: `Nereones Ahlorsath`, Age: `95`, Alignment: `💛 Lawful neutral`, Race: `👩 Human`, Class: `🥊 Fighter` }),
new RoleplayTreeGridDataItem({ ID: 12, ParentID: 9, Name: `Nalvarti Stonecutter`, Age: `118`, Alignment: `❤️ Neutral good`, Race: `🧝♀️ Elf`, Class: `❤️ Cleric` }),
new RoleplayTreeGridDataItem({ ID: 13, ParentID: 1, Name: `Errk`, Age: `22`, Alignment: `🤎 Neutral evil`, Race: `🧝🏻♂️ Half-Elf`, Class: `🎻 Bard` }),
new RoleplayTreeGridDataItem({ ID: 14, ParentID: 5, Name: `Seven Thundercloud`, Age: `43`, Alignment: `💖 Lawful good`, Race: `🐡 Locathah`, Class: `⚔️ Paladin` }),
new RoleplayTreeGridDataItem({ ID: 15, ParentID: 10, Name: `Navarra Chergoba`, Age: `16`, Alignment: `💜 Lawful evil`, Race: `🐯 Tabaxi`, Class: `❤️ Cleric` }),
new RoleplayTreeGridDataItem({ ID: 16, ParentID: 4, Name: `Sail Snap`, Age: `56`, Alignment: `💖 Lawful good`, Race: `🌳 Arboren`, Class: `💪 Barbarian` }),
new RoleplayTreeGridDataItem({ ID: 17, ParentID: 8, Name: `Urreek`, Age: `17`, Alignment: `💜 Lawful evil`, Race: `🧝🏻♂️ Half-Elf`, Class: `🐉 Warlock` }),
new RoleplayTreeGridDataItem({ ID: 18, ParentID: 6, Name: `Morkral Firetamer`, Age: `24`, Alignment: `🤎 Neutral evil`, Race: `🐲 Dragonborn`, Class: `🙏🏻 Monk` }),
new RoleplayTreeGridDataItem({ ID: 19, ParentID: 2, Name: `Vithka`, Age: `53`, Alignment: `💜 Lawful evil`, Race: `🐡 Locathah`, Class: `⚔️ Paladin` }),
new RoleplayTreeGridDataItem({ ID: 20, ParentID: 7, Name: `Sandrue Avhoste`, Age: `19`, Alignment: `💙 Chaotic Neutral`, Race: `🐲 Dragonborn`, Class: `🗡️ Rogue` }),
new RoleplayTreeGridDataItem({ ID: 21, ParentID: 8, Name: `Hapah Moq`, Age: `34`, Alignment: `💜 Lawful evil`, Race: `🎅🏽 Dwarf`, Class: `🎻 Bard` }),
new RoleplayTreeGridDataItem({ ID: 22, ParentID: 5, Name: `Kothar`, Age: `55`, Alignment: `🤍 Unaligned`, Race: `🧝🏻♂️ Half-Elf`, Class: `🐉 Warlock` }),
new RoleplayTreeGridDataItem({ ID: 23, ParentID: 1, Name: `Senen`, Age: `40`, Alignment: `💜 Lawful evil`, Race: `🧒🏻 Hafling`, Class: `🥊 Fighter` }),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrTreeGridModule } from "@infragistics/igniteui-react-grids";
import { IgrSelectModule } from "@infragistics/igniteui-react";
import { IgrTreeGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebTreeGridDescriptionModule, WebSelectDescriptionModule } from "@infragistics/igniteui-react-core";
import { RoleplayTreeGridDataItem, RoleplayTreeGridData } from './RoleplayTreeGridData';
import { IgrCellTemplateContext } from "@infragistics/igniteui-react-grids";
import { IgrSelect, IgrSelectItem } from "@infragistics/igniteui-react";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrTreeGridModule,
IgrSelectModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private treeGrid1: IgrTreeGrid
private treeGrid1Ref(r: IgrTreeGrid) {
this.treeGrid1 = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.treeGrid1Ref = this.treeGrid1Ref.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrTreeGrid
autoGenerate={false}
ref={this.treeGrid1Ref}
id="treeGrid1"
data={this.roleplayTreeGridData}
primaryKey="ID"
foreignKey="ParentID">
<IgrColumn
field="Name"
header="Character Name"
dataType="string">
</IgrColumn>
<IgrColumn
field="Race"
header="Race"
dataType="string"
editable={true}
inlineEditorTemplate={this.webTreeGridCellEditCellTemplate}>
</IgrColumn>
<IgrColumn
field="Class"
header="Class"
inlineEditorTemplate={this.webTreeGridCellEditCellTemplate}
dataType="string"
editable={true}>
</IgrColumn>
<IgrColumn
field="Age"
header="Age"
dataType="string"
editable={true}>
</IgrColumn>
<IgrColumn
field="Alignment"
header="Alignment"
inlineEditorTemplate={this.webTreeGridCellEditCellTemplate}
dataType="string"
editable={true}>
</IgrColumn>
</IgrTreeGrid>
</div>
</div>
);
}
private _roleplayTreeGridData: RoleplayTreeGridData = null;
public get roleplayTreeGridData(): RoleplayTreeGridData {
if (this._roleplayTreeGridData == null)
{
this._roleplayTreeGridData = new RoleplayTreeGridData();
}
return this._roleplayTreeGridData;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebTreeGridDescriptionModule.register(context);
WebSelectDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webTreeGridCellEditCellTemplate = (e: {dataContext: IgrCellTemplateContext}) => {
let cellValues: any = [];
let uniqueValues: any = [];
const cell = e.dataContext.cell;
const colIndex = cell.id.columnID;
var treeGrid1 = this.treeGrid1;
const field: string = treeGrid1.getColumnByVisibleIndex(colIndex).field;
let roleplayTreeGridData = treeGrid1.data;
const key = field + "_" + cell.id.rowID;
let index = 0;
for(const i of (roleplayTreeGridData as any)){
if(uniqueValues.indexOf(i[field]) === -1 )
{
cellValues.push(<><IgrSelectItem selected={e.dataContext.cell.value == i[field]}
value={i[field]} key={key + "_" + index}>
<div key={key + "_" + index}>{i[field]}</div>
</IgrSelectItem></>);
uniqueValues.push(i[field]);
}
index++;
}
return (
<IgrSelect className="size-large" key={key} onChange={(x: any) => {
setTimeout(() => {
cell.editValue = x.target.value;
});
}}>
{cellValues}
</IgrSelect>
);
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
.size-large {
--ig-size: var(--ig-size-large);
}
css
CRUD 작업
일부 CRUD 작업을 수행하면 필터링, 정렬, 그룹화 등 적용된 모든 파이프가 다시 적용되고 뷰가 자동으로 업데이트된다는 점을 명심하세요.
IgrTreeGrid
기본 CRUD 작업을 위한 간단한 API를 제공합니다.
새 레코드 추가
IgrTreeGrid
구성 요소는 제공된 데이터를 데이터 소스 자체에 추가하는 메서드를 노출 addRow
합니다.
public addNewChildRow() {
// Adding a new record
// Assuming we have a `getNewRecord` method returning the new row data
// And specifying the parentRowID.
const record = this.getNewRecord();
this.treeGrid.addRow(record, 1);
}
typescript
트리 그리드의 데이터 업데이트
트리 그리드의 데이터 업데이트는 updateRow
및 updateCell
메소드를 통해 이루어지지만 그리드의 PrimaryKey가 정의된 경우에만 가능합니다. 또한 해당 업데이트 방법을 통해 셀 및/또는 행 값을 직접 업데이트할 수도 있습니다.
// Updating the whole row
this.treeGrid.updateRow(newData, this.selectedCell.cellID.rowID);
// Just a particular cell through the Tree Grid API
this.treeGrid.updateCell(newData, this.selectedCell.cellID.rowID, this.selectedCell.column.field);
// Directly using the cell `update` method
this.selectedCell.update(newData);
// Directly using the row `update` method
const row = this.treeGrid.getRowByKey(rowID);
row.update(newData);
typescript
트리 그리드에서 데이터 삭제
deleteRow
메소드는 primaryKey
가 정의된 경우에만 지정된 행을 제거한다는 점을 명심하십시오.
// Delete row through Tree Grid API
this.treeGrid.deleteRow(this.selectedCell.cellID.rowID);
// Delete row through row object
const row = this.treeGrid.getRowByIndex(rowIndex);
row.delete();
typescript
편집 이벤트에 대한 셀 유효성 검사
IgrTreeGrid
편집 이벤트를 사용하여 사용자가 상호 작용하는 방식을 변경할 수 있습니다 IgrTreeGrid
.
이 예에서는 CellEdit
이벤트에 바인딩하여 입력된 데이터를 기반으로 셀의 유효성을 검사합니다. 셀의 새 값이 사전 정의된 기준을 충족하지 않는 경우 이벤트를 취소하여 데이터 소스에 도달하지 못하게 합니다.
가장 먼저 해야 할 일은 그리드의 이벤트에 바인딩하는 것입니다.
<IgrTreeGrid onCellEdit={handleCellEdit}>
</IgrTreeGrid>
tsx
CellEdit
셀의 값이 커밋되려고 할 때마다 내보냅니다. CellEdit 정의에서 조치를 취하기 전에 특정 열을 확인해야 합니다.
public webTreeGridCellEdit(args: IgrGridEditEventArgs): void {
const column = args.detail.column;
if (column.field === 'Age') {
if (args.detail.newValue < 18) {
args.detail.cancel = true;
alert('Employees must be at least 18 years old!');
}
} else if (column.field === 'HireDate') {
if (args.detail.newValue > new Date().getTime()) {
args.detail.cancel = true;
alert('The employee hire date must be in the past!');
}
}
}
tsx
위의 유효성 검사가 적용된 IgrTreeGrid
결과는 아래 데모에서 볼 수 있습니다.
export class EmployeesNestedTreeDataItem {
public constructor(init: Partial<EmployeesNestedTreeDataItem>) {
Object.assign(this, init);
}
public Age: number;
public HireDate: string;
public ID: number;
public Name: string;
public Phone: string;
public OnPTO: boolean;
public ParentID: number;
public Title: string;
}
export class EmployeesNestedTreeData extends Array<EmployeesNestedTreeDataItem> {
public constructor(items: Array<EmployeesNestedTreeDataItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new EmployeesNestedTreeDataItem({ Age: 55, HireDate: `2008-03-20`, ID: 1, Name: `Johnathan Winchester`, Phone: `0251-031259`, OnPTO: false, ParentID: -1, Title: `Development Manager` }),
new EmployeesNestedTreeDataItem({ Age: 42, HireDate: `2014-01-22`, ID: 4, Name: `Ana Sanders`, Phone: `(21) 555-0091`, OnPTO: true, ParentID: -1, Title: `CEO` }),
new EmployeesNestedTreeDataItem({ Age: 49, HireDate: `2014-01-22`, ID: 18, Name: `Victoria Lincoln`, Phone: `(071) 23 67 22 20`, OnPTO: true, ParentID: -1, Title: `Accounting Manager` }),
new EmployeesNestedTreeDataItem({ Age: 61, HireDate: `2010-01-01`, ID: 10, Name: `Yang Wang`, Phone: `(21) 555-0091`, OnPTO: false, ParentID: -1, Title: `Localization Manager` }),
new EmployeesNestedTreeDataItem({ Age: 43, HireDate: `2011-06-03`, ID: 3, Name: `Michael Burke`, Phone: `0452-076545`, OnPTO: true, ParentID: 1, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 29, HireDate: `2009-06-19`, ID: 2, Name: `Thomas Anderson`, Phone: `(14) 555-8122`, OnPTO: false, ParentID: 1, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 31, HireDate: `2014-08-18`, ID: 11, Name: `Monica Reyes`, Phone: `7675-3425`, OnPTO: false, ParentID: 1, Title: `Software Development Team Lead` }),
new EmployeesNestedTreeDataItem({ Age: 35, HireDate: `2015-09-17`, ID: 6, Name: `Roland Mendel`, Phone: `(505) 555-5939`, OnPTO: false, ParentID: 11, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 44, HireDate: `2009-10-11`, ID: 12, Name: `Sven Cooper`, Phone: `0695-34 67 21`, OnPTO: true, ParentID: 11, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 44, HireDate: `2014-04-04`, ID: 14, Name: `Laurence Johnson`, Phone: `981-443655`, OnPTO: false, ParentID: 4, Title: `Director` }),
new EmployeesNestedTreeDataItem({ Age: 25, HireDate: `2017-11-09`, ID: 5, Name: `Elizabeth Richards`, Phone: `(2) 283-2951`, OnPTO: true, ParentID: 4, Title: `Vice President` }),
new EmployeesNestedTreeDataItem({ Age: 39, HireDate: `2010-03-22`, ID: 13, Name: `Trevor Ashworth`, Phone: `981-443655`, OnPTO: true, ParentID: 5, Title: `Director` }),
new EmployeesNestedTreeDataItem({ Age: 44, HireDate: `2014-04-04`, ID: 17, Name: `Antonio Moreno`, Phone: `(505) 555-5939`, OnPTO: false, ParentID: 18, Title: `Senior Accountant` }),
new EmployeesNestedTreeDataItem({ Age: 50, HireDate: `2007-11-18`, ID: 7, Name: `Pedro Rodriguez`, Phone: `035-640230`, OnPTO: false, ParentID: 10, Title: `Senior Localization Developer` }),
new EmployeesNestedTreeDataItem({ Age: 27, HireDate: `2016-02-19`, ID: 8, Name: `Casey Harper`, Phone: `0342-023176`, OnPTO: true, ParentID: 10, Title: `Senior Localization` }),
new EmployeesNestedTreeDataItem({ Age: 25, HireDate: `2017-11-09`, ID: 15, Name: `Patricia Simpson`, Phone: `069-0245984`, OnPTO: false, ParentID: 7, Title: `Localization Intern` }),
new EmployeesNestedTreeDataItem({ Age: 39, HireDate: `2010-03-22`, ID: 9, Name: `Francisco Chang`, Phone: `(91) 745 6200`, OnPTO: false, ParentID: 7, Title: `Localization Intern` }),
new EmployeesNestedTreeDataItem({ Age: 25, HireDate: `2018-03-18`, ID: 16, Name: `Peter Lewis`, Phone: `069-0245984`, OnPTO: true, ParentID: 7, Title: `Localization Intern` }),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrTreeGridModule } from "@infragistics/igniteui-react-grids";
import { IgrTreeGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebTreeGridDescriptionModule } from "@infragistics/igniteui-react-core";
import { EmployeesNestedTreeDataItem, EmployeesNestedTreeData } from './EmployeesNestedTreeData';
import { IgrGrid, IgrGridEditEventArgs } from "@infragistics/igniteui-react-grids";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrTreeGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.treeGridRef = this.treeGridRef.bind(this);
this.webTreeGridCellEdit = this.webTreeGridCellEdit.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrTreeGrid
autoGenerate={false}
ref={this.treeGridRef}
id="treeGrid"
data={this.employeesNestedTreeData}
primaryKey="ID"
onCellEdit={this.webTreeGridCellEdit}
foreignKey="ParentID">
<IgrColumn
field="Name"
dataType="string">
</IgrColumn>
<IgrColumn
field="Title"
dataType="string">
</IgrColumn>
<IgrColumn
field="Age"
dataType="number"
editable={true}>
</IgrColumn>
<IgrColumn
field="HireDate"
dataType="date"
editable={true}>
</IgrColumn>
</IgrTreeGrid>
</div>
</div>
);
}
private _employeesNestedTreeData: EmployeesNestedTreeData = null;
public get employeesNestedTreeData(): EmployeesNestedTreeData {
if (this._employeesNestedTreeData == null)
{
this._employeesNestedTreeData = new EmployeesNestedTreeData();
}
return this._employeesNestedTreeData;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebTreeGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webTreeGridCellEdit(args: IgrGridEditEventArgs): void {
const column = args.detail.column;
if (column.field === 'Age') {
if (args.detail.newValue < 18) {
args.detail.cancel = true;
alert('Employees must be at least 18 years old!');
}
} else if (column.field === 'HireDate') {
if (args.detail.newValue > new Date().getTime()) {
args.detail.cancel = true;
alert('The employee hire date must be in the past!');
}
}
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
스타일링
사전 정의된 테마 외에도 사용 가능한 CSS 속성 중 일부를 설정하여 그리드를 추가로 사용자 정의할 수 있습니다. 일부 색상을 변경하려면 먼저 그리드에 대한 클래스를 설정해야 합니다.
<IgrTreeGrid className="treeGrid"></IgrTreeGrid>
tsx
그런 다음 해당 클래스에 대한 관련 CSS 속성을 설정합니다.
.treeGrid {
--ig-grid-edit-mode-color: orange;
--ig-grid-cell-editing-background: lightblue;
}
css
스타일링 예시
export class EmployeesNestedTreeDataItem {
public constructor(init: Partial<EmployeesNestedTreeDataItem>) {
Object.assign(this, init);
}
public Age: number;
public HireDate: string;
public ID: number;
public Name: string;
public Phone: string;
public OnPTO: boolean;
public ParentID: number;
public Title: string;
}
export class EmployeesNestedTreeData extends Array<EmployeesNestedTreeDataItem> {
public constructor(items: Array<EmployeesNestedTreeDataItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new EmployeesNestedTreeDataItem({ Age: 55, HireDate: `2008-03-20`, ID: 1, Name: `Johnathan Winchester`, Phone: `0251-031259`, OnPTO: false, ParentID: -1, Title: `Development Manager` }),
new EmployeesNestedTreeDataItem({ Age: 42, HireDate: `2014-01-22`, ID: 4, Name: `Ana Sanders`, Phone: `(21) 555-0091`, OnPTO: true, ParentID: -1, Title: `CEO` }),
new EmployeesNestedTreeDataItem({ Age: 49, HireDate: `2014-01-22`, ID: 18, Name: `Victoria Lincoln`, Phone: `(071) 23 67 22 20`, OnPTO: true, ParentID: -1, Title: `Accounting Manager` }),
new EmployeesNestedTreeDataItem({ Age: 61, HireDate: `2010-01-01`, ID: 10, Name: `Yang Wang`, Phone: `(21) 555-0091`, OnPTO: false, ParentID: -1, Title: `Localization Manager` }),
new EmployeesNestedTreeDataItem({ Age: 43, HireDate: `2011-06-03`, ID: 3, Name: `Michael Burke`, Phone: `0452-076545`, OnPTO: true, ParentID: 1, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 29, HireDate: `2009-06-19`, ID: 2, Name: `Thomas Anderson`, Phone: `(14) 555-8122`, OnPTO: false, ParentID: 1, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 31, HireDate: `2014-08-18`, ID: 11, Name: `Monica Reyes`, Phone: `7675-3425`, OnPTO: false, ParentID: 1, Title: `Software Development Team Lead` }),
new EmployeesNestedTreeDataItem({ Age: 35, HireDate: `2015-09-17`, ID: 6, Name: `Roland Mendel`, Phone: `(505) 555-5939`, OnPTO: false, ParentID: 11, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 44, HireDate: `2009-10-11`, ID: 12, Name: `Sven Cooper`, Phone: `0695-34 67 21`, OnPTO: true, ParentID: 11, Title: `Senior Software Developer` }),
new EmployeesNestedTreeDataItem({ Age: 44, HireDate: `2014-04-04`, ID: 14, Name: `Laurence Johnson`, Phone: `981-443655`, OnPTO: false, ParentID: 4, Title: `Director` }),
new EmployeesNestedTreeDataItem({ Age: 25, HireDate: `2017-11-09`, ID: 5, Name: `Elizabeth Richards`, Phone: `(2) 283-2951`, OnPTO: true, ParentID: 4, Title: `Vice President` }),
new EmployeesNestedTreeDataItem({ Age: 39, HireDate: `2010-03-22`, ID: 13, Name: `Trevor Ashworth`, Phone: `981-443655`, OnPTO: true, ParentID: 5, Title: `Director` }),
new EmployeesNestedTreeDataItem({ Age: 44, HireDate: `2014-04-04`, ID: 17, Name: `Antonio Moreno`, Phone: `(505) 555-5939`, OnPTO: false, ParentID: 18, Title: `Senior Accountant` }),
new EmployeesNestedTreeDataItem({ Age: 50, HireDate: `2007-11-18`, ID: 7, Name: `Pedro Rodriguez`, Phone: `035-640230`, OnPTO: false, ParentID: 10, Title: `Senior Localization Developer` }),
new EmployeesNestedTreeDataItem({ Age: 27, HireDate: `2016-02-19`, ID: 8, Name: `Casey Harper`, Phone: `0342-023176`, OnPTO: true, ParentID: 10, Title: `Senior Localization` }),
new EmployeesNestedTreeDataItem({ Age: 25, HireDate: `2017-11-09`, ID: 15, Name: `Patricia Simpson`, Phone: `069-0245984`, OnPTO: false, ParentID: 7, Title: `Localization Intern` }),
new EmployeesNestedTreeDataItem({ Age: 39, HireDate: `2010-03-22`, ID: 9, Name: `Francisco Chang`, Phone: `(91) 745 6200`, OnPTO: false, ParentID: 7, Title: `Localization Intern` }),
new EmployeesNestedTreeDataItem({ Age: 25, HireDate: `2018-03-18`, ID: 16, Name: `Peter Lewis`, Phone: `069-0245984`, OnPTO: true, ParentID: 7, Title: `Localization Intern` }),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrPaginatorModule, IgrTreeGridModule } from "@infragistics/igniteui-react-grids";
import { IgrTreeGrid, IgrPaginator, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebPaginatorDescriptionModule, WebTreeGridDescriptionModule } from "@infragistics/igniteui-react-core";
import { EmployeesNestedTreeDataItem, EmployeesNestedTreeData } from './EmployeesNestedTreeData';
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrPaginatorModule,
IgrTreeGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.treeGridRef = this.treeGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrTreeGrid
autoGenerate={false}
ref={this.treeGridRef}
id="treeGrid"
data={this.employeesNestedTreeData}
primaryKey="ID"
allowFiltering={true}
foreignKey="ParentID">
<IgrPaginator
perPage={10}>
</IgrPaginator>
<IgrColumn
field="Name"
dataType="string"
editable={true}>
</IgrColumn>
<IgrColumn
field="Title"
dataType="string"
editable={true}>
</IgrColumn>
<IgrColumn
field="Age"
dataType="number"
editable={true}>
</IgrColumn>
<IgrColumn
field="HireDate"
dataType="date"
editable={true}>
</IgrColumn>
<IgrColumn
field="OnPTO"
dataType="boolean"
editable={true}
width="130px">
</IgrColumn>
</IgrTreeGrid>
</div>
</div>
);
}
private _employeesNestedTreeData: EmployeesNestedTreeData = null;
public get employeesNestedTreeData(): EmployeesNestedTreeData {
if (this._employeesNestedTreeData == null)
{
this._employeesNestedTreeData = new EmployeesNestedTreeData();
}
return this._employeesNestedTreeData;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebPaginatorDescriptionModule.register(context);
WebTreeGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
#treeGrid {
--cell-editing-background: #4567bb;
--cell-active-border-color: #4567bb;
--cell-edited-value-color: #fff;
}
css