Render a component oclick of a row in react-table (https://github.com/react-tools/react-table) - reactjs

I want to render a component when a row is clicked in a react-table. I know i can use a subcomponent to achieve this but that doesn't allow click on the entire row. I want the subcomponent to render when the user clicks anywhere on that row. From their github page i understand that i want to edit getTdProps but am not really able to achieve it. Also the subcomponent is form and on the save of that form i want to update that row to reflect the changes made by the user and close the form. Any help is appreciated.
import React, {Component} from 'react';
import AdomainRow from './AdomainRow'
import ReactTable from "react-table"
import AdomainForm from './AdomainForm'
import 'react-table/react-table.css'
export default class AdomianTable extends Component {
render() {
const data = [{
adomain: "Reebok1.com",
name: "Reebok",
iabCategories: ["IAB1", "IAB2", "IAB5"],
status: "PENDING",
rejectionType: "Offensive Content",
rejectionComment: "The content is offensive",
isGeneric: false,
modifiedBy: "Sourav.Prem"
},
{
adomain: "Reebok2.com",
name: "Reebok",
iabCategories: ["IAB1", "IAB2", "IAB5"],
status: "PENDING",
rejectionType: "Offensive Content",
rejectionComment: "The content is offensive",
isGeneric: false,
modifiedBy: "Sourav.Prem"
},
{
adomain: "Reebok3.com",
name: "Reebok",
iabCategories: ["IAB1", "IAB2", "IAB5"],
status: "PENDING",
rejectionType: "Offensive Content",
rejectionComment: "The content is offensive",
isGeneric: false,
modifiedBy: "Sourav.Prem"
}];
//FOR REACT TABLE TO WORK
const columns = [{
Header : 'Adomian',
accessor : 'adomain'
}, {
Header : 'Name',
accessor : 'name'
}, {
Header : 'IABCategories',
accessor : 'iabCategories',
Cell : row => <div>{row.value.join(", ")}</div>
}, {
Header : 'Status',
accessor : 'status'
}];
return (
<div>
<ReactTable
getTdProps={(state, rowInfo, column, instance) => {
return {
onClick: (e, handleOriginal) => {
<AdomainForm row={rowInfo} ></AdomainForm>
console.log('A Td Element was clicked!')
console.log('it produced this event:', e)
console.log('It was in this column:', column)
console.log('It was in this row:', rowInfo)
console.log('It was in this table instance:', instance)
// IMPORTANT! React-Table uses onClick internally to trigger
// events like expanding SubComponents and pivots.
// By default a custom 'onClick' handler will override this functionality.
// If you want to fire the original onClick handler, call the
// 'handleOriginal' function.
if (handleOriginal) {
handleOriginal()
}
}
}
}}
data={data.adomains}
columns={columns}
defaultPageSize={10}
className="footable table table-stripped toggle-arrow-tiny tablet breakpoint footable-loaded"
SubComponent = { row =>{
return (
<AdomainForm row={row} ></AdomainForm>
);
}}
/>
</div>
);
}
}
}

I ran into the same issue where I wanted the entire row to be a clickable expander as React Table calls it. What I did was simply change the dimensions of the expander to match the entire row and set a z-index ahead of the row. A caveat of this approach is that any clickable elements you have on the row itself will now be covered by a full width button. My case had display only elements in the row so this approach worked.
.rt-expandable {
position: absolute;
width: 100%;
max-width: none;
height: 63px;
z-index: 1;
}
To remove the expander icon you can simply do this:
.rt-expander:after {
display: none;
}

I found it was better to add a classname to the react table:
<AdvancedExpandReactTable
columns={[
{
Header: InventoryHeadings.PRODUCT_NAME,
accessor: 'productName',
},
]}
className="-striped -highlight available-inventory" // custom classname added here
SubComponent={({ row, nestingPath, toggleRowSubComponent }) => (
<div className={classes.tableInner}>
{/* sub component goes here... */}
</div>
)}
/>
Then modify the styles so that the columns line up
.available-inventory .-header,
.available-inventory .-filters {
margin-left: -40px;
}
And then modify these styles as Sven suggested:
.rt-tbody .rt-expandable {
cursor: pointer;
position: absolute;
width: 100% !important;
max-width: none !important;
}
.rt-expander:after{
display: none;
}

Related

AntD table - change cell color on mouse hover

I'm trying to change background color of the cell in antD table using onCell property and onMouseOver function, but without success.
onCell: (record, rowIndex) => {
return {
onMouseOver: () => {
console.log("record, row", record, rowIndex);
return {
props: {
style: { background: "yellow", fontWeight: "bold" }
}
};
}
};
}
Working sandbox example:
demo
Any help would be highly appreciated.
If the goal is to add a custom background on hover to the cells of a certain column, perhaps a simple solution would be adding this as a custom class with onCell.
Forked demo with modification: codesandbox
onCell: (record, rowIndex) => {
return {
className: "custom",
};
};
In CSS, define :hover styles with a higher specificity so that it overrides default style for selected cells:
.ant-table-cell.ant-table-cell-row-hover.custom:hover {
background-color: hotpink;
color: white;
}

