1- import React , { useEffect , useRef , useState } from ' react' ;
2- import ReactDOM from ' react-dom/client' ;
3- import ' ./index.css' ;
1+ import React , { useEffect , useRef , useState } from " react" ;
2+ import ReactDOM from " react-dom/client" ;
3+ import " ./index.css" ;
44
5- import { IgrGridBaseDirective , IgrGridContextMenuEventArgs , IgrGridModule } from 'igniteui-react-grids' ;
6- import { IgrGrid , IgrColumn } from 'igniteui-react-grids' ;
7- import { NwindData } from './NwindData' ;
5+ import {
6+ IgrGridContextMenuEventArgs
7+ } from "igniteui-react-grids" ;
8+ import { IgrGrid , IgrColumn } from "igniteui-react-grids" ;
9+ import { NwindData } from "./NwindData" ;
810
9- import 'igniteui-react-grids/grids/combined' ;
10- import 'igniteui-react-grids/grids/themes/light/bootstrap.css' ;
11- import { IgrIcon } from 'igniteui-react' ;
11+ import "igniteui-react-grids/grids/combined" ;
12+ import "igniteui-react-grids/grids/themes/light/bootstrap.css" ;
13+ import { IgrIcon } from "igniteui-react" ;
14+ import { registerIconFromText } from "igniteui-webcomponents" ;
1215
13- const mods : any [ ] = [
14- IgrGridModule
15- ] ;
16- mods . forEach ( ( m ) => m . register ( ) ) ;
1716const 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>` ;
1817
1918export default function App ( ) {
20- const [ clickedCell , setClickedCell ] = useState ( null ) ;
21- const [ isCellWithinRange , setIsCellWithinRange ] = useState ( false ) ;
22- const [ selectedData , setSelectedData ] = useState ( '' ) ;
23- const gridRef = useRef < IgrGrid > ( null ) ;
24- const iconRef = useRef < IgrIcon > ( null ) ;
25- const contextMenuRef = useRef ( null ) ;
26- const northWindData = new NwindData ( ) ;
19+ const [ clickedCell , setClickedCell ] = useState ( null ) ;
20+ const [ isCellWithinRange , setIsCellWithinRange ] = useState ( false ) ;
21+ const [ selectedData , setSelectedData ] = useState ( "" ) ;
22+ const gridRef = useRef < IgrGrid > ( null ) ;
23+ const iconRef = useRef < IgrIcon > ( null ) ;
24+ const contextMenuRef = useRef ( null ) ;
25+ const northWindData = new NwindData ( ) ;
2726
28- useEffect ( ( ) => {
29- if ( iconRef . current ) {
30- iconRef . current . registerIconFromText ( 'content_copy' , icon , 'material' ) ;
27+ useEffect ( ( ) => {
28+ registerIconFromText ( "content_copy" , icon , "material" ) ;
29+ } , [ ] ) ;
30+
31+ const rightClick = ( event : IgrGridContextMenuEventArgs ) => {
32+ const eventArgs = event . detail ;
33+ eventArgs . event . preventDefault ( ) ;
34+ const node = eventArgs . cell . cellID ;
35+ const isCellWithinRange = gridRef . current
36+ . getSelectedRanges ( )
37+ . some ( ( range : any ) => {
38+ if (
39+ node . columnID >= range . columnStart &&
40+ node . columnID <= range . columnEnd &&
41+ node . rowIndex >= range . rowStart &&
42+ node . rowIndex <= range . rowEnd
43+ ) {
44+ return true ;
3145 }
32- } , [ ] )
46+ return false ;
47+ } ) ;
48+ setIsCellWithinRange ( isCellWithinRange ) ;
49+ setClickedCell ( eventArgs . cell ) ;
50+ openContextMenu ( eventArgs . event . clientX , eventArgs . event . clientY ) ;
51+ } ;
52+
53+ const openContextMenu = ( x : number , y : number ) => {
54+ contextMenuRef . current . style . left = x + "px" ;
55+ contextMenuRef . current . style . top = y + "px" ;
56+ contextMenuRef . current . style . display = "" ;
57+ } ;
3358
34- function rightClick ( grid : IgrGridBaseDirective , event : IgrGridContextMenuEventArgs ) {
35- const eventArgs = event . detail ;
36- eventArgs . event . preventDefault ( ) ;
37- const node = eventArgs . cell . cellID ;
38- const isCellWithinRange = grid . getSelectedRanges ( ) . some ( ( range : any ) => {
39- if ( node . columnID >= range . columnStart &&
40- node . columnID <= range . columnEnd &&
41- node . rowIndex >= range . rowStart &&
42- node . rowIndex <= range . rowEnd
43- ) {
44- return true ;
45- }
46- return false ;
47- } ) ;
48- setIsCellWithinRange ( isCellWithinRange ) ;
49- setClickedCell ( eventArgs . cell ) ;
50- openContextMenu ( eventArgs . event . clientX , eventArgs . event . clientY )
51- }
59+ const closeContextMenu = ( ) => {
60+ contextMenuRef . current . style . display = "none" ;
61+ } ;
5262
53- function openContextMenu ( x : number , y : number ) {
54- contextMenuRef . current . style . left = x + 'px' ;
55- contextMenuRef . current . style . top = y + 'px' ;
56- contextMenuRef . current . style . display = "" ;
57- }
63+ const copySelectedRowData = ( ) => {
64+ const selectedData = gridRef . current . getRowData ( clickedCell . cellID . rowID ) ;
65+ copyData ( selectedData ) ;
66+ closeContextMenu ( ) ;
67+ } ;
5868
59- function closeContextMenu ( ) {
60- contextMenuRef . current . style . display = "none" ;
61- }
69+ const copySelectedCellData = ( ) => {
70+ const selectedData = clickedCell . value ;
71+ copyData ( selectedData ) ;
72+ closeContextMenu ( ) ;
73+ } ;
6274
63- function copySelectedRowData ( ) {
64- const selectedData = gridRef . current . getRowData ( clickedCell . cellID . rowID ) ;
65- copyData ( selectedData ) ;
66- closeContextMenu ( ) ;
67- }
68-
69- function copySelectedCellData ( ) {
70- const selectedData = clickedCell . value ;
71- copyData ( selectedData ) ;
72- closeContextMenu ( ) ;
73- }
74-
75- function copySelectedData ( ) {
76- const selectedData = gridRef . current . getSelectedData ( null , null ) ;
77- copyData ( selectedData ) ;
78- closeContextMenu ( ) ;
79- }
80-
81- function copyData ( data : any [ ] ) {
82- const tempElement = document . createElement ( 'input' ) ;
83- document . body . appendChild ( tempElement ) ;
84- tempElement . setAttribute ( 'id' , 'temp_id' ) ;
85- ( document . getElementById ( 'temp_id' ) as HTMLInputElement ) . value = JSON . stringify ( data ) ;
86- tempElement . select ( ) ;
87- document . execCommand ( 'copy' ) ;
88- document . body . removeChild ( tempElement ) ;
89- setSelectedData ( JSON . stringify ( data ) ) ;
90- }
75+ const copySelectedData = ( ) => {
76+ const selectedData = gridRef . current . getSelectedData ( null , null ) ;
77+ copyData ( selectedData ) ;
78+ closeContextMenu ( ) ;
79+ } ;
9180
92- return (
93- < >
94- < div className = "container sample" >
95- < div className = "wrapper" onClick = { closeContextMenu } >
96- < IgrGrid
97- autoGenerate = { false }
98- data = { northWindData }
99- primaryKey = "ProductID"
100- ref = { gridRef }
101- contextMenu = { rightClick } >
102- < IgrColumn field = "ProductID" header = "Product ID" >
103- </ IgrColumn >
104- < IgrColumn field = "ProductName" header = "Product Name" >
105- </ IgrColumn >
106- < IgrColumn field = "UnitsInStock" header = "Units In Stock" dataType = "number" >
107- </ IgrColumn >
108- < IgrColumn field = "UnitPrice" header = "Units Price" dataType = "number" >
109- </ IgrColumn >
110- < IgrColumn field = "Discontinued" dataType = "boolean" >
111- </ IgrColumn >
112- < IgrColumn field = "OrderDate" header = "Order Date" dataType = "date" >
113- </ IgrColumn >
114- </ IgrGrid >
115- < div className = "selected-data-area" >
116- { selectedData }
117- </ div >
118- </ div >
119- </ div >
120- < div style = { { display : "none" } } className = "contextmenu" ref = { contextMenuRef } >
121- < span className = "item" onClick = { copySelectedCellData } >
122- < IgrIcon ref = { iconRef } collection = 'material' name = "content_copy" > </ IgrIcon > Copy Cell Data
123- </ span >
124- < span className = "item" onClick = { copySelectedRowData } >
125- < IgrIcon collection = 'material' name = "content_copy" > </ IgrIcon > Copy Row Data
126- </ span >
127- { isCellWithinRange && (
128- < span className = "item" onClick = { copySelectedData } >
129- < IgrIcon collection = 'material' name = "content_copy" > </ IgrIcon > Copy Cells Data
130- </ span > ) }
131- </ div >
132- </ >
81+ const copyData = ( data : any [ ] ) => {
82+ const tempElement = document . createElement ( "input" ) ;
83+ document . body . appendChild ( tempElement ) ;
84+ tempElement . setAttribute ( "id" , "temp_id" ) ;
85+ ( document . getElementById ( "temp_id" ) as HTMLInputElement ) . value =
86+ JSON . stringify ( data ) ;
87+ tempElement . select ( ) ;
88+ const dataStringified = JSON . stringify ( data ) ;
89+ navigator . clipboard . writeText ( dataStringified ) . catch ( ( err ) => {
90+ console . error ( "Failed to copy: " , err ) ;
91+ } ) ;
92+ document . body . removeChild ( tempElement ) ;
93+ setSelectedData ( dataStringified ) ;
94+ } ;
13395
134- ) ;
96+ return (
97+ < >
98+ < div className = "container sample" >
99+ < div className = "wrapper" onClick = { closeContextMenu } >
100+ < IgrGrid
101+ autoGenerate = { false }
102+ data = { northWindData }
103+ primaryKey = "ProductID"
104+ ref = { gridRef }
105+ onContextMenu = { rightClick }
106+ >
107+ < IgrColumn field = "ProductID" header = "Product ID" > </ IgrColumn >
108+ < IgrColumn field = "ProductName" header = "Product Name" > </ IgrColumn >
109+ < IgrColumn
110+ field = "UnitsInStock"
111+ header = "Units In Stock"
112+ dataType = "number"
113+ > </ IgrColumn >
114+ < IgrColumn
115+ field = "UnitPrice"
116+ header = "Units Price"
117+ dataType = "number"
118+ > </ IgrColumn >
119+ < IgrColumn field = "Discontinued" dataType = "boolean" > </ IgrColumn >
120+ < IgrColumn
121+ field = "OrderDate"
122+ header = "Order Date"
123+ dataType = "date"
124+ > </ IgrColumn >
125+ </ IgrGrid >
126+ < div className = "selected-data-area" > { selectedData } </ div >
127+ </ div >
128+ </ div >
129+ < div
130+ style = { { display : "none" } }
131+ className = "contextmenu"
132+ ref = { contextMenuRef }
133+ >
134+ < span className = "item" onClick = { copySelectedCellData } >
135+ < IgrIcon
136+ ref = { iconRef }
137+ collection = "material"
138+ name = "content_copy"
139+ > </ IgrIcon >
140+ Copy Cell Data
141+ </ span >
142+ < span className = "item" onClick = { copySelectedRowData } >
143+ < IgrIcon collection = "material" name = "content_copy" > </ IgrIcon > Copy Row
144+ Data
145+ </ span >
146+ { isCellWithinRange && (
147+ < span className = "item" onClick = { copySelectedData } >
148+ < IgrIcon collection = "material" name = "content_copy" > </ IgrIcon > Copy
149+ Cells Data
150+ </ span >
151+ ) }
152+ </ div >
153+ </ >
154+ ) ;
135155}
136156
137157// rendering above component in the React DOM
138- const root = ReactDOM . createRoot ( document . getElementById ( ' root' ) ) ;
139- root . render ( < App /> ) ;
158+ const root = ReactDOM . createRoot ( document . getElementById ( " root" ) ) ;
159+ root . render ( < App /> ) ;
0 commit comments