How to rewrite styles of #devexpress/dx-react-grid-material-ui? - reactjs

Is there any way to rewrite styles of TableSummaryRow from '#devexpress/dx-react-grid-material-ui' library?
What I have: a component which renders table (using '#devexpress/dx-react-grid-material-ui' library) and in the last row outputs the total number of rows in the table.
What I need to do: style table cell in which TableSummaryRow renders result.
I already tried this solution, but it don't work for me.
Here is simpifide code of my component:
import React from 'react';
import { SummaryState } from '#devexpress/dx-react-grid';
import {
TableHeaderRow,
TableSummaryRow
} from '#devexpress/dx-react-grid-material-ui';
import { ExtendedGrid } from 'components/DxGrid/index';
const Table = ({ rows }) => (
<ExtendedGrid rows={rows} columns={reportColumns}>
<SummaryState totalItems={[{ columnName: 'userName', type: 'count' }]} />
<TableHeaderRow />
<TableSummaryRow messages={{ count: 'Number of rows' }} />
</ExtendedGrid>
);
export default Table;

I figured out this by myself, maybe it will be useful for somebody.
This official docs page helped me. So I used makeStyles method.
Here is working DEMO.
And the final component (based on Andrei Konstantinov's answer) code:
import React from "react";
import { render } from "react-dom";
import Paper from "#material-ui/core/Paper";
import { makeStyles } from "#material-ui/styles";
import { SummaryState, IntegratedSummary } from "#devexpress/dx-react-grid";
import {
Grid,
Table,
TableHeaderRow,
TableSummaryRow
} from "#devexpress/dx-react-grid-material-ui";
const useStyles = makeStyles({
root: {
"& tfoot": {
"& td": {
background: "linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)",
"&:empty": {
background: "none"
}
}
}
}
});
const Hook = () => {
const data = {
totalSummaryItems: [{ columnName: "weight", type: "sum" }],
columns: [
{ name: "name", title: "Name" },
{ name: "weight", title: "Weight" }
],
rows: [
{ name: "Sandra", weight: 123 },
{ name: "Andy", weight: 9000 },
{ name: "Einstein", weight: 56 },
{ name: "Bob", weight: 11 }
]
};
const { rows, columns } = data;
const classes = useStyles();
return (
<Paper className={classes.root}>
<Grid rows={rows} columns={columns}>
<SummaryState totalItems={data.totalSummaryItems} />
<IntegratedSummary />
<Table />
<TableHeaderRow />
<TableSummaryRow messages={{ sum: "Total weight of the group" }} />
</Grid>
</Paper>
);
};
render(<Hook />, document.getElementById("root"));

According to TableSumRow's docs you need to use SummaryState component.
Also, for some reason, I can't make it work without IntegratedSummary component as well, even if it's marked as optional.
You can find working demo here.
And here is a code from demo. There is a total weight row for the whole team.
import React from "react";
import { render } from "react-dom";
import { SummaryState, IntegratedSummary } from "#devexpress/dx-react-grid";
import {
Grid,
Table,
TableHeaderRow,
TableSummaryRow
} from "#devexpress/dx-react-grid-material-ui";
class App extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
totalSummaryItems: [{ columnName: "weight", type: "sum" }],
columns: [
{ name: "name", title: "Name" },
{ name: "weight", title: "Weight" }
],
rows: [
{ name: "Sandra", weight: 123 },
{ name: "Andy", weight: 9000 },
{ name: "Einstein", weight: 56 },
{ name: "Bob", weight: 11 }
]
};
}
render() {
const { rows, columns } = this.state;
return (
<Grid rows={rows} columns={columns}>
<SummaryState totalItems={this.state.totalSummaryItems} />
<IntegratedSummary />
<Table />
<TableHeaderRow />
<TableSummaryRow messages={{ sum: "Total weight of the group" }} />
</Grid>
</Paper>
);
}
}
render(<App />, document.getElementById("root"));

Related

Array of object is getting undefined

