Change React MUI DataTable Row Color onRowClick() - reactjs

I am trying to change the background color or text color of a row after it is clicked using MUI DataTables. Does anyone know how I could go about doing this? I tried playing around with onRowClick but I can not figure out a way to update the color of a specific row. Thank you so much!
export default function CoursesTable() {
const columns = [
{
name: "dept",
label: "Dept",
options: {
filter: false,
sort: false,
}
},
{
name: "number",
label: "ID",
options: {
filter: false,
sort: true,
}
},
{
name: "title",
label: "Name",
options: {
filter: false,
sort: false,
}
},
{
name: "prereqs",
label: "Prerequisites",
options: {
filter: false,
sort: false,
display: false,
}
},
{
name: "description",
label: "Description",
options: {
filter: false,
sort: false,
display: false,
}
}
];
const data = courses;
var arr: string[] = [];
const handleRowClick = (rowData, rowMeta) => {
const courseID = rowData[0] + ' ' + rowData[1];
if (arr.includes(courseID)){
const index = arr.indexOf(courseID);
arr.splice(index, 1);
}
else if (arr.length >= 7) {
alert('You can not have more than 7 courses in your cart!')
}
else {
arr.push(courseID);
}
};
return (
<div>
<MUIDataTable
title = {"Course List"}
data = {data}
columns = {columns}
options={{
selectableRowsHideCheckboxes: true,
caseSensitive: false,
download: false,
onRowClick: handleRowClick
}}
/>
<Cart arr = {arr}/>
</div>
)
}
Please let me know if you need any further clarifications of what I am trying to do!

Related

MUIDataTable: In react application viewColumns options how to display the Checkbox List for column vertically

I have a MUI Table Implementation such that the options object viewColumns is set to true, which is supposed to display the popper to choose the columns to be displayed in vertical list of checkbox as shown below:
, but I am getting it horizontally as displayed in screenshot below:
The options to be passed in MUIDataTable components is defined as:
const options = {
filter: true,
filterType: "dropdown",
print: false,
viewColumns: true,
selectableRows: false,
onRowClick: (rowData) => {
console.log("RowClicked->", rowData);
},
responsive: "stacked",
fixedHeaderOptions: {
xAxis: false,
yAxis: true,
},
};
columns defines as:
export const DEAL_GRID_COLUMNS = [
{
name: "someReference",
label: "Some Reference",
options: {
filter: true,
sort: true,
},
},
{
name: "businessTeam",
label: "Business Teams",
options: {
filter: true,
sort: true,
},
},
{
name: "keyContact",
label: "Key Contact Lead",
options: {
filter: true,
sort: true,
},
},
.....
.....
.....
.....
];
and the component is consumed as
<MUIDataTable data={gridData} columns={DEAL_GRID_COLUMNS} options={options} />
here gridData is recieved from Api response
I made sample example using your options and I found viewColumns popper as vertical. I assume there is mui-datatable version issue. FYI, I am using "mui-datatables": "^2.14.0"
Here is the example:
import React, {useEffect, useState} from "react";
import MUIDataTable from "mui-datatables";
import axios from 'axios';
export default function DataTable() {
const [posts, setPost] = useState([]);
let signal = axios.CancelToken.source();
useEffect(() => {
let isSubscribed = true;
axios.get(`https://jsonplaceholder.typicode.com/posts`, {
cancelToken: signal.token,
})
.then(res => {
const posts = res.data;
setPost(posts);
}).catch(err => {
console.log(err);
});
return function cleanup() {
isSubscribed = false;
signal.cancel('Api is being canceled');
}
}, []);
const columns = ["id", "title", "body"];
const options = {
filter: true,
filterType: "dropdown",
print: false,
viewColumns: true,
selectableRows: 'none',
onRowClick: (rowData) => {
console.log("RowClicked->", rowData);
},
responsive: "stacked",
fixedHeaderOptions: {
xAxis: false,
yAxis: true,
},
};
return (
<MUIDataTable
title={"Posts"}
data={posts}
columns={columns}
options={options}
/>
);
}
You can check this output screen
I fixed this by overriding its maxWidth as
MuiPopover: {
paper: {
maxWidth: "16%",
},
}

How can I display the current value from a chart?

