Using custom component in ag-grid cell render - reactjs

I am trying to use a custom component in a cell in ag-grid, if i use a standard html component it works but not if i try to use a custom react component
Below code does not works
TABLE_COLUMNS = [
{
headerName: '', field: 'remarks', cellRendererFramework: (params) => {
return <div>
<SpinningWheel height={100}/>
</div>
}
}]
But below code works fine
TABLE_COLUMNS = [
{
headerName: '', field: 'remarks', cellRendererFramework: (params) => {
return <div>
<button>push me</button>
</div>
}
}

Everything seems to be working fine for me. I have created a similar component wrapped inside a div in a plunker from one of their examples and it is working as expected. Look for the following in columnDefs in index.js file.
{
headerName: "Child/Parent",
field: "value",
cellRendererFramework: (params) => <div><SpinningWheel {...params} name="Spinning Wheel"/></div>,
colId: "params",
width: 180
}

Related

Fluent-UI's dropdown and combobox both not working

I have a React app with Fluent-UI 8 set up using npm install #fluentui/react according to the documents from Microsoft.
When I try their combobox or dropdown components, the dropdown list doesn't appear when clicked on it. I use their examples from the docs, which compiles without errors. But none of their examples work out of the box, and no other information is provided.
The problem is that the dropdown list does not appear when clicked on. Not in Edge, not in Firefox. When I check the elements on the page, I do not see the html elements with the list items, although I can cycle through them with the arrow keys. The list appears from the side when the window is tablet format, and setting ResponsiveMode did nothing. Whith a normal screen however, nothing is displaying, and no onchange events are fired.
This is my code for the dropdown:
import { IStackTokens, ResponsiveMode, Stack } from '#fluentui/react';
import { Dropdown, DropdownMenuItemType, IDropdownOption, IDropdownStyles } from '#fluentui/react/lib/Dropdown';
const dropdownStyles: Partial<IDropdownStyles> = { dropdown: { width: 300 } };
const DropdownControlledMultiExampleOptions = [
{ key: 'fruitsHeader', text: 'Spooler status', itemType: DropdownMenuItemType.Header },
{ key: 'apple', text: 'Apple' },
{ key: 'banana', text: 'Banana' },
{ key: 'grape', text: 'Grape' },
{ key: 'broccoli', text: 'Broccoli' },
{ key: 'carrot', text: 'Carrot' },
{ key: 'lettuce', text: 'Lettuce' },
];
export const DropdownList: React.FunctionComponent = () => {
const stackTokens: IStackTokens = { childrenGap: 20 };
return (
<Stack tokens={stackTokens}>
<Dropdown
placeholder="Select an option"
label="Disabled responsive"
options={DropdownControlledMultiExampleOptions}
styles={dropdownStyles}
responsiveMode={ResponsiveMode.unknown}
/>
<Dropdown
placeholder="Select an option"
label="Responsive with panel"
options={DropdownControlledMultiExampleOptions}
styles={dropdownStyles}
/>
</Stack>
);
};
Which I load in my app.tsx
function App() {
return (
<div className="App">
<DropdownList/>
</div>
);
}
Does anyone have an idea how I can get this to work? Or what is causing this?
EDIT and possible solution: It seems that removing the <React.Strict> tags in index.tsx does the job. Don't know why, but then the Fluid-UI controls work fine.

componentDidUpdate is one step behind the actual value in the setState

I'm using React and chartJs to create some basic charts for a dashboard.
I want to implement a onClick functionality which will take the clicked element's data and update it in a AgGrid table.
I managed to do that but it appears that I have one problem: Whenever I click one element, it updates the values from the previous clicked element.
I understand that it has to do with the fact that setState is async and does not update at the moment when I click an element.
Any ideas?
below is my code:
handleChartClick = (element) => {
if (element[0] !== undefined) {
const { datasets } = element[0]._chart.tooltip._data;
const datasetIndex = element[0]._datasetIndex;
const dataIndex = element[0]._index;
const dataLabel = element[datasetIndex]._chart.data.labels[dataIndex];
const value = datasets[datasetIndex].data[dataIndex];
//alert(`${dataLabel}: ${value}`);
this.setState({
tabledata: {
columnDefs: [{ headerName: 'Service name', field: 'service', sortable: true, filter: true, resizable: true },
{ headerName: 'Running times', field: 'times', sortable: true, filter: true, resizable: true }],
rowData: [{ service: dataLabel, times: value }]
}
}, () => {});
}
}
In the Child class:
componentDidUpdate() {
this.state.tabledata = this.props.tabledata;
}
Extra: I am using classes for the definition of chart Components and the App.
/// Later Edit:
Found the problem, when i was instantiating my AgGrid, instead of using this.props.smth, I was using the this.state.smth (the problem was that at the current point, the state has not been modified yet and it was referencing to old values).

Cellrenderer and react-router-dom Link

This question is duplicated.
But the old one is not answered
I need to use React Router inside Cellrenderer method with Ag-grid.
Example
cellRenderer: function (params) {
return '<Link to="/customer/view/'+params.value+'">'+params.value+'</Link>'
}
I tried to use reactNext=true in the ag-grid props but no hope
You should use frameworkComponents instead.
Cell Renderer
const LinkCellRenderer = (params) => (
<Link to={"/edit/" + params.data.id}>Edit</Link>
);
Column Definitions
{
headerName: "Action",
field: "action",
cellRenderer: "LinkCellRenderer"
}
Component
<AgGridReact
{...}
frameworkComponents={{
LinkCellRenderer
}}
/>
Live Demo

Is it possible to display html formatted text in antd table?

My backend service(elasticsearch percolator) annotates text with html tags to highlight matches.
I can't find a way to display such html data in antd Table.
I've tried Highlighter component, but it applies keywords to whole column, but I need to highlight different words in each row.
link to fiddle
const { Table } = antd
class TableColor extends React.Component {
constructor (props) {
super(props)
this.state = {
data: []
}
}
componentDidMount() {
this.setState({
data: [
{id:1, name: 'Lazy < bclass="myBackgroundColor">fox</b>', match: 'fox'},
{id:2, name: '<b class="myBackgroundColor">Dog</b> runs', match: 'Dog'},
{id:3, name: 'I saw <b class="myBackgroundColor">duck</b>', match: 'duck'}
]
})
}
render () {
const columns = [{
title: 'ID',
dataIndex: 'id',
}, {
title: 'Name',
dataIndex: 'name',
}, {
title: 'Match',
dataIndex: 'match',
}]
return (
<div style={{padding: '20px'}}>
<Table
columns={columns}
dataSource={this.state.data}
/>
</div>
)
}
}
ReactDOM.render(<TableColor />, document.querySelector('#app'))
Since it looks like the name column already has highlighted html you could just add a render property to the name column definition that uses dangerouslySetInnerHtml to render the raw html.
...something like:
render: function(html) { return <div dangerouslySetInnerHtml({__html: html}) />
https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
https://ant.design/components/table/#Column
If you wanted to use react-highlight-words you could do the same thing with a render property but use the second argument passed to that function to get the .match property of the record and use that as the highlighted word.

React - Antd - Show/Hide Columns in table

I would like to resolve one problem.
How can I show/hide columns in table using Ant Design in React?
export const columns = () => [
{
key: "anyKeyOne",
title: "Title one",
dataSource: "AnyOne",
hide: true
},
{
key: "anyKeyTwo",
title: "TitleTwo",
dataSource: "AnyTwo",
hide: false
}
]
hideColumns = () => {
//
}
render() {
return (
<div>
<Table
dataSource={store.data}
columns={this.hideColumns}
/>
</div>
)
}
Thank you for answers.
You can set a boolean state property like hideColumn
<div>
<Table
dataSource={store.data}
columns={this.state.hideColumn? this.state.columns: this.state.columns}
/>
</div>
Use this function to build your visible column array. It uses dataIndex to compare the column name needed to be shown.
Form the arrayOfColumnNeeded by pushing values from a checkbox group maybe.
let columnsDisplayed = _.remove(columns, function(n) {
return arrayOfColumnsNeeded.includes(n.dataIndex);
});
You can add a className field in the object and add a css property 'display: none' to that class
{
key: "anyKeyOne",
title: "Title one",
dataSource: "AnyOne",
className: "hide"
}

Resources