This is my Cart.jsx
import { createContext, useEffect } from "react"
import Cake from "../About Section/Cake";
const PdtList = createContext();
export default function Cart() {
let list = [
{
id: "52",
name: "Doll cake"
// images: image80
},
{
id: "53",
name: "Mixed Platte cake"
// images: image81
},
{
id: "54",
name: "Pinata cake"
// images: image82
},
{
id: "55",
name: "Bomb cake"
// images: image83
}
];
return (
<>
<main className="align" >
<h1>Thanks for shopping with us</h1>
<PdtList.Provider value={list}>
<Cake />
</PdtList.Provider>
</main>
</>
)
}
export { PdtList };
This is the Cake.jsx
import { PdtList } from "../Cart/Cart";
import { useContext, useState, useEffect } from "react";
export default function Cake(props) {
const { name, images, bold, cut } = props;
const list = useContext(PdtList);
console.log(list);
console.log(typeof(list));
const Add_Products = (index) => {
console.log('Add_Products called');
let tobeAdded = { name, images, bold };
};
return (
<>
<main className="align unique">
<img src={images} alt="" />
<h1>{name}</h1>
<div className="align2">
<small>Rs {bold}</small>
<small style={{ margin: "0px 10px" }}></small>
<small
style={{ "fontSize": "15px", textDecoration: "line-through" }}
>
Rs {cut}
</small>
</div>
<button onClick={Add_Products} style={{ margin: "10px 0px" }}>
Click here
</button>
</main>
</>
);
}
This is the console,
When I am trying to console the list in the Add_Products function in the Cake.jsx then I am getting undefined.
This is a working codesandbox Link
This is the Birthday.jsx
import image60 from './assets/cake60.jpeg'
import image61 from './assets/cake61.jpeg'
import image62 from './assets/cake62.jpeg'
import image63 from './assets/cake63.jpeg'
import image64 from './assets/cake64.jpeg'
import image65 from './assets/cake65.jpeg'
import image66 from './assets/cake66.jpeg'
import image67 from './assets/cake67.jpeg'
import image68 from './assets/cake68.jpeg'
import image69 from './assets/cake69.jpeg'
import Cake from './Cake'
import { useContext } from "react"
import { PdtList } from "../Cart/Cart"
const pdtArray = [{
id: '32',
name: "Anniversary cake",
images: image60
},
{
id: '33',
name: "Anniversary cake",
images: image61
},
{
id: '134',
name: "Anniversary cake",
images: image62
},
{
id: '34',
name: "Anniversary cake",
images: image63
},
{
id: '35',
name: "Anniversary cake",
images: image64
},
{
id: '36',
name: "Anniversary cake",
images: image65
},
{
id: '37',
name: "Anniversary cake",
images: image66
},
{
id: '38',
name: "Anniversary cake",
images: image67
},
{
id: '39',
name: "Anniversary cake",
images: image68
},
{
id: '40',
name: "Anniversary cake",
images: image69
},]
export default function Birthday(props) {
const list = useContext(PdtList);
console.log(list);
const { title } = props;
return (
<>
<main className='PDT_heading align' >
<h1>{title}</h1>
<div className="grid_system">
{
pdtArray.map((e) => {
const { name, images, id } = e;
return (
<Cake key={id} name={name} images={images} cut="232" bold="343" />
)
})
}
</div>
</main>
</>
)
}
When you are going to use the useContext in a component, make sure that component is wrapped inside the Context.Provider (either the component or the parent of the component). Only then the useContext can able to access the values of the context else it will return the default value which is undefined.
So, the root component will be something lie:
<StrictMode>
<PdtList.Provider value={list}>
<Cart />
<Birthday />
</PdtList.Provider>
</StrictMode>
I wrapped the components inside the Provider so all the components inside can able to access the value.
working link: link

How to fix "Uncaught Error: "t" is read-only" in MUI DataGridPro