I am new to React and I work on a small project basically, I have a chart and I just want to display the current value from the chart.
For example, I have a chart with 4 random values:[5,2,5,1], so I want to have displayed the current value below the chart like first is 5, second is 2 and so on.
Here is my part of code:
class App extends React.Component {
addPoint = (point) => {
currentData = this.state.options.series[0].data
this.setState({
options: {
series: [
{ data: [...currentData, point]}
]
}
});
}
constructor(props) {
super(props);
this.internalChart = undefined;
this.dataStream = new DataStream();
this.dataStream.setUpdateCallback(this.addPoint);
this.state = {
options: {
chart: {
events: {
load: function () {
}
}
},
time: {
useUTC: false
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 2
},
title: {
text: 'Live random data'
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: [[(new Date()).getTime(), 0]]
}]
}
};
}
render() {
return (
<HighchartsReact
constructorType={"stockChart"}
highcharts={Highcharts}
options={this.state.options}
/>
);
}}
Based on your snippet code, try to make random method by using function
Math.floor(Math.random() * Math.floor(max))
And then assign the options to HighchartsReact,
Full code on sandbox: https://codesandbox.io/s/headless-dream-0lzj1

custom pagination and filtering not working in react js

i want to do pagination with api ,when i fileter with with NO and when i want to go to next page within that filter its redirecting to default filter,below is my code
i want to do pagination with api ,when i fileter with with NO and when i want to go to next page within that filter its redirecting to default filter,below is my code
try {
let val = (typeof status[0] == "undefined" ? '' : status[0]);
if(val.toLowerCase() === 'yes'){
val = false;
} else {
val = true;
}
let res = await axios(`${process.env.REACT_APP_API_URL}messages?page=${page}&limit=10&limit=10&status=${val}`, {
headers: {
"x-access-token": cookies.get("token"),
"Content-Type": "application/json",
},
});
console.log(res,'test')
setData({ tableData: res.data.messages, isFetching: false });
setCurrentPage(res.data.currentpage);
} catch (err) {
console.log("############");
}
};
let opt = {
selectableRows: "none",
responsive: "scrollFullHeight",
serverSide: true,
count: count,
onTableChange: (action, tableState) => {
// a developer could react to change on an action basis or
// examine the state as a whole and do whatever they want
switch (action) {
case "changePage":
fetchData1(tableState.page,tableState.rowsPerPage);
break;
case "filterChange":
fetchData1(tableState.page,tableState.rowsPerPage,tableState.filterList[4]);
break;
}
}
}
<React.Fragment>
{data.isFetching ? (
<div className={classes.progressBarCont}>
<CircularProgress color="secondary" />
</div>
) : (
<React.Fragment>
<PageTitle title="List Of Messages" />
<Grid container spacing={3}>
<Grid item xs={12}>
<MUIDataTable
title="Messages List"
data={messageArr}
columns={[
{
name: "room",
label: "Room",
options: {
filter: true,
sort: true,
},
},
{
name: "sender",
label: "Sender",
options: {
filter: false,
},
},
{
name: "message",
label: "Message",
options: {
filter: false,
},
},
{
name: "sender",
label: "Sender",
options: {
filter: false,
},
},
{
name: 'unanswered',
label: 'Status',
options: {
filterType: 'dropdown',
customFilterListRender: value => `Status: ${value}`,
filterOptions: {
names: ["No","Yes"],
logic(unanswered, filters) {
}
},
},
},
]}
options={opt}
/>
</Grid>
</Grid>
</React.Fragment>
)}
<ToastContainer />
</React.Fragment> ```
First of you did not use page in you opt json for paging. you have to use page like:
let opt = {
selectableRows: "none",
responsive: "scrollFullHeight",
serverSide: true,
count: count,
page: page,
onTableChange: (action, tableState) => {
switch (action) {
case "changePage":
case "changeRowsPerPage":
changePage(tableState);
break;
case "search":
search(tableState);
break;
}
},
Then you should write two function changePage and search where you should call your api. but keep it mind that you must store correct tableState using searchText, filtering criteria and page information like pageNo, rowsPerPage and so on.

React Material - MUIDataTable - how to add content in column header

I use in my React app:
import MUIDataTable from "mui-datatables";
I'd like to add some button to my last column header (instead of the column name):
<MUIDataTable
data={data}
columns={columns}
options={options}
>
</MUIDataTable>
where columns:
export const columns = [
{
name: "name",
label: "Nazwa",
options: {
filter: true,
sort: true,
}
},
{
name: "productNumber",
label: "Numer",
options: {
filter: true,
sort: true,
}
}, (...)
How to do that? Is it possible? I can't find anything
You can define a custom body for column. You can add a column like this:
{
name: "Age",
options: {
filter: false,
customBodyRender: (value, tableMeta, updateValue) => (
<FormControlLabel
control={<TextField value={value || ''} type='number' />}
onChange={event => updateValue(event.target.value)}
/>
)
}
}
You need to use customHeadRender
const columns = [
{
name: "id",
label: "Id",
options: {
filter: false,
}
},
{
name: "subject",
label: "Subject",
options: {
filter: true,
sort: false,
}
},
{
name: "button",
options: {
customHeadRender: ({index, ...column}) => {
return (
<Button key={index}>
Click
</Button>
)
}
}
}
];

Is the autocomplete filter doesn't work for columns with numeric values in react-data-grid version 2.0.0?

I am trying to implement a dropdown filter(Singleselect/multiselect/autocpmplete) for a column in my table which contains numeric values for a use case, but in react-data-grid version 2.0.0 and react-data-grid-addons version 2.0.0 I am not able to do this. Is there any work around? and the autocomplete filter only works for columns that have string values.
In the below code the Singleselect filter doesn't work at all and the columns such as ftPad, ptmPad which have numeric value, if I apply autocomplete filter it doesn't work as well, However, it works for string values.
Any workarounds to implement this filter on columns with numeric value?
import React, { Component } from 'react';
import ReactDataGrid from "react-data-grid";
import { Toolbar, Data, Filters} from "react-data-grid-addons";
const Selectors = Data.Selectors;
const AutoCompleteFilter = Filters.AutoCompleteFilter;
const NumericFilter = Filters.NumericFilter;
const SingleSelectFilter = Filters.SingleSelectFilter;
export default class PadMonitoringReport extends Component {
constructor(props) {
super(props);
this._columns = [
{
key: 'nodeId',
name: 'WarehouseId',
sortable: true,
filterable: true,
filterRenderer: SingleSelectFilter
},
{
key: 'nodeType',
name: 'Node Type',
filterable: true,
sortable: true,
resizable: true,
filterRenderer: AutoCompleteFilter
},
{
key: 'backlog',
name: 'Backlog',
sortable: true,
filterable: true,
filterRenderer: NumericFilter
},
{
key: 'ptmPad',
name: 'PTM Pad',
filterable: true,
sortable: true,
filterRenderer: NumericFilter
},
{
key: 'ftPad',
name: 'FT Pad',
filterable: true,
sortable: true,
filterRenderer: NumericFilter
},
{
key: 'maxCPTRisk',
name: 'Max CPT Risk',
sortable: true,
filterable: true,
filterRenderer: NumericFilter
},
{
key: 'pickToManifestTimeInSeconds',
name: 'Pick to manifest (time in sec)',
sortable: true,
filterable:true,
filterRenderer: NumericFilter
}
];
this.state = {
rows: props.data,
filters: {},
sortColumn: null,
sortDirection: null
};
this.rowGetter = this.rowGetter.bind(this);
this.handleGridSort = this.handleGridSort.bind(this);
this.handleFilterChange = this.handleFilterChange.bind(this);
this.onClearFilters = this.onClearFilters.bind(this);
this.getRows = this.getRows.bind(this);
this.getSize = this.getSize.bind(this);
this.getValidFilterValues = this.getValidFilterValues.bind(this);
}
getRows() {
return Selectors.getRows(this.state);
}
getSize() {
return this.getRows().length;
}
rowGetter(i) {
//console.log("it is............")
//console.log(this.state.rows[i])
let rows = this.getRows();
return rows[i];
}
handleGridSort(sortColumn, sortDirection) {
this.setState({ sortColumn: sortColumn, sortDirection: sortDirection });
}
handleFilterChange(filter) {
let newFilters = Object.assign({}, this.state.filters);
if (filter.filterTerm) {
newFilters[filter.column.key] = filter;
} else {
delete newFilters[filter.column.key];
}
this.setState({ filters: newFilters });
}
onClearFilters() {
// all filters removed
this.setState({filters: {} });
}
getValidFilterValues(columnId) {
let values = this.state.rows.map(r => r[columnId]);
return values.filter((item, i, a) => { return i === a.indexOf(item); });
}
render() {
return (
<div>
<ReactDataGrid
onGridSort={this.handleGridSort}
enableCellSelect={true}
columns={this._columns}
rowGetter={this.rowGetter}
rowsCount={this.getSize()}
toolbar={<Toolbar enableFilter={true}/>}
onAddFilter={this.handleFilterChange}
getValidFilterValues={this.getValidFilterValues}
onClearFilters={this.onClearFilters}
/>
</div>
);
}
}
I don't know is it relevant now or not, I faced this issue and solved it.
You need to convert your number array to string array for getValidFilterValues props
For instance:
getValidFilterValues={this.getValidFilterValues}
getValidFilterValues = (columnId) => {
let values = this.state.rows.map(r => r[columnId]);
var r = values.filter((item, i, a) => {
return i === a.indexOf(item);
});
return r.map(v => v.toString());
};

Resources