React 계층형 그리드 셀 편집
React 계층적 그리드의 Ignite UI for React 셀 편집은 React 계층적 그리드 구성 요소 내에서 개별 셀의 콘텐츠에 대한 뛰어난 데이터 조작 기능을 제공하며 React CRUD 작업을 위한 강력한 API와 함께 제공됩니다. 스프레드시트, 데이터 테이블 및 데이터 그리드와 같은 앱의 기본 기능으로, 사용자가 특정 셀 내에서 데이터를 추가, 편집 또는 업데이트할 수 있습니다. 기본적으로 Ignite UI for React의 그리드는 셀 편집에 사용됩니다. 그리고 기본 셀 편집 템플릿 으로 인해 열 데이터 유형 Top of Form에 따라 다른 편집기가 있습니다.
또한 데이터 업데이트 작업에 대한 사용자 정의 템플릿을 정의하고 변경 사항 커밋 및 삭제에 대한 기본 동작을 재정의할 수 있습니다.
React 계층적 그리드 셀 편집 및 편집 템플릿 예제
import React from 'react' ;
import ReactDOM from 'react-dom/client' ;
import './index.css' ;
import { IgrHierarchicalGridModule, IgrPaginatorModule } from "@infragistics/igniteui-react-grids" ;
import { IgrHierarchicalGrid, IgrPaginator, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids" ;
import { ComponentRenderer, WebHierarchicalGridDescriptionModule, WebPaginatorDescriptionModule } from "@infragistics/igniteui-react-core" ;
import NwindData from './NwindData.json' ;
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css" ;
const mods : any [] = [
IgrHierarchicalGridModule,
IgrPaginatorModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component <any, any> {
private grid: IgrHierarchicalGrid
private gridRef(r: IgrHierarchicalGrid) {
this .grid = r;
this .setState({});
}
constructor (props: any ) {
super (props);
this .gridRef = this .gridRef.bind(this );
}
public render (): JSX .Element {
return (
<div className ="container sample ig-typography" >
<div className ="container fill" >
<IgrHierarchicalGrid
autoGenerate ={false}
id ="grid"
ref ={this.gridRef}
data ={this.nwindData}
primaryKey ="ProductID"
allowFiltering ={true} >
<IgrPaginator
perPage ={10} >
</IgrPaginator >
<IgrColumn
field ="ProductName"
header ="Product Name"
dataType ="string"
sortable ={true}
hasSummary ={true}
editable ={true}
resizable ={true} >
</IgrColumn >
<IgrColumn
field ="UnitsInStock"
header ="Units in Stock"
dataType ="number"
sortable ={true}
hasSummary ={true}
editable ={true}
resizable ={true} >
</IgrColumn >
<IgrColumn
field ="OrderDate"
header ="Order Date"
dataType ="date"
sortable ={true}
hasSummary ={true}
editable ={true}
resizable ={true} >
</IgrColumn >
<IgrColumn
field ="Discontinued"
header ="Discontinued"
dataType ="boolean"
sortable ={true}
hasSummary ={true}
editable ={true} >
</IgrColumn >
<IgrColumn
field ="ReorderLevel"
header ="Reorder Level"
dataType ="number"
sortable ={true}
hasSummary ={true}
editable ={true}
filterable ={false} >
</IgrColumn >
<IgrRowIsland
childDataKey ="Locations"
autoGenerate ={false} >
<IgrColumn
field ="Shop"
header ="Shop"
dataType ="string"
editable ={true}
resizable ={true} >
</IgrColumn >
<IgrColumn
field ="LastInventory"
header ="Last Inventory"
dataType ="date"
editable ={true}
resizable ={true} >
</IgrColumn >
</IgrRowIsland >
</IgrHierarchicalGrid >
</div >
</div >
);
}
private _nwindData: any [] = NwindData;
public get nwindData(): any [] {
return this ._nwindData;
}
private _componentRenderer: ComponentRenderer = null ;
public get renderer(): ComponentRenderer {
if (this ._componentRenderer == null ) {
this ._componentRenderer = new ComponentRenderer();
var context = this ._componentRenderer.context;
WebHierarchicalGridDescriptionModule.register(context);
WebPaginatorDescriptionModule.register(context);
}
return this ._componentRenderer;
}
}
const root = ReactDOM.createRoot (document.getElementById('root' ));
root.render (<Sample /> );
tsx コピー
#grid {
--ig-size: var (--ig-size-medium);
}
css コピー
셀 편집
UI를 통한 편집
다음 방법 중 하나로 편집 가능한 셀에 초점이 맞춰지면 특정 셀에 대한 편집 모드로 들어갈 수 있습니다.
두 번 클릭하면;
한 번 클릭 시 - 이전에 선택한 셀이 편집 모드이고 현재 선택한 셀이 편집 가능한 경우에만 한 번 클릭하면 편집 모드로 들어갑니다. 이전에 선택한 셀이 편집 모드가 아닌 경우 한 번 클릭하면 편집 모드로 들어가지 않고 셀이 선택됩니다.
키 누름 ENTER 시;
키를 누르면 F2 ;
다음 방법 중 하나로 변경 사항을 커밋하지 않고 편집 모드를 종료할 수 있습니다.
키를 누를 때 Escape ;
정렬 , 필터링 , 검색 및 숨기기 작업을 수행할 때
다음 방법 중 하나로 편집 모드를 종료하고 변경 사항을 커밋 할 수 있습니다.
키 누름 ENTER 시;
키를 누르면 F2 ;
키 누름 TAB 시;
다른 셀을 한 번 클릭할 때 - 에서 IgrHierarchicalGrid 다른 셀을 클릭하면 변경 사항이 제출됩니다.
페이징, 크기 조정, 고정 또는 이동과 같은 작업을 수행하면 편집 모드가 종료되고 변경 사항이 제출됩니다.
셀은 세로 또는 가로로 스크롤하거나 IgrHierarchicalGrid 외부를 클릭할 때 편집 모드로 유지됩니다. 이는 셀 편집과 행 편집 모두에 유효합니다.
API를 통한 편집
API를 IgrHierarchicalGrid 통해 셀 값을 수정할 수도 있지만 기본 키가 정의된 경우에만 가능합니다.
public updateCell ( ) {
this .hierarchicalGrid.updateCell(newValue, rowID, 'Age' );
}
typescript
셀을 업데이트하는 또 다른 방법은 다음과 같은 방법을 사용하는 Update 것입니다. Cell
public updateCell ( ) {
const cell = this .hierarchicalGrid.getCellByColumn(rowIndex, 'ReorderLevel' );
cell.update(70 );
}
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
추가 참조를 위해 위의 작업 샘플을 여기에서 찾을 수 있습니다.
import React from 'react' ;
import ReactDOM from 'react-dom/client' ;
import './index.css' ;
import { IgrHierarchicalGridModule } from "@infragistics/igniteui-react-grids" ;
import { IgrSelectModule } from "@infragistics/igniteui-react" ;
import { IgrHierarchicalGrid, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids" ;
import { ComponentRenderer, WebHierarchicalGridDescriptionModule, WebSelectDescriptionModule } from "@infragistics/igniteui-react-core" ;
import HGridDndData from './HGridDndData.json' ;
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 [] = [
IgrHierarchicalGridModule,
IgrSelectModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component <any, any> {
private hierarchicalGrid1: IgrHierarchicalGrid
private hierarchicalGrid1Ref(r: IgrHierarchicalGrid) {
this .hierarchicalGrid1 = r;
this .setState({});
}
constructor (props: any ) {
super (props);
this .hierarchicalGrid1Ref = this .hierarchicalGrid1Ref.bind(this );
}
public render (): JSX .Element {
return (
<div className ="container sample ig-typography" >
<div className ="container fill" >
<IgrHierarchicalGrid
autoGenerate ={false}
data ={this.hGridDndData}
primaryKey ="Name"
ref ={this.hierarchicalGrid1Ref} >
<IgrColumn
field ="Name"
header ="Character Name"
dataType ="string" >
</IgrColumn >
<IgrColumn
field ="Race"
header ="Race"
dataType ="string"
inlineEditorTemplate ={this.hGridCellEditCellTemplate}
editable ={true} >
</IgrColumn >
<IgrColumn
field ="Class"
header ="Class"
inlineEditorTemplate ={this.hGridCellEditCellTemplate}
editable ={true}
dataType ="string" >
</IgrColumn >
<IgrColumn
field ="Age"
header ="Age"
dataType ="string"
editable ={true} >
</IgrColumn >
<IgrColumn
field ="Alignment"
header ="Alignment"
inlineEditorTemplate ={this.hGridCellEditCellTemplate}
editable ={true}
dataType ="string" >
</IgrColumn >
<IgrRowIsland
childDataKey ="Skills"
autoGenerate ={false} >
<IgrColumn
field ="Skill"
header ="Skill"
dataType ="string"
editable ={true}
resizable ={true} >
</IgrColumn >
<IgrColumn
field ="Level"
header ="Level"
dataType ="string"
editable ={true}
resizable ={true} >
</IgrColumn >
</IgrRowIsland >
</IgrHierarchicalGrid >
</div >
</div >
);
}
private _hGridDndData: any [] = HGridDndData;
public get hGridDndData(): any [] {
return this ._hGridDndData;
}
private _componentRenderer: ComponentRenderer = null ;
public get renderer(): ComponentRenderer {
if (this ._componentRenderer == null ) {
this ._componentRenderer = new ComponentRenderer();
var context = this ._componentRenderer.context;
WebHierarchicalGridDescriptionModule.register(context);
WebSelectDescriptionModule.register(context);
}
return this ._componentRenderer;
}
public hGridCellEditCellTemplate = (e: {dataContext: IgrCellTemplateContext}) => {
let cellValues : any = [];
let uniqueValues : any = [];
const cell = e.dataContext.cell;
const colIndex = cell.id.columnID;
let hierarchicalGrid1 = this .hierarchicalGrid1;
const field : string = hierarchicalGrid1.getColumnByVisibleIndex(colIndex).field;
const key = field + "_" + cell.id.rowID;
let index = 0 ;
let hGridDndData = hierarchicalGrid1.data;
for (const i of (hGridDndData 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 >
);
}
}
const root = ReactDOM.createRoot (document.getElementById('root' ));
root.render (<Sample /> );
tsx コピー
.size-large {
--ig-size: var (--ig-size-large);
}
css コピー
CRUD 작업
일부 CRUD 작업을 수행하면 필터링, 정렬, 그룹화 등 적용된 모든 파이프가 다시 적용되고 뷰가 자동으로 업데이트된다는 점을 명심하세요.
IgrHierarchicalGrid 기본 CRUD 작업을 위한 간단한 API를 제공합니다.
새 레코드 추가
IgrHierarchicalGrid 구성 요소는 제공된 데이터를 데이터 소스 자체에 추가하는 메서드를 노출 AddRow 합니다.
public addRow ( ) {
const record = this .getNewRecord();
this .hierarchicalGrid.addRow(record);
}
typescript
계층형 그리드의 데이터 업데이트
계층적 그리드의 데이터 업데이트는 및 updateCell 메서드를 통해 updateRow 수행되지만 그리드의 PrimaryKey가 정의된 경우에만 수행됩니다. 또한 각각의 업데이트 방법을 통해 셀 및/또는 행 값을 직접 업데이트할 수도 있습니다.
this .hierarchicalGrid.updateRow(newData, this .selectedCell.cellID.rowID);
this .hierarchicalGrid.updateCell(newData, this .selectedCell.cellID.rowID, this .selectedCell.column.field);
this .selectedCell.update(newData);
const row = this .hierarchicalGrid.getRowByKey(rowID);
row.update(newData);
typescript
계층형 그리드에서 데이터 삭제
deleteRow 메소드는 primaryKey 가 정의된 경우에만 지정된 행을 제거한다는 점을 명심하십시오.
this .hierarchicalGrid.deleteRow(this .selectedCell.cellID.rowID);
const row = this .hierarchicalGrid.getRowByIndex(rowIndex);
row.delete();
typescript
편집 이벤트에 대한 셀 유효성 검사
IgrHierarchicalGrid 편집 이벤트를 사용하여 사용자가 상호 작용하는 방식을 변경할 수 있습니다 IgrHierarchicalGrid .
이 예에서는 CellEdit 이벤트에 바인딩하여 입력된 데이터를 기반으로 셀의 유효성을 검사합니다. 셀의 새 값이 사전 정의된 기준을 충족하지 않는 경우 이벤트를 취소하여 데이터 소스에 도달하지 못하게 합니다.
가장 먼저 해야 할 일은 그리드의 이벤트에 바인딩하는 것입니다.
<IgrHierarchicalGrid onCellEdit ={handleCellEdit} >
</IgrHierarchicalGrid >
tsx
CellEdit 셀 의 값이 커밋되려고 할 때마다 내보냅니다. CellEdit 정의에서 조치를 취하기 전에 특정 열을 확인해야 합니다.
주문 단위 열 아래의 셀에 입력된 값이 사용 가능한 금액(재고 단위 아래의 값)보다 큰 경우 편집이 취소되고 사용자에게 취소 알림이 표시됩니다.
public handleCellEdit(event: IgrGridEditEventArgs): void {
const detail = args.detail;
if (detail.column != null && d.column.field == "UnitsOnOrder" ) {
if (detail.newValue > detail.rowData.UnitsInStock) {
detail.cancel = true ;
alert("You cannot order more than the units in stock!" );
}
}
}
tsx
위의 유효성 검사가 적용된 IgrHierarchicalGrid 결과는 아래 데모에서 볼 수 있습니다.
import React from 'react' ;
import ReactDOM from 'react-dom/client' ;
import './index.css' ;
import { IgrHierarchicalGridModule, IgrPaginatorModule } from "@infragistics/igniteui-react-grids" ;
import { IgrHierarchicalGrid, IgrPaginator, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids" ;
import { ComponentRenderer, WebHierarchicalGridDescriptionModule, WebPaginatorDescriptionModule } from "@infragistics/igniteui-react-core" ;
import NwindData from './NwindData.json' ;
import { IgrGrid, IgrGridEditEventArgs } from "@infragistics/igniteui-react-grids" ;
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css" ;
const mods : any [] = [
IgrHierarchicalGridModule,
IgrPaginatorModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component <any, any> {
private grid: IgrHierarchicalGrid
private gridRef(r: IgrHierarchicalGrid) {
this .grid = r;
this .setState({});
}
constructor (props: any ) {
super (props);
this .gridRef = this .gridRef.bind(this );
this .webGridEditingEventsCellEdit = this .webGridEditingEventsCellEdit.bind(this );
}
public render (): JSX .Element {
return (
<div className ="container sample ig-typography" >
<div className ="container fill" >
<IgrHierarchicalGrid
autoGenerate ={false}
id ="grid"
ref ={this.gridRef}
data ={this.nwindData}
onCellEdit ={this.webGridEditingEventsCellEdit}
primaryKey ="ProductID"
allowFiltering ={true} >
<IgrPaginator
perPage ={10} >
</IgrPaginator >
<IgrColumn
field ="ProductName"
header ="Product Name"
dataType ="string"
sortable ={true}
hasSummary ={true}
editable ={true}
resizable ={true} >
</IgrColumn >
<IgrColumn
field ="UnitsInStock"
header ="Units in Stock"
dataType ="number"
sortable ={true}
hasSummary ={true}
editable ={true}
resizable ={true} >
</IgrColumn >
<IgrColumn
field ="UnitsOnOrder"
header ="Units in Order"
dataType ="number"
sortable ={true}
hasSummary ={true}
editable ={true}
resizable ={true} >
</IgrColumn >
<IgrColumn
field ="OrderDate"
header ="Order Date"
dataType ="date"
sortable ={true}
hasSummary ={true}
editable ={true}
resizable ={true} >
</IgrColumn >
<IgrColumn
field ="Discontinued"
header ="Discontinued"
dataType ="boolean"
sortable ={true}
hasSummary ={true}
editable ={true} >
</IgrColumn >
<IgrColumn
field ="ReorderLevel"
header ="Reorder Level"
dataType ="number"
sortable ={true}
hasSummary ={true}
editable ={true}
filterable ={false} >
</IgrColumn >
<IgrRowIsland
childDataKey ="Locations"
autoGenerate ={false} >
<IgrColumn
field ="Shop"
header ="Shop"
dataType ="string"
editable ={true}
resizable ={true} >
</IgrColumn >
<IgrColumn
field ="LastInventory"
header ="Last Inventory"
dataType ="date"
editable ={true}
resizable ={true} >
</IgrColumn >
</IgrRowIsland >
</IgrHierarchicalGrid >
</div >
</div >
);
}
private _nwindData: any [] = NwindData;
public get nwindData(): any [] {
return this ._nwindData;
}
private _componentRenderer: ComponentRenderer = null ;
public get renderer(): ComponentRenderer {
if (this ._componentRenderer == null ) {
this ._componentRenderer = new ComponentRenderer();
var context = this ._componentRenderer.context;
WebHierarchicalGridDescriptionModule.register(context);
WebPaginatorDescriptionModule.register(context);
}
return this ._componentRenderer;
}
public webGridEditingEventsCellEdit(args: IgrGridEditEventArgs): void {
var d = args.detail;
if (d.column != null && d.column.field == "UnitsOnOrder" ) {
if (d.newValue > d.rowData.UnitsInStock) {
d.cancel = true ;
alert("You cannot order more than the units in stock!" )
}
}
}
}
const root = ReactDOM.createRoot (document.getElementById('root' ));
root.render (<Sample /> );
tsx コピー
#grid {
--ig-size: var (--ig-size-medium);
}
css コピー
스타일링
사전 정의된 테마 외에도 사용 가능한 CSS 속성 중 일부를 설정하여 그리드를 추가로 사용자 정의할 수 있습니다. 일부 색상을 변경하려면 먼저 그리드에 대한 클래스를 설정해야 합니다.
<IgrHierarchicalGrid className ="hierarchicalGrid" > </IgrHierarchicalGrid >
tsx
그런 다음 해당 클래스에 대한 관련 CSS 속성을 설정합니다.
.hierarchicalGrid {
--ig-grid-edit-mode-color : orange;
--ig-grid-cell-editing-background : lightblue;
}
css
스타일링 예시
API 참조
추가 리소스