I am trying to use MUI DataGridPro, but I keep getting "An error occurred" instead of the component rendering my data. The data is hard-coded, so I know it's not an issue with the data not being present.
I get the following error in the console:
The listed files are all things that are native to DataGridPro and nothing I touched, so I don't know how to go about fixing it (I'm not even sure what "t" is or where it is being called).
Here is my code for the DataGridPro component:
import Box from '#mui/material/Box';
import {
DataGridPro,
GridColumns,
GridRowsProp,
GridToolbar,
LicenseInfo,
} from '#mui/x-data-grid-pro';
import { useDemoData } from '#mui/x-data-grid-generator';
import KeyboardArrowRightIcon from '#mui/icons-material/KeyboardArrowRight';
import { styled } from '#mui/material/styles';
import FormControl from '#mui/material/FormControl';
import FormGroup from '#mui/material/FormGroup';
import Button from '#mui/material/Button';
import InputLabel from '#mui/material/InputLabel';
import MenuItem from '#mui/material/MenuItem';
import Select from '#mui/material/Select';
import { Typography } from '#mui/material';
const columns: GridColumns = [
{ field: 'voicemail', headerName: 'VOICEMAIL' },
{ field: 'patientName', headerName: 'PATIENT NAME' },
{ field: 'patientId', headerName: 'PATIENT ID' },
{ field: 'phoneNumber', headerName: 'PHONE NUMBER' },
{ field: 'callTime', headerName: 'TIME OF CALL' },
{ field: 'department', headerName: 'DEPARTMENT' },
{ field: 'status', headerName: 'STATUS' },
{ field: 'assignee', headerName: 'ASSIGNEE' },
];
const rows: GridRowsProp = [
{
id: 1,
voicemail: '00:13:23',
patientName: 'Holly Shelton',
patientID: '78491684',
phoneNumber: '(667) 370-2337',
callTime: '2:30 pm EST',
department: 'Enrollment',
status: 'Open',
assignee: 'Unassigned',
},
{
id: 2,
voicemail: '00:11:08',
patientName: 'Sharon Bishop',
patientID: '24742813',
phoneNumber: '(345) 246-4865',
callTime: '3:30 pm EST',
department: 'Medical',
status: 'Unavailable',
assignee: 'Alex Alvarez',
},
{
id: 3,
voicemail: '00:15:08',
patientName: 'Marcus Shelton',
patientID: '49030689',
phoneNumber: '(432) 753-8463',
callTime: '4:30 pm EST',
department: 'Medical',
status: 'Call BAck',
assignee: 'Pablo Lueng',
},
];
const VoicemailGrid = (): JSX.Element => (
<Box width="100%" height="350px">
<Typography>Rendering</Typography>
<DataGridPro
rows={rows}
columns={columns}
/>
</Box>
);
export default VoicemailGrid;
And then in index.tsx:
import type { FC } from 'react';
import { Container, makeStyles } from '#material-ui/core';
import type { Theme } from 'src/theme';
import Page from 'src/components/Page';
import VoicemailGrid from 'src/components/VoicemailComponents/VoicemailGrid';
import Header from './Header';
const useStyles = makeStyles((theme: Theme) => ({
root: {
backgroundColor: theme.palette.background.dark,
height: '100vh',
paddingTop: theme.spacing(3),
paddingBottom: theme.spacing(3),
},
}));
const PatientChart: FC<any> = () => {
const classes = useStyles();
return (
<Page className={classes.root} title="Voicemail">
<Container maxWidth="xl">
<Header />
<VoicemailGrid />
</Container>
</Page>
);
};
PatientChart.propTypes = {
};
export default PatientChart;
Try following steps
Delete node_modules
Delete yarn.lock/package-lock.json
yarn install/npm install
try again

