React Grid 選択の概要
React Grid の Ignite UI for React 選択機能を使用すると、単純なマウス操作を使用してデータを簡単に操作および操作できます。使用可能な選択モードは 3 つあります。
rowSelection
プロパティを使用すると、以下を指定できます。
- None (なし)
- Single (単一)
- Multiple Select (複数選択)
React Grid 選択の例
以下のサンプルは、IgrGrid
の 3 種類のセル選択動作を示しています。以下のボタンを使用して、利用可能な各選択モードを有効にします。
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrPropertyEditorPanelModule } from "@infragistics/igniteui-react-layouts";
import { IgrGridModule } from "@infragistics/igniteui-react-grids";
import { IgrPropertyEditorPanel, IgrPropertyEditorPropertyDescription } from "@infragistics/igniteui-react-layouts";
import { IgrGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, PropertyEditorPanelDescriptionModule, WebGridDescriptionModule } 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";
import 'igniteui-webcomponents/themes/light/bootstrap.css';
const mods: any[] = [
IgrPropertyEditorPanelModule,
IgrGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private propertyEditor: IgrPropertyEditorPanel
private propertyEditorRef(r: IgrPropertyEditorPanel) {
this.propertyEditor = r;
this.setState({});
}
private cellSelectionEditor: IgrPropertyEditorPropertyDescription
private grid: IgrGrid
private gridRef(r: IgrGrid) {
this.grid = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.propertyEditorRef = this.propertyEditorRef.bind(this);
this.gridRef = this.gridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="options vertical">
<IgrPropertyEditorPanel
ref={this.propertyEditorRef}
componentRenderer={this.renderer}
target={this.grid}
descriptionType="WebGrid"
isHorizontal="true"
isWrappingEnabled="true">
<IgrPropertyEditorPropertyDescription
propertyPath="CellSelection"
name="CellSelectionEditor"
valueType="EnumValue"
dropDownNames={["None", "Single", "Multiple"]}
dropDownValues={["NOne", "Single", "Multiple"]}>
</IgrPropertyEditorPropertyDescription>
</IgrPropertyEditorPanel>
</div>
<div className="container fill">
<IgrGrid
autoGenerate="false"
ref={this.gridRef}
data={this.nwindData}>
<IgrColumn
field="ProductID"
header="Product ID">
</IgrColumn>
<IgrColumn
field="ProductName"
header="Product Name">
</IgrColumn>
<IgrColumn
field="UnitsInStock"
header="Units In Stock"
dataType="Number">
</IgrColumn>
<IgrColumn
field="UnitPrice"
header="Units Price"
dataType="Number">
</IgrColumn>
<IgrColumn
field="Discontinued"
dataType="Boolean">
</IgrColumn>
<IgrColumn
field="OrderDate"
header="Order Date"
dataType="Date">
</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;
PropertyEditorPanelDescriptionModule.register(context);
WebGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx
このサンプルが気に入りましたか? 完全な Ignite UI for Reactツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
React Grid 選択のオプション
Ignite UI for React IgrGrid
コンポーネントは、行選択、セル選択、列選択の 3 つの選択モードを提供します。デフォルトでは、IgrGrid
で複数セル選択モードのみが有効になっています。選択モードの変更または有効化は、rowSelection
、cellSelection
または selectable
プロパティを使用します。
React Grid 行選択
プロパティ rowSelection
を使用すると、次のオプションを指定できます。
None
- IgrGrid
の行選択が無効になります。
Single
- IgrGrid
内の 1 行のみの選択が利用可能になります。
Multiple
- 複数行の選択は、Ctrl + クリック、Space キー を押して行セレクターを使用することにより、複数行の選択が可能になります。
詳細については、行選択トピックを参照してください。
React Grid セル選択
以下のオプションは、プロパティ cellSelection
で指定できます。
None
- IgrGrid
のセル選択が無効になります。
Single
- IgrGrid
内の 1 セルのみの選択が利用可能になります。
Multiple
- IgrGrid
の選択のデフォルト状態です。複数セルの選択は、マウスの左ボタンを連続してクリックした後、マウスをセル上にドラッグすることで利用できます。
詳細については、セル選択トピックを参照してください。
React Grid 列選択
selectable
プロパティを使用して、IgrColumn
ごとに以下のオプションを指定できます。このプロパティが true または false に設定されている場合、対応する列の選択がそれぞれ有効または無効になります。
以下の 3 つのバリエーションがあります。
- Single selection (単一選択) - 列セルをマウス クリックします。
- Multi column selection (複数列の選択) - Ctrl キーを押しながら列セルをマウス クリックします。
- Range column selection (列の範囲選択) - Shift キーを押しながら + マウス クリック、その間のすべての列が選択されます。
詳細については、列選択トピックを参照してください。
React Grid コンテキスト メニュー
ContextMenu
イベントは、カスタム コンテキスト メニューを追加して、IgrGrid
での作業をアシストします。グリッドの本体を右クリックすると、イベントはトリガーされたセルを放出します。コンテキスト メニューは、放出されたセルで動作します。
複数セルの選択がある場合、選択したセルが複数セルの選択領域にあるかどうかをチェックするロジックを配置します。その場合、選択したセルの値も出力します。
基本的に、メイン関数は次のようになります。
function rightClick(grid: IgrGridBaseDirective, event: IgrGridCellEventArgs) {
const eventArgs = event.detail;
eventArgs.event.preventDefault();
const node = eventArgs.cell.id;
const isCellWithinRange = grid.getSelectedRanges().some((range: any) => {
if (node.columnID >= range.columnStart &&
node.columnID <= range.columnEnd &&
node.rowIndex >= range.rowStart &&
node.rowIndex <= range.rowEnd
) {
return true;
}
return false;
});
setIsCellWithinRange(isCellWithinRange);
setClickedCell(eventArgs.cell);
openContextMenu(eventArgs.event.clientX, eventArgs.event.clientY)
}
tsx
以下はコンテキストメニューの機能です。
- 選択したセルの value のコピー。
- 選択したセルの dataRow のコピー。
- 選択したセルが複数セルの選択範囲内にある場合、選択したすべてのデータをコピーします。
function copySelectedRowData() {
const selectedData = gridRef.current.getRowData(clickedCell.id.rowID);
copyData(selectedData);
closeContextMenu();
}
function copySelectedCellData() {
const selectedData = clickedCell.value;
copyData(selectedData);
closeContextMenu();
}
function copySelectedData() {
const selectedData = gridRef.current.getSelectedData(null,null);
copyData(selectedData);
closeContextMenu();
}
function copyData(data: any[]) {
const tempElement = document.createElement('input');
document.body.appendChild(tempElement);
tempElement.setAttribute('id', 'temp_id');
(document.getElementById('temp_id') as HTMLInputElement).value = JSON.stringify(data);
tempElement.select();
document.execCommand('copy');
document.body.removeChild(tempElement);
setSelectedData(JSON.stringify(data));
}
tsx
IgrGrid
はコピーされたデータを取得し、コンテナ要素に貼り付けます。
グリッドとコンテキスト メニューを組み合わせるために使用するテンプレート:
<>
<div className="container sample">
<div className="wrapper" onClick={closeContextMenu}>
<IgrGrid
autoGenerate="false"
data={northWindData}
primaryKey="ProductID"
ref={gridRef}
contextMenu={rightClick}>
<IgrColumn field="ProductID" header="Product ID">
</IgrColumn>
<IgrColumn field="ProductName" header="Product Name">
</IgrColumn>
<IgrColumn field="UnitsInStock" header="Units In Stock" dataType="number">
</IgrColumn>
<IgrColumn field="UnitPrice" header="Units Price" dataType="number">
</IgrColumn>
<IgrColumn field="Discontinued" dataType="boolean">
</IgrColumn>
<IgrColumn field="OrderDate" header="Order Date" dataType="date">
</IgrColumn>
</IgrGrid>
<div className="selected-data-area">
{selectedData}
</div>
</div>
</div>
<div style={{display: "none"}} className="contextmenu" ref={contextMenuRef}>
<span className="item" onClick={copySelectedCellData}>
<IgrIcon ref={iconRef} collection='material' name="content_copy"></IgrIcon>Copy Cell Data
</span>
<span className="item" onClick={copySelectedRowData}>
<IgrIcon collection='material' name="content_copy"></IgrIcon>Copy Row Data
</span>
{isCellWithinRange && (
<span className="item" onClick={copySelectedData}>
<IgrIcon collection='material' name="content_copy"></IgrIcon>Copy Cells Data
</span>)}
</div>
</>
tsx
複数のセルを選択し、マウスの右ボタンを押します。コンテキストメニューが表示され、セル データのコピー を選択すると、選択したデータが右側の空のボックスに表示されます。
結果:
export class NwindDataItem {
public constructor(init: Partial<NwindDataItem>) {
Object.assign(this, init);
}
public ProductID: number;
public ProductName: string;
public SupplierID: number;
public CategoryID: number;
public QuantityPerUnit: string;
public UnitPrice: number;
public UnitsInStock: number;
public UnitsOnOrder: number;
public ReorderLevel: number;
public Discontinued: boolean;
public OrderDate: string;
public Rating: number;
public Locations: NwindDataItem_LocationsItem[];
}
export class NwindDataItem_LocationsItem {
public constructor(init: Partial<NwindDataItem_LocationsItem>) {
Object.assign(this, init);
}
public Shop: string;
public LastInventory: string;
}
export class NwindData extends Array<NwindDataItem> {
public constructor() {
super();
this.push(new NwindDataItem(
{
ProductID: 1,
ProductName: `Chai`,
SupplierID: 1,
CategoryID: 1,
QuantityPerUnit: `10 boxes x 20 bags`,
UnitPrice: 18,
UnitsInStock: 39,
UnitsOnOrder: 30,
ReorderLevel: 10,
Discontinued: false,
OrderDate: `2012-02-12`,
Rating: 5,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Fun-Tasty Co.`,
LastInventory: `06/12/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 2,
ProductName: `Chang`,
SupplierID: 1,
CategoryID: 1,
QuantityPerUnit: `24 - 12 oz bottles`,
UnitPrice: 19,
UnitsInStock: 17,
UnitsOnOrder: 40,
ReorderLevel: 25,
Discontinued: true,
OrderDate: `2003-03-17`,
Rating: 5,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Super Market`,
LastInventory: `09/09/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 3,
ProductName: `Aniseed Syrup`,
SupplierID: 1,
CategoryID: 2,
QuantityPerUnit: `12 - 550 ml bottles`,
UnitPrice: 10,
UnitsInStock: 13,
UnitsOnOrder: 70,
ReorderLevel: 25,
Discontinued: false,
OrderDate: `2006-03-17`,
Rating: 3,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Street Market`,
LastInventory: `12/12/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `24/7 Market`,
LastInventory: `11/11/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 4,
ProductName: `Chef Antons Cajun Seasoning`,
SupplierID: 2,
CategoryID: 2,
QuantityPerUnit: `48 - 6 oz jars`,
UnitPrice: 22,
UnitsInStock: 53,
UnitsOnOrder: 30,
ReorderLevel: 0,
Discontinued: false,
OrderDate: `2016-03-17`,
Rating: 3,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Fun-Tasty Co.`,
LastInventory: `06/12/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Street Market`,
LastInventory: `12/12/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 5,
ProductName: `Chef Antons Gumbo Mix`,
SupplierID: 2,
CategoryID: 2,
QuantityPerUnit: `36 boxes`,
UnitPrice: 21.35,
UnitsInStock: 0,
UnitsOnOrder: 30,
ReorderLevel: 0,
Discontinued: true,
OrderDate: `2011-11-11`,
Rating: 5,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Super Market`,
LastInventory: `09/09/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 6,
ProductName: `Grandmas Boysenberry Spread`,
SupplierID: 3,
CategoryID: 2,
QuantityPerUnit: `12 - 8 oz jars`,
UnitPrice: 25,
UnitsInStock: 0,
UnitsOnOrder: 30,
ReorderLevel: 25,
Discontinued: false,
OrderDate: `2017-12-17`,
Rating: 4,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Super Market`,
LastInventory: `09/09/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 7,
ProductName: `Uncle Bobs Organic Dried Pears`,
SupplierID: 3,
CategoryID: 7,
QuantityPerUnit: `12 - 1 lb pkgs.`,
UnitPrice: 30,
UnitsInStock: 150,
UnitsOnOrder: 30,
ReorderLevel: 10,
Discontinued: false,
OrderDate: `2016-07-17`,
Rating: 5,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Fun-Tasty Co.`,
LastInventory: `06/12/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Street Market`,
LastInventory: `12/12/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 8,
ProductName: `Northwoods Cranberry Sauce`,
SupplierID: 3,
CategoryID: 2,
QuantityPerUnit: `12 - 12 oz jars`,
UnitPrice: 40,
UnitsInStock: 6,
UnitsOnOrder: 30,
ReorderLevel: 0,
Discontinued: false,
OrderDate: `2018-01-17`,
Rating: 4,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Fun-Tasty Co.`,
LastInventory: `06/12/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 9,
ProductName: `Mishi Kobe Niku`,
SupplierID: 4,
CategoryID: 6,
QuantityPerUnit: `18 - 500 g pkgs.`,
UnitPrice: 97,
UnitsInStock: 29,
UnitsOnOrder: 30,
ReorderLevel: 0,
Discontinued: true,
OrderDate: `2010-02-17`,
Rating: 4,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 10,
ProductName: `Ikura`,
SupplierID: 4,
CategoryID: 8,
QuantityPerUnit: `12 - 200 ml jars`,
UnitPrice: 31,
UnitsInStock: 31,
UnitsOnOrder: 30,
ReorderLevel: 0,
Discontinued: false,
OrderDate: `2008-05-17`,
Rating: 3,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Wall Market`,
LastInventory: `12/06/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 11,
ProductName: `Queso Cabrales`,
SupplierID: 5,
CategoryID: 4,
QuantityPerUnit: `1 kg pkg.`,
UnitPrice: 21,
UnitsInStock: 22,
UnitsOnOrder: 30,
ReorderLevel: 30,
Discontinued: false,
OrderDate: `2009-01-17`,
Rating: 5,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Fun-Tasty Co.`,
LastInventory: `06/12/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 12,
ProductName: `Queso Manchego La Pastora`,
SupplierID: 5,
CategoryID: 4,
QuantityPerUnit: `10 - 500 g pkgs.`,
UnitPrice: 38,
UnitsInStock: 86,
UnitsOnOrder: 30,
ReorderLevel: 0,
Discontinued: false,
OrderDate: `2015-11-17`,
Rating: 3,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 13,
ProductName: `Konbu`,
SupplierID: 6,
CategoryID: 8,
QuantityPerUnit: `2 kg box`,
UnitPrice: 6,
UnitsInStock: 24,
UnitsOnOrder: 30,
ReorderLevel: 5,
Discontinued: false,
OrderDate: `2015-03-17`,
Rating: 2,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Super Market`,
LastInventory: `09/09/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 14,
ProductName: `Tofu`,
SupplierID: 6,
CategoryID: 7,
QuantityPerUnit: `40 - 100 g pkgs.`,
UnitPrice: 23.25,
UnitsInStock: 35,
UnitsOnOrder: 30,
ReorderLevel: 0,
Discontinued: false,
OrderDate: `2017-06-17`,
Rating: 4,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Street Market`,
LastInventory: `12/12/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 15,
ProductName: `Genen Shouyu`,
SupplierID: 6,
CategoryID: 2,
QuantityPerUnit: `24 - 250 ml bottles`,
UnitPrice: 15.5,
UnitsInStock: 39,
UnitsOnOrder: 30,
ReorderLevel: 5,
Discontinued: false,
OrderDate: `2014-03-17`,
Rating: 4,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Local Market`,
LastInventory: `07/03/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Wall Market`,
LastInventory: `12/06/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 16,
ProductName: `Pavlova`,
SupplierID: 7,
CategoryID: 3,
QuantityPerUnit: `32 - 500 g boxes`,
UnitPrice: 17.45,
UnitsInStock: 29,
UnitsOnOrder: 30,
ReorderLevel: 10,
Discontinued: false,
OrderDate: `2018-03-28`,
Rating: 2,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Street Market`,
LastInventory: `12/12/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `24/7 Market`,
LastInventory: `11/11/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 17,
ProductName: `Alice Mutton`,
SupplierID: 7,
CategoryID: 6,
QuantityPerUnit: `20 - 1 kg tins`,
UnitPrice: 39,
UnitsInStock: 0,
UnitsOnOrder: 30,
ReorderLevel: 0,
Discontinued: true,
OrderDate: `2015-08-17`,
Rating: 2,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Farmer Market`,
LastInventory: `04/04/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 18,
ProductName: `Carnarvon Tigers`,
SupplierID: 7,
CategoryID: 8,
QuantityPerUnit: `16 kg pkg.`,
UnitPrice: 62.5,
UnitsInStock: 42,
UnitsOnOrder: 30,
ReorderLevel: 0,
Discontinued: false,
OrderDate: `2005-09-27`,
Rating: 2,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `24/7 Market`,
LastInventory: `11/11/2018`
}),
new NwindDataItem_LocationsItem(
{
Shop: `Super Market`,
LastInventory: `09/09/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 19,
ProductName: `Teatime Chocolate Biscuits`,
SupplierID: 8,
CategoryID: 3,
QuantityPerUnit: ``,
UnitPrice: 9.2,
UnitsInStock: 25,
UnitsOnOrder: 30,
ReorderLevel: 5,
Discontinued: false,
OrderDate: `2001-03-17`,
Rating: 2,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Local Market`,
LastInventory: `07/03/2018`
})]
}));
this.push(new NwindDataItem(
{
ProductID: 20,
ProductName: `Sir Rodneys Marmalade`,
SupplierID: 8,
CategoryID: 3,
QuantityPerUnit: `4 - 100 ml jars`,
UnitPrice: 4.5,
UnitsInStock: 40,
UnitsOnOrder: 30,
ReorderLevel: 0,
Discontinued: false,
OrderDate: `2005-03-17`,
Rating: 5,
Locations: [
new NwindDataItem_LocationsItem(
{
Shop: `Super Market`,
LastInventory: `09/09/2018`
})]
}));
}
}
ts
import React, { useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrGridBaseDirective, IgrGridContextMenuEventArgs, IgrGridModule } from "@infragistics/igniteui-react-grids";
import { IgrGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import { NwindData } from './NwindData';
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
import { IgrIcon } from "@infragistics/igniteui-react";
const mods: any[] = [
IgrGridModule
];
mods.forEach((m) => m.register());
const icon = `<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M180-81q-24 0-42-18t-18-42v-603h60v603h474v60H180Zm120-120q-24 0-42-18t-18-42v-560q0-24 18-42t42-18h440q24 0 42 18t18 42v560q0 24-18 42t-42 18H300Zm0-60h440v-560H300v560Zm0 0v-560 560Z"/></svg>`;
export default function App() {
const [clickedCell, setClickedCell] = useState(null);
const [isCellWithinRange, setIsCellWithinRange] = useState(false);
const [selectedData, setSelectedData] = useState('');
const gridRef = useRef<IgrGrid>(null);
const iconRef = useRef<IgrIcon>(null);
const contextMenuRef = useRef(null);
const northWindData = new NwindData();
useEffect(() => {
if (iconRef.current) {
iconRef.current.registerIconFromText('content_copy', icon, 'material');
}
}, [])
function rightClick(grid: IgrGridBaseDirective, event: IgrGridContextMenuEventArgs) {
const eventArgs = event.detail;
eventArgs.event.preventDefault();
const node = eventArgs.cell.cellID;
const isCellWithinRange = grid.getSelectedRanges().some((range: any) => {
if (node.columnID >= range.columnStart &&
node.columnID <= range.columnEnd &&
node.rowIndex >= range.rowStart &&
node.rowIndex <= range.rowEnd
) {
return true;
}
return false;
});
setIsCellWithinRange(isCellWithinRange);
setClickedCell(eventArgs.cell);
openContextMenu(eventArgs.event.clientX, eventArgs.event.clientY)
}
function openContextMenu(x: number, y: number) {
contextMenuRef.current.style.left = x + 'px';
contextMenuRef.current.style.top = y + 'px';
contextMenuRef.current.style.display = "";
}
function closeContextMenu() {
contextMenuRef.current.style.display = "none";
}
function copySelectedRowData() {
const selectedData = gridRef.current.getRowData(clickedCell.cellID.rowID);
copyData(selectedData);
closeContextMenu();
}
function copySelectedCellData() {
const selectedData = clickedCell.value;
copyData(selectedData);
closeContextMenu();
}
function copySelectedData() {
const selectedData = gridRef.current.getSelectedData(null,null);
copyData(selectedData);
closeContextMenu();
}
function copyData(data: any[]) {
const tempElement = document.createElement('input');
document.body.appendChild(tempElement);
tempElement.setAttribute('id', 'temp_id');
(document.getElementById('temp_id') as HTMLInputElement).value = JSON.stringify(data);
tempElement.select();
document.execCommand('copy');
document.body.removeChild(tempElement);
setSelectedData(JSON.stringify(data));
}
return (
<>
<div className="container sample">
<div className="wrapper" onClick={closeContextMenu}>
<IgrGrid
autoGenerate="false"
data={northWindData}
primaryKey="ProductID"
ref={gridRef}
contextMenu={rightClick}>
<IgrColumn field="ProductID" header="Product ID">
</IgrColumn>
<IgrColumn field="ProductName" header="Product Name">
</IgrColumn>
<IgrColumn field="UnitsInStock" header="Units In Stock" dataType="number">
</IgrColumn>
<IgrColumn field="UnitPrice" header="Units Price" dataType="number">
</IgrColumn>
<IgrColumn field="Discontinued" dataType="boolean">
</IgrColumn>
<IgrColumn field="OrderDate" header="Order Date" dataType="date">
</IgrColumn>
</IgrGrid>
<div className="selected-data-area">
{selectedData}
</div>
</div>
</div>
<div style={{display: "none"}} className="contextmenu" ref={contextMenuRef}>
<span className="item" onClick={copySelectedCellData}>
<IgrIcon ref={iconRef} collection='material' name="content_copy"></IgrIcon>Copy Cell Data
</span>
<span className="item" onClick={copySelectedRowData}>
<IgrIcon collection='material' name="content_copy"></IgrIcon>Copy Row Data
</span>
{isCellWithinRange && (
<span className="item" onClick={copySelectedData}>
<IgrIcon collection='material' name="content_copy"></IgrIcon>Copy Cells Data
</span>)}
</div>
</>
);
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
tsx
.contextmenu {
position: absolute;
width: 180px;
background: white;
display: flex;
cursor: context-menu;
flex-direction: column;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12);
z-index: 9999;
font-size: 0.75rem;
font-weight: 650;
}
.item {
padding: 10px;
display: flex;
}
.item:hover {
background:rgb(204, 203, 203);
}
.icon {
vertical-align: middle;
margin-bottom: 5px;
margin-right: 5px;
}
.selected-data-area{
overflow-y: auto;
width: 50%;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12);
margin-left: 10px;
}
.wrapper{
margin: 10px;
display: flex;
justify-content: space-evenly;
}
css
既知の問題と制限
グリッドに primaryKey
が設定されておらず、リモート データ シナリオが有効になっている場合 (ページング、ソート、フィルタリング、スクロール時に、グリッドに表示されるデータを取得するためのリモート サーバーへのリクエストがトリガーされる場合)、データ要求が完了すると、行は次の状態を失います:
API リファレンス
その他のリソース
コミュニティに参加して新しいアイデアをご提案ください。