React Tree Grid 行の編集
React Tree Grid の Ignite UI for React 行編集機能を使用すると、IgrTreeGrid
内でデータを直接編集できます。データを操作するこの便利な方法に加えて、完全な CRUD 操作のための強力な API があります。行をクリックして Enter キー を押すと、グリッド行の編集を実行できます。もう 1 つの簡単な方法は、変更する必要がある行をマウスでダブルクリックすることです。
React Tree Grid 行編集の例
以下の手順では、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 ));
}
}
}
ts コピー import 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 "@infragistics/igniteui-react-grids/grids/combined" ;
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 );
}
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"
foreignKey ="ParentID"
moving ={true}
rowEditable ={true}
rowSelection ="multiple" >
<IgrColumn
field ="Name"
header ="Full Name"
dataType ="string"
resizable ={true}
sortable ={true}
filterable ={true}
editable ={true} >
</IgrColumn >
<IgrColumn
field ="Age"
dataType ="number"
resizable ={false}
sortable ={false}
filterable ={false}
editable ={true} >
</IgrColumn >
<IgrColumn
field ="Title"
dataType ="string"
resizable ={true}
sortable ={true}
filterable ={true}
editable ={true} >
</IgrColumn >
<IgrColumn
field ="HireDate"
header ="Hire Date"
dataType ="date"
resizable ={true}
sortable ={true}
filterable ={true}
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;
}
}
const root = ReactDOM.createRoot (document.getElementById('root' ));
root.render (<Sample /> );
tsx コピー
このサンプルが気に入りましたか? 完全な Ignite UI for Reactツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
行が編集モードにある場合、他の行のセルをクリックすると [完了] ボタンが押されたように動作し、前の行の変更をすべての変更をサブミットします。新しくフォーカスされたセルが編集可能な場合、新しい行も編集モードになります。ただし、セルが編集可能でない場合は、前の行のみが編集モードを終了します。
行編集の使用
次に IgrTreeGrid
をバインドしたデータソースで定義し、rowEditable
を true に設定してバインドします。
<IgrTreeGrid primaryKey ="ID" width ="100%" height ="500px" rowEditable ="true" >
<IgrColumn field ="Name" header ="Name" dataType ="string" > </IgrColumn >
<IgrColumn field ="Age" header ="Age" dataType ="number" > </IgrColumn >
<IgrColumn field ="Title" header ="Title" dataType ="string" > </IgrColumn >
<IgrColumn field ="HireDate" header ="Hire Date" dataType ="date" > </IgrColumn >
</IgrTreeGrid >
tsx
個々の列の編集を有効にする必要はありません。IgrTreeGrid の rowEditable プロパティを使用すると、定義された field プロパティを持つすべての行 (主行を除く) が編集可能になります。特定の列の編集を無効にしたい場合は、その列の editable 入力を false に設定するだけです。
IgrTreeGrid は、行の状態が送信されるかキャンセルされるまで保留中のセルの変更を保持する内部プロバイダーである BaseTransactionService を利用します。
位置
オーバーレイのデフォルトの位置は編集モードで行の下にあります。
行の下にスペースがない場合、オーバーレイが行の上に表示されます。
一番上または下に表示されると、オーバーレイは閉じられるまでスクロール時にこの位置を保持します。
動作
行が編集モードの場合、編集が継続します。同じ行のセルがクリックされたかどうか。
[完了] ボタンをクリックすると行編集を完了し、変更をデータソースまたはトランザクションへサブミットします。更に行が編集モードを完了します。
[キャンセル] ボタンがをクリックすると現在の行のすべての変更を元に戻し、行編集モードを終了します。
行が編集モードにある場合、他の行のセルをクリックすると現在の行編集を終了し、行の新規の変更をサブミット ([完了] ボタンをクリックした場合と同じ) します。フォーカスのある新しいセルが編集可能かどうか、新しい行が編集モードに入るかどうか、セルが編集できない場合は前の行のみ編集モードを終了します。
行が編集モードの時にグリッドがスクロールされると行が表示領域外になりますが、IgrTreeGrid
は編集モードのままです。IgrTreeGrid
をスクロールすると編集行は再度表示されますが編集行が編集モードのままになります。IgrTreeGrid
以外をクリックしたときにセルも編集モードに残ります。
ソート 、フィルタリング 、検索 、および非表示 操作を実行すると、現在の行のすべての変更が元に戻され、行の編集モードを終了します。
ページング 、サイズ変更 、ピン固定 、移動 操作を実行すると、編集モードを終了して最新の値を送信します。
編集した各セルは行編集が終了するまで変更スタイルを取得します。IgrTreeGrid
がトランザクションで提供されない場合の動作です。トランザクションが有効な場合、すべての変更がコミットされるまでセル編集スタイルが適用されます。
キーボード ナビゲーション
機能の統合
行編集オーバーレイのカスタマイズ
テキストのカスタマイズ
テンプレート化を使用した行編集オーバーレイのテキストのカスタマイズが可能です。
RowChangesCount
プロパティが公開されて変更されたセルのカウントを保持します。
function rowEditTextTemplate(ctx: IgrGridRowEditTextTemplateContext) {
return (
<>
Changes: {ctx.dataContext.implicit}
</>
);
}
tsx
ボタンのカスタマイズ
テンプレート化を使用した行編集オーバーレイのボタンのカスタマイズも可能です。
function rowEditActionsTemplate(ctx: IgrGridRowEditActionsTemplateContext) {
const endRowEdit = ctx.dataContext.implicit;
return (
<>
<button onClick ={(event) => endRowEdit(false , event)}>Cancel</button >
<button onClick ={(event) => endRowEdit(true , event)}>Apply</button >
</>
);
}
tsx
スタイル設定
定義済みのテーマに加えて、利用可能な CSS プロパティ のいくつかを設定することで、グリッドをさらにカスタマイズできます。
一部の色を変更したい場合は、最初にグリッドのクラスを設定する必要があります。
<IgrTreeGrid className ="grid" > </IgrTreeGrid >
tsx
次に、そのクラスに関連する CSS プロパティを設定します。
.grid {
--ig-banner-banner-background : #e3e3e3 ;
--ig-banner-banner-message-color : #423589 ;
}
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 ));
}
}
}
ts コピー import 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 "@infragistics/igniteui-react-grids/grids/combined" ;
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 grid: IgrTreeGrid
private gridRef(r: IgrTreeGrid) {
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" >
<IgrTreeGrid
autoGenerate ={false}
ref ={this.gridRef}
id ="grid"
data ={this.employeesNestedTreeData}
primaryKey ="ID"
foreignKey ="ParentID"
moving ={true}
rowEditable ={true}
rowSelection ="multiple" >
<IgrColumn
field ="Name"
header ="Full Name"
dataType ="string"
resizable ={true}
sortable ={true}
filterable ={true}
editable ={true} >
</IgrColumn >
<IgrColumn
field ="Age"
dataType ="number"
resizable ={false}
sortable ={false}
filterable ={false}
editable ={true} >
</IgrColumn >
<IgrColumn
field ="Title"
dataType ="string"
resizable ={true}
sortable ={true}
filterable ={true}
editable ={true} >
</IgrColumn >
<IgrColumn
field ="HireDate"
header ="Hire Date"
dataType ="date"
resizable ={true}
sortable ={true}
filterable ={true}
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;
}
}
const root = ReactDOM.createRoot (document.getElementById('root' ));
root.render (<Sample /> );
tsx コピー
#grid {
--ig-banner-banner-background : #292826 ;
--ig-banner-banner-message-color : #ffcd0f ;
--ig-button -foreground: #ffcd0f ;
--ig-button -hover-foreground: white;
--ig-button -font-weight : 600 ;
}
css コピー
既知の問題と制限
グリッドに primaryKey
が設定されておらず、リモート データ シナリオが有効になっている場合 (ページング、ソート、フィルタリング、スクロール時に、グリッドに表示されるデータを取得するためのリモート サーバーへのリクエストがトリガーされる場合)、データ要求が完了すると、行は次の状態を失います:
API リファレンス
その他のリソース
コミュニティに参加して新しいアイデアをご提案ください。