How to add SrNo (#) column at first position at mui-datatable React.js

Created table using React and MUI-Datatables: need to add SrNo column at first, also need to add Delete and IsActive button.
import React, { useState, useEffect } from 'react';
import Grid from '#material-ui/core/Grid';
import Switch from '#material-ui/core/Switch';
import MUIDataTable from "mui-datatables";
export const Services = () => {
const [itemList, setItemList] = useState([]);
const [mainColumns, setMainColumns] = useState([]);
const selectData = async () => {
const response = await ServiceAPI(); // data from web wervice
var data = JSON.parse(response.data);
setItemList(data);
};
const createColumns = () => {
var columns = [];
// how to add Sr No column
columns.push(
{
label: 'ID',
name: 'service_id',
});
columns.push(
{
label: 'Name',
name: 'service_name',
});
setMainColumns(columns);
};
useEffect(() => {
createColumns();
selectData();
}, []);
return (
<>
<h3>Service</h3>
<Grid container >
<Grid item xs={12}>
<MUIDataTable
title={"Service"}
data={itemList}
columns={mainColumns}
className="table nowrap"
/>
</Grid>
</Grid>
</>
);
}
tried below code for active/deactivate, but OnChange() is run every time, which should call on only click event (also tried OnClick()):
columns.push(
{
label: 'Active',
name: 'is_active',
options: {
filter: false,
sort: false,
customBodyRender: (value, tableMeta, updateValue) => {
const serviceID = tableMeta.rowData[0];
return (
<Switch color="primary" checked={value} value={value} onChange={activate}/>
/>
);
}
}
});
Please check example. I have added serial number and delete button in this example.
import React from "react";
import ReactDOM from "react-dom";
import MUIDataTable from "mui-datatables";
import IconButton from "#material-ui/core/IconButton";
import Button from "#material-ui/core/Button";
export default class MuiDatatableSerial extends React.Component {
render() {
const columns = [
{name: "sl", label: "Serial No"},
{name: "name", label: "Name"},
{name: "title", label: "Title"},
{name: "location", label: "Location"},
{name: "age", label: "Age"},
{name: "salary", label: "Salary"},
{
name: "delete",
label: "",
options: {
filter: false,
sort: false,
customBodyRender: (value, tableMeta, updateValue) => {
return <Button
color="secondary"
onClick={(ev) =>
alert('deleted')
}> Delete
</Button>;
},
}
}
];
const data = [
{name: "Khabir Uddin", title: "Senior Software Engineer", location: "Dhaka", age: 38, salary: "$150,000"},
{name: "Gabby George", title: "Business Analyst", location: "Minneapolis", age: 30, salary: "$100,000"},
{name: "Aiden Lloyd", title: "Business Consultant", location: "Dallas", age: 55, salary: "$200,000"}
];
let newData = [];
data.map((item, index) => {
newData.push({sl: index + 1, ...item});
});
const options = {
selectableRows: "none",
onRowsSelect: (rowsSelected, allRows) => {
},
};
return (
<MUIDataTable
title={"ACME Employee list"}
data={newData}
columns={columns}
options={options}
/>
);
}
}

React Data Grid shows bad

I have a problem with ReactDataGrid component. I have already installed react-data-grid. The code is the same as in the reac grid's web:
const columns = [
{ key: 'id', name: 'ID' },
{ key: 'title', name: 'Title' },
{ key: 'count', name: 'Count' }];
const rows = [{ id: 0, title: 'row1', count: 20 }, { id: 1, title: 'row1', count: 40 }, { id: 2, title: 'row1', count: 60 }];
class App extends React.Component {
render() {
return (
<ReactDataGrid
columns={columns}
rowGetter={i => rows[i]}
rowsCount={3}
minHeight={150} />
)
}
}
export default App;
and i get:
Result
Thank you!
Import the CSS like so :
import 'react-data-grid/dist/react-data-grid.css';
It should be fine.
import React from "react";
import ReactDOM from "react-dom";
import ReactDataGrid from "react-data-grid";
const columns = [
{ key: "id", name: "ID", editable: true },
{ key: "title", name: "Title", editable: true },
{ key: "count", name: "Count", editable: true }
];
const rows = [
{ id: 0, title: "row1", count: 20 },
{ id: 1, title: "row1", count: 40 },
{ id: 2, title: "row1", count: 60 }
];
class App extends React.Component {
render() {
return (
<ReactDataGrid
columns={columns}
rowGetter={i => rows[i]}
rowsCount={3}
minHeight={150}
enableCellSelect={true}
/>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
https://codesandbox.io/s/rdg-cell-editing-h8bnr
the answer is in the above code this above code is working
You don't really need to downgrade. The issue is that the css is not being imported.
If you can import css from node-modules, it'll work.
Workaround for me was I took the whole css and we are now self-maintaining the css, making changes when needed.
I couldn't load the css either, I got around this by including
import ReactDataGrid from 'react-data-grid/dist/react-data-grid.min.js';
instead of
import ReactDataGrid from 'react-data-grid';

breaking big component into smaller one

I'm working on separating code from index.tsx into two different files viz: firstTab.tsx and secondTab.tsx. I haven't started working on secondTab.tsx yet.
I separated first tab related code into firstTab.tsx as shown in the following code editor: The full functional code with both tabs working are in index.tsx is pasted below:
import React, { Component } from "react";
import { render } from "react-dom";
import "jqwidgets-scripts/jqwidgets/styles/jqx.base.css";
import JqxButton from "jqwidgets-scripts/jqwidgets-react-tsx/jqxbuttons";
import * as ReactDOM from "react-dom";
import JqxWindow from "jqwidgets-scripts/jqwidgets-react-tsx/jqxwindow";
import JqxInput from "jqwidgets-scripts/jqwidgets-react-tsx/jqxinput";
import JqxChart, {
IChartProps
} from "jqwidgets-scripts/jqwidgets-react-tsx/jqxchart";
import JqxGrid, {
IGridProps,
jqx
} from "jqwidgets-scripts/jqwidgets-react-tsx/jqxgrid";
import JqxTabs from "jqwidgets-scripts/jqwidgets-react-tsx/jqxtabs";
import JqxDropDownList, {
IDropDownListProps
} from "jqwidgets-scripts/jqwidgets-react-tsx/jqxdropdownlist";
import firstTab from './firstTab';
interface AppProps {}
interface AppState {
name: string;
}
interface IProps extends IGridProps {
dropdownlistSource: IDropDownListProps["source"];
}
class App extends Component<{}, IProps> {
private myTabs = React.createRef<JqxTabs>();
private gridElement = React.createRef<HTMLDivElement>();
private myGrid = React.createRef<JqxGrid>();
private gridElementTwo = React.createRef<HTMLDivElement>();
private myGrid2 = React.createRef<JqxGrid>();
constructor(props: {}) {
super(props);
this.state = {
dropdownlistSource: [
{ value: 0, label: "Affogato" },
{ value: 1, label: "Americano" },
{ value: 2, label: "Bicerin" },
{ value: 3, label: "Breve" }
]
};
}
public render() {
return (
<JqxTabs
ref={this.myTabs}
// #ts-ignore
width={400}
height={560}
initTabContent={this.initWidgets}
>
<ul>
<li style={{ marginLeft: 30 }}>
<div style={{ height: 20, marginTop: 5 }}>
<div
style={{
marginLeft: 4,
verticalAlign: "middle",
textAlign: "center",
float: "left"
}}
>
US Indexes
</div>
</div>
</li>
<li>
<div style={{ height: 20, marginTop: 5 }}>
<div
style={{
marginLeft: 4,
verticalAlign: "middle",
textAlign: "center",
float: "left"
}}
>
NASDAQ compared to S&P 500
</div>
</div>
</li>
</ul>
<div style={{ overflow: "hidden" }}>
<div id="jqxGrid" ref={this.gridElement} />
<div style={{ marginTop: 10, height: "15%" }} />
</div>
<div style={{ overflow: "hidden" }}>
<div id="jqxGrid2" ref={this.gridElementTwo} />
<div style={{ marginTop: 10, height: "15%" }} />
</div>
</JqxTabs>
);
}
private initGrid = () => {
const source = {
datafields: [{ name: "Date" }, { name: "S&P 500" }, { name: "NASDAQ" }],
datatype: "csv",
localdata: `1/2/2014,1831.98,4143.07
1/3/2014,1831.37,4131.91
1/6/2014,1826.77,4113.68
1/7/2014,1837.88,4153.18
1/8/2014,1837.49,4165.61
1/9/2014,1838.13,4156.19
2/6/2014,1773.43,4057.12
2/7/2014,1797.02,4125.86`
};
const dataAdapter = new jqx.dataAdapter(source, {
async: false,
loadError: (xhr: any, status: any, error: any) => {
console.log(xhr, status, error);
}
});
const columns: IGridProps["columns"] = [
{ cellsformat: "d", datafield: "Date", text: "Date", width: 250 },
{ datafield: "S&P 500", text: "S&P 500", width: 150 },
{ datafield: "NASDAQ", text: "NASDAQ" }
];
const grid = (
<JqxGrid
ref={this.myGrid}
width={"100%"}
height={400}
source={dataAdapter}
columns={columns}
/>
);
render(grid, this.gridElement.current!);
};
private initGrid2 = () => {
const source = {
datafields: [{ name: "Date" }, { name: "S&P 500" }, { name: "NASDAQ" }],
datatype: "csv",
localdata: `1/2/2014,1831.98,4143.07
1/3/2014,1831.37,4131.91
1/6/2014,1826.77,4113.68
1/7/2014,1837.88,4153.18
1/8/2014,1837.49,4165.61
1/9/2014,1838.13,4156.19
1/10/2014,1842.37,4174.67
2/7/2014,1797.02,4125.86`
};
const dataAdapter = new jqx.dataAdapter(source, {
async: false,
loadError: (xhr: any, status: any, error: any) => {
console.log(xhr, status, error);
}
});
const columns: IGridProps["columns"] = [
{ cellsformat: "d", datafield: "Date", text: "Date", width: 250 },
{ datafield: "S&P 500", text: "S&P 500", width: 150 },
{ datafield: "NASDAQ", text: "NASDAQ" }
];
const grid = (
<JqxGrid
ref={this.myGrid2}
width={"100%"}
height={400}
source={dataAdapter}
columns={columns}
/>
);
render(grid, this.gridElementTwo.current!);
};
private initWidgets = (tab: any) => {
switch (tab) {
case 0:
this.initGrid();
break;
case 1:
this.initGrid2();
break;
}
};
}
render(<App />, document.getElementById("root"));
Question:
Since I've already moved private initGrid = () => { inside a separate file firstTab.tsx, in index.tsx where should I put {firstTab.tsx} to make sure both tabs in index.tsx works fine? I mean, even if I comment out private initGrid = () => { function from index.tsx both tabs should work fine.
Thanks
If I would refactor this I would consider the next approach:
Create Parent component Table (probably some more appropriate name)
Create a component for US Indexes
Create a component for NASDAQ compared to S&P 500
Based on the active tab render the proper component.
You could also create a separate file that contains only exports with your data.
If you then import that into your files with the functions you can use that there, keeps it cleaner.
And if you pass that data as a prop / param to your initGrid() functions, you don't have to repeat that code, can reuse it.

Resources