React Hierarchical Grid セル編集
React Hierarchical Grid の Ignite UI for React セル編集機能は、React Hierarchical Grid コンポーネント内の個々のセルのコンテンツの優れたデータ操作機能を提供し、React CRUD 操作用の強力な API を備えています。これはスプレッドシート、データ テーブル、データ グリッドなどのアプリの基本的な機能であり、ユーザーが特定のセル内のデータを追加、編集、更新できるようにします。
デフォルトでは、Ignite UI for React の Grid がセル編集に使用されます。また、デフォルトのセル編集テンプレート により、列のデータ型 「Top of Form」 に基づいて異なるエディターが存在します。
さらに、データ更新アクション用の独自のカスタム テンプレートを定義したり、変更をコミット/破棄したりするためのデフォルトの動作をオーバーライドすることもできます。
React Hierarchical Grid セル編集と編集テンプレートの例
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/combined" ;
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 コピー
このサンプルが気に入りましたか? 完全な Ignite UI for Reactツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
セルの編集
UI を介した編集
編集可能なセルがフォーカスされたときに以下のいずれかの方法で特定のセルを編集モードにすることができます。
ダブル クリック
シングル クリック - 以前選択したセルが編集モードで現在選択したセルが編集可能な場合のみ、シングル クリックで編集モードに入ります。以前選択したセルが編集モードではない場合、編集モードに入らずにシングル クリックでセルを選択します。
Enter キーの押下
F2 キーの押下
変更をコミットしない場合 も以下の方法で編集モードを終了できます。
Escape キーの押下;
ソート、フィルターリング、検索、非表示 操作の実行時。
変更をコミット しない場合も以下の方法で編集モードを終了できます。
Enter キーの押下
F2 キーの押下
Tab キーの押下
他のセルをシングル クリック - IgrHierarchicalGrid
で他のセルをクリックしたときに変更がサブミットされます。
その他の操作 (ページング、サイズ変更、ピン固定、移動など) は、編集モードを終了して変更を送信します。
セルは、垂直/水平方向へのスクロールや IgrHierarchicalGrid 以外をクリックした場合も編集モードのままです。セル編集と行編集両方で有効です。
API を介した編集
プライマリキーが定義されている場合のみ IgrHierarchicalGrid
API でもセル値を変更することができます。
public updateCell ( ) {
this .hierarchicalGrid.updateCell(newValue, rowID, 'Age' );
}
typescript
セルを更新するその他の方法として Cell
の Update
メソッドで直接更新する方法があります。
public updateCell ( ) {
const cell = this .hierarchicalGrid.getCellByColumn(rowIndex, 'ReorderLevel' );
cell.update(70 );
}
typescript
セル編集テンプレート
デフォルトのセル編集テンプレートの詳細については、編集トピック を参照してください。
セルに適用されるカスタム テンプレートを提供する場合は、そのテンプレートをセル自体またはそのヘッダーに渡すことができます。まず、通常どおりに列を作成します。
<IgrColumn
field ="race"
header ="Race"
dataType ="String"
editable ="true"
name ="column1"
id ="column1" >
</IgrColumn >
tsx
そして、テンプレートを index.ts ファイルのこの列に渡します。
public webGridCellEditCellTemplate = (e: { dataContext: IgrCellTemplateContext; } ) => {
let cellValues: any = [];
let uniqueValues: any = [];
const cell = e.dataContext.cell;
const colIndex = cell.id.columnID;
const field: string = this .grid1.getColumnByVisibleIndex(colIndex).field;
const key = field + "_" + cell.id.rowID;
let index = 0 ;
for (const i of this .roleplayDataStats 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
key ={key}
change ={(x: any ) => {
setTimeout(() => {
cell.editValue = x.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/combined" ;
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({});
}
private column1: IgrColumn
private column2: IgrColumn
private column3: IgrColumn
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}
name ="column1" >
</IgrColumn >
<IgrColumn
field ="Class"
header ="Class"
inlineEditorTemplate ={this.hGridCellEditCellTemplate}
editable ={true}
dataType ="string"
name ="column2" >
</IgrColumn >
<IgrColumn
field ="Age"
header ="Age"
dataType ="string"
editable ={true} >
</IgrColumn >
<IgrColumn
field ="Alignment"
header ="Alignment"
inlineEditorTemplate ={this.hGridCellEditCellTemplate}
editable ={true}
dataType ="string"
name ="column3" >
</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} change ={(x: any ) => {
setTimeout(() => {
cell.editValue = x.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 操作を実行した場合、filtering、sorting、grouping などのパイプが再適用されるため、ビューが自動的に更新されることに注意してください。
IgrHierarchicalGrid
は基本的な CRUD 操作のための簡易な API を提供します。
新しいレコードの追加
IgrHierarchicalGrid
コンポーネントは、提供したデータをデータ ソースに追加する AddRow
メソッドを公開します。
public addRow ( ) {
const record = this .getNewRecord();
this .hierarchicalGrid.addRow(record);
}
typescript
データを Hierarchical Grid で更新
Hierarchical Grid のデータ更新は、グリッドで PrimaryKey が定義されている場合のみ updateRow
と updateCell
メソッドで行うことができます。セルと行の値またはそのいずれかを各 update メソッドで直接更新できます。
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
Hierarchical Grid からデータを削除
deleteRow
メソッドは、primaryKey
が定義されている場合に指定した行のみを削除することに注意してください。
this .hierarchicalGrid.deleteRow(this .selectedCell.cellID.rowID);
const row = this .hierarchicalGrid.getRowByIndex(rowIndex);
row.del();
typescript
編集イベントでのセル検証
IgrHierarchicalGrid
の編集イベントを使用して、ユーザーが IgrHierarchicalGrid
を操作する方法を変更できます。
この例では、CellEdit
イベントにバインドすることにより、入力されたデータに基づいてセルを検証します。セルの新しい値が事前定義された基準を満たしていない場合、イベントをキャンセルすることでデータソースに到達しないようにします。
最初に必要なことは、グリッドのイベントにバインドすることです。
<IgrHierarchicalGrid cellEdit ={handleCellEdit} >
</IgrHierarchicalGrid >
tsx
CellEdit
は、セルの値 がコミットされる直前に発生します。CellEdit の定義では、アクションを実行する前に特定の列を確認する必要があります。
ここでは、2 つの列を検証しています。ユーザーがアーティストの Debut (デビュー) 年またはアルバムの Launch Date (発売日) を変更しようとした際に、グリッドは今日よりも後の日付を許可しません。
public handleCellEdit(sender: IgrHierarchicalGrid, event: IgrGridEditEventArgs): void {
const today = new Date();
const column = event.detail.column;
if (column.field === 'Debut' ) {
if (event.detail.newValue > today.getFullYear()) {
event.detail.cancel = true ;
alert('The debut date must be in the past!' );
}
} else if (column.field === 'LaunchDate' ) {
if (event.detail.newValue > today) {
event.detail.cancel = true ;
alert('The launch date must be in the past!' );
}
}
}
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/combined" ;
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}
cellEdit ={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(sender: IgrHierarchicalGrid, 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
スタイル設定の例
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/combined" ;
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);
}
#grid {
--ig-grid-edit-mode-color : #FFA500 ;
--ig-grid-cell-active-border-color : #AAFF00 ;
--ig-grid-cell-editing-background : #ADD8E6 ;
}
css コピー
API リファレンス
その他のリソース