Mui Datagrid not populating, data is there

I have a few Mui datagrids through my app. I recently switched over to using RTK Query for the api and was able to get all the grids functioning and displaying fine. I honestly do not know what changed (since it took place after I was done mucking with the grid components and was adjusting the auth/login to RTK) but 3 of the 4 are displaying an empty grid with no errors. I can console the data, and even the corner of the grids shows the total number of entries, which reflects the changes if I add an item to the array that should be displayed by the grid. I already had the container components set to display: flex and set autoHeight and autoWidth on the grids. I've tried adjusting the containers, even putting height to 5000, with no change. As I mentioned, I have 1 that still displays correctly, and even copying the display props for that grid to the others had no effect.
import React from 'react';
import PropTypes from 'prop-types';
import { DataGrid, GridActionsCellItem } from '#mui/x-data-grid';
import { Link } from 'react-router-dom';
import { useGetVisitsByUserIdQuery } from '../../redux/apiSlice';
import { CircularProgress, Box } from '#mui/material';
const UserVisits = ({ user }) => {
const userId = user._id
const {
data,
isLoading,
isSuccess
} = useGetVisitsByUserIdQuery(userId);
console.log(data)
const columns =
[
{
field: 'client',
headerName: 'Client',
width: 150,
renderCell: (params) => {
return (
<Link to={`/ClientChart/${params?.value?._id}`}>{params?.value?.fullName}</Link>
)}
},
{
field: 'visitStart',
headerName: 'Start Time',
type: 'date',
width: 200,
valueFormatter: (params) => {
const date = new Date(params.value);
let options = {
year: "numeric",
month: "numeric",
day: "numeric"
};
return date.toLocaleTimeString("en-US", options);
}
},
{
field: 'visitEnd',
headerName: 'End Time',
type: 'date',
width: 200,
valueFormatter: (params) => {
const date = new Date(params.value);
let options = {
year: "numeric",
month: "numeric",
day: "numeric"
};
return date.toLocaleTimeString("en-US", options);
}
},
{field: 'location', headerName: 'Location', width: 150},
];
let content
if (isLoading) {
content = <CircularProgress />
} else if (isSuccess) {
content =
<div style={{ display: 'flex', height: '100%'}}>
<Box sx={{ flexGrow: 1 }}>
{ data &&
<DataGrid
autoHeight
autoWidth
getRowId={(row) => row.id}
rows={data}
columns={columns}
rowsPerPageOptions={[20, 50, 100]}
autoPageSize
//sx={{ height: '100%', width: '100%' }}
/>}
</Box>
</div>
}
return (
<div>
<h1>Visits</h1>
<div>
{content}
</div>
</div>
)
}
If I push new data to the grid, the number of entries in the bottom right corner adjusts, and the console shows the correct array of data, as well as Redux DevTools showing the data in state. Even manually adjusting the height of the div/Box containing the grid, the grid itself never changes in height.
Again they had been working perfectly, and I'm at a total loss as to what would have affected them. Any help is greatly appreciated.
Thanks
So the issue was resolved by removing 'autoPageSize' from the Datagrid props. Playing with it, it seems that autoHeight and autoPageSize cause the grid to break when in place together.
Could not find any specific references online to this being an issue, but I was able to recreate the issue on this codesandbox I found: https://codesandbox.io/s/datagrid-v5-0-1-autoheight-autopagesize-9dy64?file=/src/App.tsx
If you add in autoPageSize to the datagrid props, the grid goes empty.

Rendering an action menu in Ant Table on Row hover

I'm using Ant table to display some data. So far so good except the requirement that I need to display an action menu when a particular row hovered over. Here's the mock of what I'm trying to achieve:
Ant table's onRow callback will allow me to get the record that's being hovered over and onRowClassName allows me to pass a class name so I can dynamically apply css on the row hovered over. But I'm stuck on rendering an element at the end of the row like you see in the screenshot.
I'm a bit stumbled on how to go about doing this. Closest thing I came across is this context menu implementation: https://codesandbox.io/s/rm23kroqyo
Appreciate any input.
One way to do this is to add a column for the actions and add a className for it.
export const columns = [
{ title: `Name`, dataIndex: `name` },
{ title: `Age`, dataIndex: `age` },
{ title: `Address`, dataIndex: `address` },
{
title: "",
dataIndex: "actions",
render: (actions) =>
actions &&
actions.map((action) => (
<a className="action" href>
{action}
</a>
)),
className: "actions"
}
];
add the actions on the data
const dataWithActions = data.map((item) =>
item.key === "2" ? { ...item, actions: ["Like", "Share"] } : item
);
Then set it's position absolute so it does not take up space
.actions {
position: absolute;
}
.ant-table-row {
position: relative;
}
And finally position it when the row is hovered
.ant-table-row:hover .actions {
display: block;
height: 54px;
right: 0;
}
Here's the updated codesandbox:
https://codesandbox.io/s/custom-context-menu-table-antd-forked-b6y5c

