React Grid セル編集
React Grid の Ignite UI for React セル編集機能は、React Grid コンポーネント内の個々のセルのコンテンツの優れたデータ操作機能を提供し、React CRUD 操作用の強力な API を備えています。これはスプレッドシート、データ テーブル、データ グリッドなどのアプリの基本的な機能であり、ユーザーが特定のセル内のデータを追加、編集、更新できるようにします。
デフォルトでは、Ignite UI for React の Grid がセル編集に使用されます。また、デフォルトのセル編集テンプレート により、列のデータ型 「Top of Form」 に基づいて異なるエディターが存在します。
さらに、データ更新アクション用の独自のカスタム テンプレートを定義したり、変更をコミット/破棄したりするためのデフォルトの動作をオーバーライドすることもできます。
React Grid セル編集と編集テンプレートの例
import React from 'react' ;
import ReactDOM from 'react-dom/client' ;
import './index.css' ;
import { IgrGridModule, IgrPaginatorModule } from "@infragistics/igniteui-react-grids" ;
import { IgrGrid, IgrPaginator, IgrColumn } from "@infragistics/igniteui-react-grids" ;
import { ComponentRenderer, WebGridDescriptionModule, 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 [] = [
IgrGridModule,
IgrPaginatorModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component <any, any> {
private grid: IgrGrid
private gridRef(r: IgrGrid) {
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" >
<IgrGrid
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 >
</IgrGrid >
</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;
WebGridDescriptionModule.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 キーの押下
他のセルをシングル クリック - IgrGrid
で他のセルをクリックしたときに変更がサブミットされます。
その他の操作 (ページング、サイズ変更、ピン固定、移動など) は、編集モードを終了して変更を送信します。
セルは、垂直/水平方向へのスクロールや IgrGrid 以外をクリックした場合も編集モードのままです。セル編集と行編集両方で有効です。
API を介した編集
プライマリキーが定義されている場合のみ IgrGrid
API でもセル値を変更することができます。
function updateCell ( ) {
grid1Ref.current.updateCell(newValue, rowID, 'ReorderLevel' );
}
typescript
セルを更新するその他の方法として Cell
の update
メソッドで直接更新する方法があります。
function updateCell ( ) {
const cell = grid1Ref.current.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
上記のサンプルは、こちらで参照できます。
export class RoleplayDataStatsItem {
public constructor (init: Partial<RoleplayDataStatsItem> ) {
Object .assign(this , init);
}
public Name: string ;
public Age: string ;
public Alignment: string ;
public Race: string ;
public Class: string ;
}
export class RoleplayDataStats extends Array <RoleplayDataStatsItem > {
public constructor (items: Array <RoleplayDataStatsItem> | number = -1 ) {
if (Array .isArray(items)) {
super (...items);
} else {
const newItems = [
new RoleplayDataStatsItem(
{
Name : `Stredo` ,
Age : `244` ,
Alignment : `💜 Lawful evil` ,
Race : `👩 Human` ,
Class : `🎻 Bard`
}),
new RoleplayDataStatsItem(
{
Name : `Haluun` ,
Age : `40` ,
Alignment : `🤍 Unaligned` ,
Race : `🧒🏻 Hafling` ,
Class : `🙏🏻 Monk`
}),
new RoleplayDataStatsItem(
{
Name : `Ivellios` ,
Age : `244` ,
Alignment : `🧡 Chaotic good` ,
Race : `👩 Human` ,
Class : `⚔️ Paladin`
}),
new RoleplayDataStatsItem(
{
Name : `Tes` ,
Age : `35` ,
Alignment : `💜 Lawful evil` ,
Race : `🎭 Changeling` ,
Class : `🧙♂️ Wizard`
}),
new RoleplayDataStatsItem(
{
Name : `Kalla` ,
Age : `47` ,
Alignment : `🤎 Neutral evil` ,
Race : `🤖 Warforged` ,
Class : `🦹♂️ Sorcerer`
}),
new RoleplayDataStatsItem(
{
Name : `Halimath Dundragon` ,
Age : `149` ,
Alignment : `🤍 Unaligned` ,
Race : `🐲 Dragonborn` ,
Class : `⚔️ Paladin`
}),
new RoleplayDataStatsItem(
{
Name : `Iriphawa` ,
Age : `39` ,
Alignment : `💛 Lawful neutral` ,
Race : `🧝🏻♂️ Half-Elf` ,
Class : `🏹 Ranger`
}),
new RoleplayDataStatsItem(
{
Name : `Quaf` ,
Age : `25` ,
Alignment : `💚 Neutral` ,
Race : `👩 Human` ,
Class : `🥊 Fighter`
}),
new RoleplayDataStatsItem(
{
Name : `Rat Scratch` ,
Age : `15` ,
Alignment : `🤎 Neutral evil` ,
Race : `🐡 Locathah` ,
Class : `🍁 Druid`
}),
new RoleplayDataStatsItem(
{
Name : `Slicer` ,
Age : `57` ,
Alignment : `💜 Lawful evil` ,
Race : `🐡 Locathah` ,
Class : `💪 Barbarian`
}),
new RoleplayDataStatsItem(
{
Name : `Nereones Ahlorsath` ,
Age : `95` ,
Alignment : `💛 Lawful neutral` ,
Race : `👩 Human` ,
Class : `🥊 Fighter`
}),
new RoleplayDataStatsItem(
{
Name : `Nalvarti Stonecutter` ,
Age : `118` ,
Alignment : `❤️ Neutral good` ,
Race : `🧝♀️ Elf` ,
Class : `❤️ Cleric`
}),
new RoleplayDataStatsItem(
{
Name : `Errk` ,
Age : `22` ,
Alignment : `🤎 Neutral evil` ,
Race : `🧝🏻♂️ Half-Elf` ,
Class : `🎻 Bard`
}),
new RoleplayDataStatsItem(
{
Name : `Seven Thundercloud` ,
Age : `43` ,
Alignment : `💖 Lawful good` ,
Race : `🐡 Locathah` ,
Class : `⚔️ Paladin`
}),
new RoleplayDataStatsItem(
{
Name : `Navarra Chergoba` ,
Age : `16` ,
Alignment : `💜 Lawful evil` ,
Race : `🐯 Tabaxi` ,
Class : `❤️ Cleric`
}),
new RoleplayDataStatsItem(
{
Name : `Sail Snap` ,
Age : `56` ,
Alignment : `💖 Lawful good` ,
Race : `🌳 Arboren` ,
Class : `💪 Barbarian`
}),
new RoleplayDataStatsItem(
{
Name : `Urreek` ,
Age : `17` ,
Alignment : `💜 Lawful evil` ,
Race : `🧝🏻♂️ Half-Elf` ,
Class : `🐉 Warlock`
}),
new RoleplayDataStatsItem(
{
Name : `Morkral Firetamer` ,
Age : `24` ,
Alignment : `🤎 Neutral evil` ,
Race : `🐲 Dragonborn` ,
Class : `🙏🏻 Monk`
}),
new RoleplayDataStatsItem(
{
Name : `Vithka` ,
Age : `53` ,
Alignment : `💜 Lawful evil` ,
Race : `🐡 Locathah` ,
Class : `⚔️ Paladin`
}),
new RoleplayDataStatsItem(
{
Name : `Sandrue Avhoste` ,
Age : `19` ,
Alignment : `💙 Chaotic Neutral` ,
Race : `🐲 Dragonborn` ,
Class : `🗡️ Rogue`
}),
new RoleplayDataStatsItem(
{
Name : `Hapah Moq` ,
Age : `34` ,
Alignment : `💜 Lawful evil` ,
Race : `🎅🏽 Dwarf` ,
Class : `🎻 Bard`
}),
new RoleplayDataStatsItem(
{
Name : `Kothar ` ,
Age : `55` ,
Alignment : `🤍 Unaligned` ,
Race : `🧝🏻♂️ Half-Elf` ,
Class : `🐉 Warlock`
}),
new RoleplayDataStatsItem(
{
Name : `Senen` ,
Age : `40` ,
Alignment : `💜 Lawful evil` ,
Race : `🧒🏻 Hafling` ,
Class : `🥊 Fighter`
}),
];
super (...newItems.slice(0 ));
}
}
}
ts コピー import React from 'react' ;
import ReactDOM from 'react-dom/client' ;
import './index.css' ;
import { IgrGridModule } from "@infragistics/igniteui-react-grids" ;
import { IgrSelectModule } from "@infragistics/igniteui-react" ;
import { IgrGrid, IgrColumn } from "@infragistics/igniteui-react-grids" ;
import { ComponentRenderer, WebGridDescriptionModule, WebSelectDescriptionModule } from "@infragistics/igniteui-react-core" ;
import { RoleplayDataStatsItem, RoleplayDataStats } from './RoleplayDataStats' ;
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 [] = [
IgrGridModule,
IgrSelectModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component <any, any> {
private grid1: IgrGrid
private grid1Ref(r: IgrGrid) {
this .grid1 = r;
this .setState({});
}
private column1: IgrColumn
private column2: IgrColumn
private column3: IgrColumn
constructor (props: any ) {
super (props);
this .grid1Ref = this .grid1Ref.bind(this );
}
public render (): JSX .Element {
return (
<div className ="container sample ig-typography" >
<div className ="container fill" >
<IgrGrid
autoGenerate ={false}
ref ={this.grid1Ref}
data ={this.roleplayDataStats}
primaryKey ="Name" >
<IgrColumn
field ="Name"
header ="Character Name"
dataType ="string" >
</IgrColumn >
<IgrColumn
field ="Race"
header ="Race"
dataType ="string"
inlineEditorTemplate ={this.webGridCellEditCellTemplate}
editable ={true}
name ="column1" >
</IgrColumn >
<IgrColumn
field ="Class"
header ="Class"
inlineEditorTemplate ={this.webGridCellEditCellTemplate}
editable ={true}
dataType ="string"
name ="column2" >
</IgrColumn >
<IgrColumn
field ="Age"
header ="Age"
dataType ="string"
editable ={true} >
</IgrColumn >
<IgrColumn
field ="Alignment"
header ="Alignment"
inlineEditorTemplate ={this.webGridCellEditCellTemplate}
editable ={true}
dataType ="string"
name ="column3" >
</IgrColumn >
</IgrGrid >
</div >
</div >
);
}
private _roleplayDataStats: RoleplayDataStats = null ;
public get roleplayDataStats(): RoleplayDataStats {
if (this ._roleplayDataStats == null )
{
this ._roleplayDataStats = new RoleplayDataStats();
}
return this ._roleplayDataStats;
}
private _componentRenderer: ComponentRenderer = null ;
public get renderer(): ComponentRenderer {
if (this ._componentRenderer == null ) {
this ._componentRenderer = new ComponentRenderer();
var context = this ._componentRenderer.context;
WebGridDescriptionModule.register(context);
WebSelectDescriptionModule.register(context);
}
return this ._componentRenderer;
}
public webGridCellEditCellTemplate = (e: {dataContext: IgrCellTemplateContext}) => {
let cellValues : any = [];
let uniqueValues : any = [];
const cell = e.dataContext.cell;
const colIndex = cell.id.columnID;
let grid1 = this .grid1;
const field : string = grid1.getColumnByVisibleIndex(colIndex).field;
const key = field + "_" + cell.id.rowID;
let index = 0 ;
let roleplayDataStats = grid1.data;
for (const i of (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 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 コピー
Grid Excel スタイル編集
Excel スタイル編集を使用すると、Excel を使用する場合と同じようにセルをナビゲートし、すばやく編集できます。
このカスタム機能を実装するには、IgrGrid
のイベントを使用します。最初にグリッドの keydown イベントにフックし、そこから 2 つの機能を実装できます。
function keydownHandler (event ) {
const key = event.keyCode;
const grid = grid1Ref.current;
const activeElem = grid.navigation.activeNode;
if ((key >= 48 && key <= 57 ) ||
(key >= 65 && key <= 90 ) ||
(key >= 97 && key <= 122 )) {
const columnName = grid.getColumnByVisibleIndex(activeElem.column).field;
const cell = grid.getCellByColumn(activeElem.row, columnName);
if (cell && !grid.crudService.cellInEditMode) {
grid.crudService.enterEditMode(cell);
cell.editValue = event.key;
}
}
}
typescript
Enter /Shift+Enter ナビゲーション
if (key == 13 ) {
let thisRow = activeElem.row;
const column = activeElem.column;
const rowInfo = grid.dataView;
let nextRow = getNextEditableRowIndex(thisRow, rowInfo, event.shiftKey);
grid1Ref.current.navigateTo(nextRow, column, (obj ) => {
obj.target.activate();
grid1Ref.current.clearCellSelection();
});
}
typescript
次の適格なインデックスを見つけるための重要な部分は以下のようになります。
if (currentRowIndex < 0 || (currentRowIndex === 0 && previous) || (currentRowIndex >= dataView.length - 1 && !previous)) {
return currentRowIndex;
}
if (previous) {
return dataView.findLastIndex((rec, index ) => index < currentRowIndex && this .isEditableDataRecordAtIndex(index, dataView));
}
return dataView.findIndex((rec, index ) => index > currentRowIndex && this .isEditableDataRecordAtIndex(index, dataView));
typescript
詳細については、サンプルを参照してください。
React Grid Excel スタイル編集のサンプル
import React from 'react' ;
import ReactDOM from 'react-dom/client' ;
import './index.css' ;
import { IgrGridModule } from "@infragistics/igniteui-react-grids" ;
import { IgrGrid, IgrColumn } from "@infragistics/igniteui-react-grids" ;
import { ComponentRenderer, WebGridDescriptionModule } from "@infragistics/igniteui-react-core" ;
import NwindData from './NwindData.json' ;
import { IgrGridKeydownEventArgs } 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 [] = [
IgrGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component <any, any> {
private grid1: IgrGrid
private grid1Ref(r: IgrGrid) {
this .grid1 = r;
this .setState({});
}
constructor (props: any ) {
super (props);
this .grid1Ref = this .grid1Ref.bind(this );
this .webGridEditingExcelStyle = this .webGridEditingExcelStyle.bind(this );
}
public render (): JSX .Element {
return (
<div className ="container sample ig-typography" >
<div className ="container fill" >
<IgrGrid
autoGenerate ={false}
data ={this.nwindData}
primaryKey ="ProductID"
gridKeydown ={this.webGridEditingExcelStyle}
ref ={this.grid1Ref} >
<IgrColumn
field ="ProductID"
header ="Product ID"
editable ={true}
groupable ={true}
hidden ={true} >
</IgrColumn >
<IgrColumn
field ="ProductName"
header ="Product Name"
dataType ="String"
editable ={true} >
</IgrColumn >
<IgrColumn
field ="UnitPrice"
header ="Unit Price"
dataType ="Number"
editable ={true} >
</IgrColumn >
<IgrColumn
field ="QuantityPerUnit"
header ="Quantity Per Unit"
groupable ={true}
dataType ="String"
editable ={true} >
</IgrColumn >
<IgrColumn
field ="ReorderLevel"
header ="Reorder Level"
dataType ="Number"
groupable ={true}
editable ={true} >
</IgrColumn >
</IgrGrid >
</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;
WebGridDescriptionModule.register(context);
}
return this ._componentRenderer;
}
public webGridEditingExcelStyle(sender: IgrGrid, args: IgrGridKeydownEventArgs): void {
var key = (args.detail.event as any ).keyCode;
var grid = args.detail.target.grid;
var activeElem = grid.navigation.activeNode;
if ((key >= 48 && key <= 57) || (key > = 65 && key <= 90) || (key > = 97 && key <= 122)) {
var columnName = grid.getColumnByVisibleIndex(activeElem.column).field;
var cell = grid.getCellByColumn(activeElem.row, columnName);
if (cell && !grid.crudService.cellInEditMode) {
grid.crudService.enterEditMode(cell);
cell.editValue = key;
}
}
if (key == 13) {
var thisRow = activeElem.row;
var column = activeElem.column;
var rowInfo = grid.dataView;
var nextRow = this.getNextEditableRowIndex(thisRow, rowInfo, (args.detail.event as any).shiftKey);
grid.navigateTo(nextRow, column, (obj: any) => {
obj.target.activate();
grid.clearCellSelection();
});
}
}
public getNextEditableRowIndex(currentRowIndex: number , dataView: any , previous: boolean ) {
if (currentRowIndex < 0 || (currentRowIndex === 0 && previous) || (currentRowIndex > = dataView.length - 1 && !previous)) {
return currentRowIndex;
}
if (previous) {
return dataView.findLastIndex((rec: any , index: number ) => index < currentRowIndex && this.isEditableDataRecordAtIndex(index, dataView));
}
return dataView.findIndex((rec: any, index: number) => index > currentRowIndex && this .isEditableDataRecordAtIndex(index, dataView));
}
public isEditableDataRecordAtIndex(dataViewIndex: number , dataView: any ) {
const rec = dataView[dataViewIndex];
return !rec.expression && !rec.summaries && !rec.childGridsData && !rec.detailsData;
}
}
const root = ReactDOM.createRoot (document.getElementById('root' ));
root.render (<Sample /> );
tsx コピー
上記のアプローチの主な利点は次のとおりです:
常時編集モード: セルが選択されているときに入力すると、編集モードに入り、入力された値が既存の値を置き換えます。
Enter /Shift+Enter で移動する場合、データ以外の行はスキップされます。これにより、ユーザーは値をすばやく切り替えることができます。
CRUD 操作
CRUD 操作を実行した場合、filtering、sorting、grouping などのパイプが再適用されるため、ビューが自動的に更新されることに注意してください。
IgrGrid
は基本的な CRUD 操作のための簡易な API を提供します。
新しいレコードの追加
IgrGrid
コンポーネントは、提供したデータをデータ ソースに追加する addRow
メソッドを公開します。
const record = getNewRecord();
grid1Ref.current.addRow(record);
typescript
データを Grid で更新
Grid のデータ更新は、グリッドで PrimaryKey が定義されている場合のみ updateRow
と updateCell
メソッドで行うことができます。セルと行の値またはそのいずれかを各 update メソッドで直接更新できます。
grid1Ref.current.updateRow(newData, this .selectedCell.cellID.rowID);
grid1Ref.current.updateCell(newData, this .selectedCell.cellID.rowID, this .selectedCell.column.field);
selectedCell.update(newData);
const row = grid1Ref.current.getRowByKey(rowID);
row.update(newData);
typescript
Grid からデータを削除
deleteRow
メソッドは、primaryKey
が定義されている場合に指定した行のみを削除することに注意してください。
grid1Ref.current.deleteRow(selectedCell.cellID.rowID);
const row = grid1Ref.current.getRowByIndex(rowIndex);
row.del();
typescript
編集イベントでのセル検証
IgrGrid
の編集イベントを使用して、ユーザーが IgrGrid
を操作する方法を変更できます。
この例では、CellEdit
イベントにバインドすることにより、入力されたデータに基づいてセルを検証します。セルの新しい値が事前定義された基準を満たしていない場合、イベントをキャンセルすることでデータソースに到達しないようにします。
最初に必要なことは、グリッドのイベントにバインドすることです。
<IgrGrid cellEdit ={handleCellEdit} >
</IgrGrid >
tsx
CellEdit
は、セルの値 がコミットされる直前に発生します。CellEdit の定義では、アクションを実行する前に特定の列を確認する必要があります。
function handleCellEdit (s: IgrGridBaseDirective, args: IgrGridEditEventArgs ): void {
const column = args.detail.column;
if (column.field === 'UnitsOnOrder' ) {
const rowData = args.detail.rowData;
if (!rowData) {
return ;
}
if (args.detail.newValue > rowData.UnitsInStock) {
args.detail.cancel = true ;
alert("You cannot order more than the units in stock!" );
}
}
}
typescript
Units On Order (注文済み) 列の下のセルに入力された値が使用可能量 (Units in Stock、在庫数 の値) よりも大きい場合、編集はキャンセルされ、ユーザーにキャンセルの警告が表示されます。
以下は、上記の検証が IgrGrid
に適用された結果のデモです。
import React from 'react' ;
import ReactDOM from 'react-dom/client' ;
import './index.css' ;
import { IgrGridModule } from "@infragistics/igniteui-react-grids" ;
import { IgrGrid, IgrColumn } from "@infragistics/igniteui-react-grids" ;
import { ComponentRenderer, WebGridDescriptionModule } from "@infragistics/igniteui-react-core" ;
import NwindData from './NwindData.json' ;
import { 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 [] = [
IgrGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component <any, any> {
private grid1: IgrGrid
private grid1Ref(r: IgrGrid) {
this .grid1 = r;
this .setState({});
}
private unitsInStock: IgrColumn
private unitsOnOrder: IgrColumn
constructor (props: any ) {
super (props);
this .grid1Ref = this .grid1Ref.bind(this );
this .webGridEditingEventsCellEdit = this .webGridEditingEventsCellEdit.bind(this );
}
public render (): JSX .Element {
return (
<div className ="container sample ig-typography" >
<div className ="container fill" >
<IgrGrid
autoGenerate ={false}
data ={this.nwindData}
primaryKey ="ProductID"
cellEdit ={this.webGridEditingEventsCellEdit}
ref ={this.grid1Ref} >
<IgrColumn
field ="ProductName"
header ="Product Name"
dataType ="string" >
</IgrColumn >
<IgrColumn
field ="UnitPrice"
header ="Unit Price"
dataType ="number"
editable ={true} >
</IgrColumn >
<IgrColumn
name ="UnitsInStock"
field ="UnitsInStock"
header ="Units In Stock"
dataType ="number"
editable ={true} >
</IgrColumn >
<IgrColumn
name ="UnitsOnOrder"
field ="UnitsOnOrder"
header ="Units on Order"
dataType ="number"
editable ={true} >
</IgrColumn >
</IgrGrid >
</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;
WebGridDescriptionModule.register(context);
}
return this ._componentRenderer;
}
public webGridEditingEventsCellEdit(sender: IgrGrid, 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 コピー
スタイル設定
事前定義されたテーマに加えて、利用可能な CSS プロパティ を設定することでグリッドをさらにカスタマイズできます。
一部の色を変更したい場合は、最初にグリッドのクラスを設定する必要があります。
<IgrGrid className ="grid" > </IgrGrid >
tsx
次に、そのクラスに関連する CSS プロパティを設定します。
.grid {
--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 { IgrGridModule, IgrPaginatorModule } from "@infragistics/igniteui-react-grids" ;
import { IgrGrid, IgrPaginator, IgrColumn } from "@infragistics/igniteui-react-grids" ;
import { ComponentRenderer, WebGridDescriptionModule, 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 [] = [
IgrGridModule,
IgrPaginatorModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component <any, any> {
private grid: IgrGrid
private gridRef(r: IgrGrid) {
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" >
<IgrGrid
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 >
</IgrGrid >
</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;
WebGridDescriptionModule.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 リファレンス
その他のリソース