-
Notifications
You must be signed in to change notification settings - Fork 6
Updated Excel edit style sample to functional component (React v19) #777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v19-updates
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,146 +1,138 @@ | ||
import React from 'react'; | ||
import React, { useRef, useEffect } from 'react'; | ||
import ReactDOM from 'react-dom/client'; | ||
import './index.css'; | ||
|
||
import { IgrGridModule } from 'igniteui-react-grids'; | ||
import { IgrActiveNodeChangeEventArgs, IgrGridModule } from 'igniteui-react-grids'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IgrActiveNodeChangeEventArgs isn't used - either remove the import or better yet - use the type for the event handler |
||
import { IgrGrid, IgrColumn } from 'igniteui-react-grids'; | ||
import { ComponentRenderer, WebGridDescriptionModule } from 'igniteui-react-core'; | ||
import NwindData from './NwindData.json'; | ||
import { IgrGridKeydownEventArgs } from 'igniteui-react-grids'; | ||
|
||
import 'igniteui-react-grids/grids/combined'; | ||
import 'igniteui-react-grids/grids/themes/light/bootstrap.css'; | ||
|
||
const mods: any[] = [ | ||
IgrGridModule | ||
]; | ||
mods.forEach((m) => m.register()); | ||
// Register modules once | ||
IgrGridModule.register(); | ||
Comment on lines
+12
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
export default class Sample extends React.Component<any, any> { | ||
private grid1: IgrGrid | ||
private grid1Ref(r: IgrGrid) { | ||
this.grid1 = r; | ||
this.setState({}); | ||
} | ||
const nwindData = NwindData; | ||
|
||
constructor(props: any) { | ||
super(props); | ||
const Sample = () => { | ||
const gridRef = useRef<IgrGrid>(null); | ||
const shouldAppendValue = useRef(false); | ||
|
||
this.grid1Ref = this.grid1Ref.bind(this); | ||
this.webGridEditingExcelStyle = this.webGridEditingExcelStyle.bind(this); | ||
} | ||
useEffect(() => { | ||
const gridElement = gridRef.current; | ||
|
||
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); | ||
if (!gridElement) { | ||
return undefined; | ||
} | ||
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; | ||
const handleKeyDown = (event: KeyboardEvent) => { | ||
var code = event.code; | ||
var activeElem = gridRef.current.selectedCells[0]; | ||
|
||
if ((event.code >= 'Digit0' && event.code <= 'Digit9') || | ||
(event.code >= 'KeyA' && event.code <= 'KeyZ') || | ||
(event.code >= 'Numpad0' && event.code <= 'Numpad9') && | ||
event.code !== 'Enter' && event.code !== 'NumpadEnter') { | ||
|
||
if (activeElem && activeElem.editMode === false) { | ||
activeElem.editMode = true; | ||
activeElem.editValue = event.key; | ||
shouldAppendValue.current = true; | ||
gridRef.current.markForCheck(); | ||
} else | ||
|
||
if (activeElem && activeElem.editMode && shouldAppendValue.current) { | ||
event.preventDefault(); | ||
activeElem.editValue = activeElem.editValue + event.key; | ||
shouldAppendValue.current = false; | ||
} | ||
} | ||
|
||
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 (code === 'Backspace') { | ||
if(activeElem == null) { | ||
return; | ||
} | ||
const rowIndex = activeElem.row.index; | ||
const columnKey = activeElem.column.field; | ||
|
||
gridRef.current.data[rowIndex][columnKey] = ''; | ||
gridRef.current.markForCheck(); | ||
|
||
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; | ||
if (code === 'Enter' || code === 'NumpadEnter') { | ||
|
||
if(activeElem == null) { | ||
return; | ||
} | ||
|
||
const thisRow = activeElem.row.index; | ||
const dataView = gridRef.current.dataView; | ||
const nextRowIndex = getNextEditableRowIndex(thisRow, dataView, event.shiftKey); | ||
|
||
gridRef.current.navigateTo(nextRowIndex, activeElem.column.visibleIndex, (obj: any) => { | ||
|
||
requestAnimationFrame(() => { | ||
gridRef.current.endEdit(true, obj); | ||
gridRef.current.clearCellSelection(); | ||
obj.target.activate(); | ||
|
||
}); | ||
}); | ||
|
||
var nextRow = this.getNextEditableRowIndex(thisRow, rowInfo, (args.detail.event as any).shiftKey); | ||
} | ||
}; | ||
|
||
grid.navigateTo(nextRow, column, (obj: any) => { | ||
obj.target.activate(); | ||
grid.clearCellSelection(); | ||
}); | ||
} | ||
} | ||
gridElement.addEventListener("keydown", handleKeyDown); | ||
Comment on lines
+41
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Multiple points:
|
||
|
||
return () => { | ||
gridElement.removeEventListener("keydown", handleKeyDown); | ||
}; | ||
}, []); | ||
|
||
public getNextEditableRowIndex(currentRowIndex: number, dataView: any, previous: boolean) { | ||
|
||
const 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.findLastIndex((rec: any, index: number) => index < currentRowIndex && isEditableDataRecordAtIndex(index, dataView)); | ||
} | ||
return dataView.findIndex((rec: any, index: number) => index > currentRowIndex && this.isEditableDataRecordAtIndex(index, dataView)); | ||
} | ||
return dataView.findIndex((rec: any, index: number) => index > currentRowIndex && isEditableDataRecordAtIndex(index, dataView)); | ||
}; | ||
|
||
public isEditableDataRecordAtIndex(dataViewIndex: number, dataView: any) { | ||
const isEditableDataRecordAtIndex = (dataViewIndex: number, dataView: any) => { | ||
const rec = dataView[dataViewIndex]; | ||
return !rec.expression && !rec.summaries && !rec.childGridsData && !rec.detailsData; | ||
}; | ||
|
||
function gridEndEdit(event: CustomEvent<any>): void { | ||
gridRef.current.endEdit(true, event.detail); | ||
} | ||
|
||
} | ||
return ( | ||
<div className="container sample ig-typography"> | ||
<div className="container fill"> | ||
<IgrGrid | ||
autoGenerate={false} | ||
data={nwindData} | ||
primaryKey="ProductID" | ||
ref={gridRef} | ||
onActiveNodeChange={gridEndEdit} | ||
> | ||
<IgrColumn field="ProductID" header="Product ID" editable={true} groupable={true} hidden={true} /> | ||
<IgrColumn field="ProductName" header="Product Name" dataType="string" editable={true} /> | ||
<IgrColumn field="UnitPrice" header="Unit Price" dataType="number" editable={true} /> | ||
<IgrColumn field="QuantityPerUnit" header="Quantity Per Unit" groupable={true} dataType="string" editable={true} /> | ||
<IgrColumn field="ReorderLevel" header="Reorder Level" dataType="number" groupable={true} editable={true} /> | ||
</IgrGrid> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Sample; | ||
|
||
// rendering above component in the React DOM | ||
// Render the component | ||
const root = ReactDOM.createRoot(document.getElementById('root')); | ||
root.render(<Sample/>); | ||
root.render(<Sample />); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
React
import is unused and should be removed