Set dynamic style for Checkbox in Ant Design

Is it possible to set tick container's style backgroundColor and borderColor in Checkbox dynamically from JSX?
I can do it with CSS/LESS, but I need to set specific color based on data from API.
Example:
.
If the colors from API are completely unknown to you until the time of running, then there is no way to accomplish the task with Antd library. Because the class you need to update colors for (.ant-checkbox-checked .ant-checkbox-inner) is nested inside the parent component , and can be changed only in your .less file.
As you can see in Rafael's example, you can only control the colors of the parent (.ant-checkbox-wrapper) from .js file.
On the other hand, if you know there will always be, let's say "#1890FF", "#FA8072", and "#008100" colors, you just don't know in what order, you can easily change the colors dynamically, by creating your logic around CSS classes. Which means you can map through all your checkboxes and give the classNames based on the color you get from API (getColor function). In order to do so, in your .js file import the data from API and define getColor function:
import React, { PureComponent } from "react";
import { Checkbox } from "antd";
export default class ColoredCheckboxes extends PureComponent {
getColor = color => {
let checkboxClassName = "checkbox-green";
if (color === "#FA8072") {
checkboxClassName = "checkbox-orange"
}
if (color === "#1890FF") {
checkboxClassName = "checkbox-blue"
}
return checkboxClassName;
};
render() {
const dataFromAPI = [
{
key: "first",
name: "First",
color: "#008100",
},
{
key: "second",
name: "Second",
color: "#FA8072",
},
{
key: "third",
name: "Third",
color: "#1890FF",
},
]
return (
<div>
{dataFromAPI.map(item => (
<div key={item.key}>
<Checkbox className={this.getColor(item.color)}>
{item.name}
</Checkbox>
</div>
))}
</div>
);
}
}
Then in your .less file reassign the colors for ".ant-checkbox-checked .ant-checkbox-inner" class originally coming from Antd Library:
.checkbox-green {
.ant-checkbox-checked .ant-checkbox-inner {
background-color: #008100;
border-color: #008100;
}
}
.checkbox-orange {
.ant-checkbox-checked .ant-checkbox-inner {
background-color: #FA8072;
border-color: #FA8072;
}
}
.checkbox-blue {
.ant-checkbox-checked .ant-checkbox-inner {
background-color: #1890FF;
border-color: #1890FF;
}
}
You just styled it, something like
<Checkbox
style={{
backgroundColor: data.backgroundColor,
borderColor : data.borderColor
}}
/>

React DataTable fails to change the font-size

I work on a React app and there is a component using DataTable (reference is here).
The default font-size looks too small so I want to change to make it look bigger.
I try to set the style to the table as the code below but it doesn't work.
Here is my code:
import React from 'react';
import ReactDOM from 'react-dom';
import DataTable from 'react-data-table-component';
export default class MyTable2 extends React.Component {
constructor(props) {
super(props);
const data = [];
for (var i = 0; i < 200; i++) {
data.push({ id: i, title: 'Conan the Barbarian' + i, summary: 'Orphaned boy Conan is enslaved after his village is destroyed...', year: '1982', expanderDisabled: true, image: 'http://conan.image.png' })
}
this.state = {
rs: data
}
}
render() {
const columns = [
{
name: 'Title',
selector: 'title',
sortable: true,
},
{
name: 'Year',
selector: 'year',
sortable: true
},
];
const handleChange = (state) => {
console.log('Selected Rows: ', state.selectedRows);
};
let styleobj = { "font-size": "25px" } //try to set the font-size here
return (
<DataTable
className="dataTables_wrapper"
title="Arnold Movies"
columns={columns}
data={this.state.rs}
selectableRows // add for checkbox selection
onTableUpdate={handleChange}
pagination
style={styleobj}
/>
)
}
}
Is there anyone here can suggest me a solution?
Thank you in advanced.
Can you try this
// Override the row font size
const myNewTheme= {
rows: {
fontSize: '25px'
}
}
<DataTable
className="dataTables_wrapper"
title="Arnold Movies"
columns={columns}
data={this.state.rs}
selectableRows // add for checkbox selection
onTableUpdate={handleChange}
pagination
customTheme={myNewTheme}
/>
Theme reference
Source file
If you want to change an individual cell font size, you can do this
const columns = [
{
name: 'Title',
selector: 'title',
sortable: true,
cell: row => <div style={{fontSize: 25}}>{row.title}</div>
}]
Hi #humanbean answer is correct, you can fix the inline stile or, if you want, you also can set the style directly in your app.css
Based on your custom classname (.dataTables_wrapper) I think that this css should work.
.dataTables_wrapper .rdt_TableCell{
font-size:25px;
}
this is the className used by react-data-table-component
rdt_Table
rdt_TableRow
rdt_TableCol
rdt_TableCol_Sortable
rdt_TableCell
rdt_TableHeader
rdt_TableFooter
rdt_TableHead
rdt_TableHeadRow
rdt_TableBody
rdt_ExpanderRow

Resources