- Home
- Forum
- React - EJ 2
- Switch component on a react grid stacked column
Switch component on a react grid stacked column
Hi,
I want to customize column display on a SyncFusion react grid.
My requirements are as follows:
- Show a toggle button and a custom display text (refer to attached image) on a single grid column.
- User should be able to toggle the switch on single click. Display text need to change accordingly.
- This needs to happen a on stacked column.
I have achieved all these by capturing QueryCellInfo event. I wrote a handler and custom render the components I wanted. I used ‘ReactDOM.render’ method here. I understand that this render gets executed for every row (twice in my case as I have two columns with this requirements).
Are there any alternatives to this? I want to avoid calling ReactDOM.render multiple times. I have attached sample code and a screenshot of my grid columns.
const renderSwitchComponent = (args: QueryCellInfoEventArgs) => {
const columnName = (args.column as Column).field;
const value = 1;
const displayText = 'Custom Text'
ReactDOM.render(
<div style={{ display: 'flex', width: '100%', gap: '1rem' }}>
<SwitchComponent
className="ABC"
id={columnName}
checked={value}
change={(args: ChangeEventArgs) => {
handleSwitchChange(args.checked, rowData, columnName);
}}
/>
<Label>{displayText}</Label>
</div>,
args.cell as Element
);
}
};
function handleSwitchChange(checked: boolean | undefined, rowData: IMyDataSource, columnName: string): void {
if (checked !== undefined && rowData) {
// update data source
grid?.refreshColumns();
}
}
Hi Ilya,
Greetings from Syncfusion support
Based on your we could see that you like to implement the switch component in the template column and display the custom text. Based on your query we have prepared a sample and we suggest you use the below way to achieve your requirement. Please refer the below code example and sample for more information.
|
const change = (args) => { let grid = document.getElementsByClassName('e-grid')[0].ej2_instances[0]; let rowDetails = grid.getRowInfo(args.event.target); rowDetails.rowData.Status = args.checked; grid.updateRow(rowDetails.rowIndex, rowDetails.rowData); //it helps to update the changes in datasource }
function templateFunction(props) { const value = props.Status ? 'Post' : 'Not Post'; return (<div className='image'> <SwitchComponent checked={props.Status} change={change} /> {value} </div>); }
|
Sample: https://stackblitz.com/edit/react-vbgu3b?file=index.js,data.js
Regards,
Rajapandi R
Thanks for your feedback. I can use this template method if I am working on regular columns, not on stacked columns. We are using SyncFusion react grid with typescript. ‘template’ in ColumnModel expects a template string, or HTML element Id. It does not accept a function that returns HTML. I see it working in sample JS code that you sent, but in typescript template expects HTML string.
I read a lot on internet, folks are suggesting the following way for stacked columns. Please advise. I want to confirm that we are looking for the functionality that you put in sample code, but we need it in typescript.
https://www.syncfusion.com/forums/173249/trying-to-set-edittemplate-to-columns
The stacked header columns are initialized directly as an array of objects and so you need to use the TS approach for defining the edit template to these columns.
/**
* Defines the column template that renders customized element in each cell of the column.
* It accepts either [template string](../../common/template-engine/) or HTML element ID.
*
* @default null
*/
template?: string;
Compilation error when I assign a function to template:
Overload 2 of 2, '(props: GridColumnModel | (GridColumnDirTypecast & { children?: ReactNode; }), context: any): ColumnDirective', gave the following error.
Type '(props: any) => Element' is not assignable to type 'string'.
Ilya,
Before we start providing solution to your query, we need some information for our clarification. So, please share the below details that will be helpful for us to provide better solution.
1) Share your complete Grid rendering code, we would like to check how you are implementing the template with stacked header and expecting the solution.
2) Please confirm you like to expect that our same shared sample in .tsx format.
3) Share your exact requirement step by step with detailed description for better understanding.
1) Share your complete Grid rendering code, we would like to check how you are implementing the template with stacked header and expecting the solution.
Refer to attached GridDemo.tsx file. I have one regular toggle switch column and 2 stacked toggle switch columns. I used template methods for regular toggle column, I would like to use the same template approach for stacked columns, but typescript code does not allow this for stacked columns. I used queryCellInfo to achieve the same for stacked columns, but I am looking for alternatives.
2) Please confirm you like to expect that our same shared sample in .tsx format.
Yes, I would like to have your sample code functionality in tsx (typescript code).
3) Share your exact requirement step by step with detailed description for better understanding.
- I want to have 2 grid STACKED columns with switch component and a custom text like Yes, and No.
- On a single click user should be able to toggle the switch, and corresponding custom text should change appropriately to Yes, or No.
- I have achieved this functionality using QueryCellInfo event, refer to attached sample code.
- I would like to have an alternative approach so I avoid calling ReactDOM.Render multiple times.
- I have tried to use column templates, but these do not work for stacked columns. template for a stacked column expects a string or HTML element Id. It does not take a function like your JS code.
- I am using SyncFusion react grid with typescript.
Attachment: GridDemo_3161fe58.zip
Ilya,
Since you are using the typescript way and facing the problem while defining template as a function, we suggest you use the below way to achieve your requirement. Please refer the below code example for more information.
|
function App() { const editSettings = { allowEditing: true };
const stackedColumns: any = [{ field: 'OrderDate', headerText: 'Order Date', format: 'yMd', width: 130, textAlign: 'Right' }, { field: 'Freight', headerText: 'Freight ($)', width: 120, format: 'C1', textAlign: 'Right' }, { field: 'Status', headerText: 'Template Column', width: 120, template: templateFunction }]
const change = (args: any) => { let grid = (document.getElementsByClassName('e-grid')[0] as any).ej2_instances[0]; let rowDetails = grid.getRowInfo(args.event.target); rowDetails.rowData.Status = args.checked; grid.updateRow(rowDetails.rowIndex, rowDetails.rowData); //it helps to update the changes in datasource console.log(rowDetails); }
function templateFunction(props: any) { const value = props.Status ? 'Post' : 'Not Post'; return (<div className='image'> <SwitchComponent checked={props.Status} change={change} /> {value} </div>); }
return ( <div className="App"> <GridComponent dataSource={orderDetails} allowPaging={true} editSettings={editSettings} allowResizing={true}> <ColumnsDirective> <ColumnDirective field='OrderID' headerText='Order ID' width='120' textAlign='Right'></ColumnDirective> <ColumnDirective headerText='Order Details' columns={stackedColumns}></ColumnDirective>
</ColumnsDirective> <Inject services={[Page, Edit, Resize]}/> </GridComponent> </div> ); } export default App;
|
Please get back us if you need further assistance.
- 5 Replies
- 2 Participants
-
IZ Ilya Zlochisty
- Jun 5, 2023 07:01 PM UTC
- Jun 14, 2023 11:50 AM UTC