Using CheckboxEditor with react-data-grid - reactjs

I'm new to React and I'm trying to get the react-data-grid to display a checkbox for one of the columns. I have imported react-data-grid and react-data-grid-addons but I'm not sure how to pass the required props to the CheckboxEditor.
import React, {PropTypes} from "react";
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
import * as identityActions from "../../actions/identityActions";
import * as defectViewActions from "../../actions/defectViewActions";
import MultiSelectBox from "../common/MultiSelectBox";
import ReactDataGrid from "react-data-grid";
import Editors from "react-data-grid-addons";
const {CheckboxEditor} = Editors;
class UserProfilePage extends React.Component {
constructor(props, context) {
super(props, context);
this.setReportingArea = this.setReportingArea.bind(this);
this.rowGetter = this.rowGetter.bind(this);
this.onCellChanged = this.onCellChanged.bind(this);
this.state = {
viewColumns: [],
summaryColumns: [],
detailColumns: [],
commentColumns: [],
columns: [
{
key: "Name",
name: "Column",
resizable: false,
width: 200,
editable: false
},
{
key: "SummaryView",
name: "Summary",
resizable: false,
width: 80,
editor: <CheckboxEditor value={this.props.value} column={null} rowIdx={"1"} />
},
{
key: "DetailView",
name: "Detail",
resizable: false,
width: 80,
editable: true,
},
{
key: "CommentView",
name: "Comment",
resizable: false,
width: 80,
editable: true,
}
]
};
}
componentDidMount() {
this.props.defectViewActions.loadViewColumns();
}
componentWillReceiveProps(nextProps) {
if ((!this.props.viewColumns || this.props.viewColumns.length === 0) && (nextProps.viewColumns || nextProps.viewColumns.length > 0)) {
nextProps.viewColumns.forEach(function (col) {
col.SummaryView = false, col.DetailView = false, col.CommentView = false;
switch (col.DefaultView) {
case 1:
col.SummaryView = true;
break;
case 2:
col.DetailView = true;
break;
case 3:
col.CommentView = true;
break;
}
});
this.setState({
viewColumns: nextProps.viewColumns
})
;
}
}
onCellChanged() {
console.log("Cell updated");
}
// -- React Data Grid ----------------------------------------------------------------------------------------------------------
rowGetter(i) {
if (this.state.viewColumns.length > 0) {
return {
value: this.state.viewColumns[i]
};
}
else {
return "";
}
}
// -----------------------------------------------------------------------------------------------------------------------------
setReportingArea(event) {
this.props.actions.setPreferredReportingArea(event.target.value);
}
render() {
return (
<div style={{marginTop: '50px'}}>
<table className="table table-condensed" style={{width: '70%', margin: 'auto'}}>
<thead>
<tr>
<th colSpan="3"><h2>User Profile</h2></th>
</tr>
</thead>
<tbody>
<tr>
<td>Name:</td>
<td>{this.props.user.name}</td>
</tr>
<tr>
<td>Email:</td>
<td>
{this.props.user.Username}
</td>
</tr>
<tr>
<td>Preferred Reporting Area:</td>
<td>
{(this.props.user.ReportingArea) ? (
<MultiSelectBox name="ddlReportingArea"
onChange={this.setReportingArea}
value={this.props.user.ReportingAreaId}
options={this.props.user.ReportingAreas.map((ra) => {
return {id: ra.Id, value: ra.ReportingAreaName};
}).sort((a, b) => {
return a.value > b.value;
})}/>)
: "None Assigned"}
</td>
</tr>
</tbody>
</table>
<div className="row" style={{width: '70%', margin: 'auto'}}>
<div className="form-horizontal form-group">
<label className="col-md-2 control-label">View:</label>
<div className="col-md-2">
<select className="form-control">
<option>Default</option>
</select>
</div>
</div>
</div>
<div className="row" style={{width: '70%', margin: 'auto'}}>
<div className="col-md-6">
<h4>Available Columns</h4>
<ReactDataGrid
rowHeight={35}
minHeight={500}
minWidth={450}
maxWidth={450}
columns={this.state.columns}
rowGetter={this.rowGetter}
rowsCount={this.state.viewColumns.length}/>
</div>
<div className="col-md-2">
<h4>Default Columns</h4>
</div>
<div className="col-md-2">
<h4>Detail Columns</h4>
</div>
<div className="col-md-2">
<h4>History Columns</h4>
</div>
</div>
</div>
);
}
}
UserProfilePage.propTypes = {
user: PropTypes.object.isRequired,
viewColumns: PropTypes.array.isRequired,
defectViewActions: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired
};
function mapStoreStateToProps(state, ownProps) {
return {
user: state.Identity,
viewColumns: state.ViewColumns
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(identityActions, dispatch),
defectViewActions: bindActionCreators(defectViewActions, dispatch)
};
}
export default connect(mapStoreStateToProps, mapDispatchToProps)(UserProfilePage);
From the documentation is presume "value" is returned by the "rowGetter" but how do I pass the "key" and "onCellChange" props to the CheckboxEditor and is "rowIdx" obtained from "this.state.viewColumns".
Any examples or tutorials would be greatly appreciated.

Related

how to close react dropdown componet after out focus?

I've created a react dropdown component to show a list of data. this data get from server and I handle dropdown list show/hide with display property.
I want to use this component in other components. I need that closed after click out of component in the parent.
export default class Dropdown extends React.Component {
constructor(props) {
super(props);
this.state = {
show: false,
value: "",
data: []
};
this.handleChange = this.handleChange.bind(this);
}
componentDidMount() {
this.getData();
}
async getData() {
const response = await fetch(this.props.url);
const data = await response.json();
this.setState({ data: data });
}
handleChange(event) {
this.setState({ value: event.target.value });
}
render() {
return (
<div className={styles.container}>
<input type="text" name="name"
onClick={() => this.setState({ show: !this.state.show })}
className={styles.bottonStyle}
value={this.state.value}
onChange={this.handleChange}
/>
<div style={Object.assign({
position: "absolute", backgroundColor: "#f9f9f9", minWidth: "350px", zIndex: "1"
}, this.state.show ? { display: "block" } : { display: "none" })} >
<div style={Object.assign({ backgroundColor: "lightgray" }, !this.state.showMounthList ? { display: "block" } : { display: "none" })} >
<table>
<tr style={{ backgroundColor: "orange" }}>
<th>Id</th>
<th>code</th>
<th>name</th>
</tr>
{
this.state.data.length > 0 ? (
this.state.data.map((item) => {
return <tr>
<td>{item.id}</td>
<td>{item.code}</td>
<td>{item.fullName}</td>
</tr>
})
) : null
}
</table>
</div>
</div >
</div >);
}}

TypeError: h is undefined

I have the following code working properly except when I click on the following button inside projectSpacedGrid function, I get errors in the browser's console as shown below the code:
<Button
label="Associate Project Spaces"
icon="pi pi-plus"
style={{ marginRight: ".25em", marginTop: ".25em" }}
onClick={e =>
this.setState({
assocAssetsVisible: true
})
}
/>
Here's my full code( I've removed lot of code to keep it as small as possible):
import React from "react";
import * as ReactDOM from "react-dom";
import JqxTabs from "jqwidgets-scripts/jqwidgets-react-tsx/jqxtabs";
import JqxGrid, {
IGridProps,
jqx
} from "jqwidgets-scripts/jqwidgets-react-tsx/jqxgrid";
import JqxButton from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxbuttons';
import JqxInput from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxinput';
import JqxDateTimeInput from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxdatetimeinput';
import JqxWindow from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxwindow';
import JqxDropDownList, { IDropDownListProps } from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxdropdownlist';
import JqxNotification from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxnotification';
import { Button } from "primereact/button";
import { Growl } from "primereact/growl";
import { properties } from ".././properties";
import { Messages } from "primereact/messages";
import axios from "axios/index";
type Props = {
project,
username
};
export interface AssetsState extends IGridProps {
//export interface AssetsState extends IDropDownListProps {
visible: boolean,
assocAssetsVisible: boolean,
project: {},
selectedAsset: [],
addEditLabel: {},
selectedRowIndex: number,
deleteDialogVisible: boolean,
dropdownlistSource:IDropDownListProps["source"];
rendertoolbar: (toolbar: any) => void;
}
export class Assets extends React.PureComponent<Props, AssetsState> {
private growl = React.createRef<Growl>();
//Created Refs for a particular div
private projectSpacesGridElement = React.createRef<HTMLDivElement>();
//Created Refs for the desired widgets (JQXGrid and JQXTabs)
private assetsDataGrid = React.createRef<JqxGrid>();
private myTabs = React.createRef<JqxTabs>();
//Created Refs for editing popups for project spaces tab
private assetsEditWindow = React.createRef<JqxWindow>();
private assetsAddWindow = React.createRef<JqxWindow>();
private id = React.createRef<JqxInput>();
private assetsTypeId = React.createRef<JqxInput>();
private assetCategoryId = React.createRef<JqxInput>();
private locationTypeId = React.createRef<JqxInput>();
private statusIndicatorId = React.createRef<JqxInput>();
private uri = React.createRef<JqxInput>();
private fileName = React.createRef<JqxInput>();
private fileAddCDSName = React.createRef<JqxInput>();
private fileVersion = React.createRef<JqxInput>();
private fileEncodingId = React.createRef<JqxInput>();
private ownerId = React.createRef<JqxInput>();
private createdDate = React.createRef<JqxDateTimeInput>();
private updatedDate = React.createRef<JqxDateTimeInput>();
private createdBy = React.createRef<JqxInput>();
private assetDescription = React.createRef<JqxInput>();
private assetCDSDescription = React.createRef<JqxInput>();
private msgNotification = React.createRef<JqxNotification>();
private firstTabButtonContent = "Add New Project Space ";
private editrow: number = -1;
private baseUrl = properties.baseUrlWs;
private messages = React.createRef<Messages>();
constructor(props: Props) {
super(props);
this.saveEditCDSBtn = this.saveEditCDSBtn.bind(this);
this.cancelEditCDSBtn = this.cancelEditCDSBtn.bind(this);
this.savenewCDSpaceBtn = this.savenewCDSpaceBtn.bind(this);
this.cancelnewCDSpaceBtn = this.cancelnewCDSpaceBtn.bind(this);
const rendertoolbar = (toolbar: any): void => {
const addPSRowClick = () => {
this.assetsAddWindow.current!.open();
};
ReactDOM.render(
<div style={{ margin: '5px' }}>
<div id="button1" style={{ float: 'left' }}>
<JqxButton theme={'material'} onClick={addPSRowClick} width={155} value={'Add Project Space'} />
</div>
</div>,
toolbar[0]
);
};
this.state = {
visible: false,
project: {},
assocAssetsVisible: false,
selectedAsset: [],
addEditLabel: {},
selectedRowIndex: null,
deleteDialogVisible: false,
rendergridrows: (params: any): any[] => {
const data = params.data;
return data;
},
rendertoolbar,
dropdownlistSource:[
{value:0, label:'Individual'},
{value:1, label:'Project'},
{value:2, label:'Institution'},
{value:3, label:'Public'}
]
};
}
public render() {
console.log(this.state.selectedAsset);
return (
<div>
<JqxTabs
ref={this.myTabs}
theme={"arctic"}
width="1390px"
//height={560}
//height={100}
initTabContent={this.initWidgets}
onSelected={this.onTabSelected}
>
<ul>
<li style={{ marginLeft: 30 }}>
<div style={{ height: 20, marginTop: 5 }}>
<div style={{ float: "left" }}></div>
<div
style={{
marginLeft: 4,
verticalAlign: "middle",
textAlign: "center",
float: "left"
}}
>
Project Spaces
</div>
</div>
</li>
</ul>
<div style={{ overflow: "hidden" }}>
<div id="jqxGrid" ref={this.projectSpacesGridElement} />
<div style={{ marginTop: 10, height: "15%", width: "100%" }}></div>
</div>
</JqxTabs>
<JqxWindow ref={this.assetsEditWindow} width={250} height={230} resizable={false}
isModal={false} autoOpen={false} modalOpacity={'0.01'} position={{ x: 68, y: 368 }}>
<div>Edit</div>
<div style={{ overflow: 'hidden' }}>
<table>
<tbody>
<tr>
<td align={'right'}>Name :</td>
<td align={'left'}>
<JqxInput ref={this.fileName} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'}>Version:</td>
<td align={'left'}>
<JqxInput ref={this.fileVersion} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'}>Description:</td>
<td align={'left'}>
<JqxInput ref={this.assetDescription} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'}>Visibility Indicator:</td>
<td align={'left'}>
{/* <JqxInput ref={this.visibilityIndicatorID} width={150} height={23} /> */}
<JqxDropDownList width={100} height={20} source={this.state.dropdownlistSource} selectedIndex={0} autoDropDownHeight={true}/>
</td>
</tr>
<tr hidden>
<td align={'right'}>ID:</td>
<td align={'left'}>
<JqxInput ref={this.id} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Location Type ID:</td>
<td align={'left'}>
<JqxInput ref={this.locationTypeId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Asset Category ID:</td>
<td align={'left'}>
<JqxInput ref={this.assetCategoryId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Asset Type ID:</td>
<td align={'left'}>
<JqxInput ref={this.assetsTypeId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Status Indicator ID:</td>
<td align={'left'}>
<JqxInput ref={this.statusIndicatorId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>URI:</td>
<td align={'left'}>
<JqxInput ref={this.uri} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>File Encoding ID:</td>
<td align={'left'}>
<JqxInput ref={this.fileEncodingId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Owner ID:</td>
<td align={'left'}>
<JqxInput ref={this.ownerId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Created Date:</td>
<td align={'left'}>
<JqxDateTimeInput ref={this.createdDate}
width={150} height={23} formatString={'F'} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Updated Date:</td>
<td align={'left'}>
<JqxDateTimeInput ref={this.updatedDate}
width={150} height={23} formatString={'F'} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Created By:</td>
<td align={'left'}>
<JqxInput ref={this.createdBy} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'} />
<td style={{ paddingTop: '10px' }} align={'right'}>
<JqxButton style={{ display: 'inline-block', marginRight: '5px' }} onClick={this.saveEditCDSBtn} width={50}>
Save
</JqxButton>
<JqxButton style={{ display: 'inline-block', marginRight: '5px' }} onClick={this.cancelEditCDSBtn} width={50}>
Cancel
</JqxButton>
</td>
</tr>
</tbody>
</table>
</div>
</JqxWindow>
<JqxWindow ref={this.assetsAddWindow} width={250} height={230} resizable={false}
isModal={false} autoOpen={false} modalOpacity={'0.01'} position={{ x: 68, y: 368 }}>
<div>{this.firstTabButtonContent}</div>
<div style={{ overflow: 'hidden' }}>
<table>
<tbody>
<tr>
<td align={'right'}>Name:</td>
<td align={'left'}>
<JqxInput ref={this.fileAddCDSName} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'}>Description:</td>
<td align={'left'}>
<JqxInput ref={this.assetCDSDescription} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'}>Visibility Indicator:</td>
<td align={'left'}>
<JqxDropDownList width={100} height={20} source={this.state.dropdownlistSource} selectedIndex={0} autoDropDownHeight={true} />
</td>
</tr>
<tr>
<td align={'right'} />
<td style={{ paddingTop: '10px' }} align={'right'}>
<JqxButton style={{ display: 'inline-block', marginRight: '5px' }} onClick={this.savenewCDSpaceBtn} width={50}>
Save
</JqxButton>
<JqxButton style={{ display: 'inline-block', marginRight: '5px' }} onClick={this.cancelnewCDSpaceBtn} width={50}>
Cancel
</JqxButton>
</td>
</tr>
</tbody>
</table>
</div>
</JqxWindow>
<JqxNotification ref={this.msgNotification}
width={250} position={'top-left'} opacity={0.9} autoOpen={false}
autoClose={true} animationOpenDelay={800} autoCloseDelay={3000} template={'info'} appendContainer={'#forNotification'}>
<div>
Record Deleted Successfully!
</div>
</JqxNotification>
</div>
);
}
//Tab 1
private projectSpacesGrid = () => {
const source: any = {
datafields: [
{ name: "id", type: "long" },
{ name: "assetsTypeId", type: "long" },
{ name: "fileName", type: "string" },
{ name: "locationTypeId", type: "long" },
{ name: "uri", type: "string" },
{ name: "fileVersion", type: "string" },
{ name: "fileEncodingId", type: "long" },
{ name: "ownerId", type: "long" },
{ name: "createdDate", type: "date",format: "dd-MMM-yy" },
{ name: "assetCategoryId", type: "long" },
{ name: "assetDescription", type: "string" },
{ name: "createdBy", type: "string" },
{ name: "updatedDate", type: "date",format: "dd-MMM-yy" },
{ name: "statusIndicatorId", type: "long" },
{ name: "visibilityIndicatorId", type: "long" },
{ name: "displayedValues", type: "string" }
],
deleterow: (rowid: number,commit:any): void => {
console.log("Delete row method called in source of Project Spaces");
console.log("Role ID:" + rowid);
commit(true);
},
datatype: "json",
root: "assets",
url: this.baseUrl + `api/assets/search/getAssetsByProjectId`
};
const dataAdapter = new jqx.dataAdapter(source, {
//async: false,
autoBind: true,
downloadComplete: (data: any, status: any, xhr: any): void => {
source.totalrecords = parseInt(data["page"].totalElements);
console.log("Total Assets Records check"+source.totalrecords);
},
formatData: (data: any): any => {
data.value = this.props.project.id;
data.page = data.pagenum;
data.size = data.pagesize;
if (data.sortdatafield && data.sortorder) {
data.sort = data.sortdatafield + "," + data.sortorder;
}
return data;
},
loadError: (xhr: any, status: any, error: any) => {
alert('Error loading "' + source.url + '" : ' + error);
}
});
const columns: IGridProps["columns"] = [
{ datafield: "id", text: "ID Number", width: 100,hidden:true },
{ datafield: "assetsTypeId", text: "Assets Type ID", width: 100, hidden: true },
{ datafield: "fileName", text: "Name", width: 275 },
{ datafield: "fileVersion", text: "File Version", width: 275, hidden: true },
{ datafield: "fileEncodingId", text: "File Encoding", width: 275, hidden: true },
{ datafield: "ownerid", text: "Owner ID", width: 100, hidden: true },
{ datafield: "assetCategoryId", text: "Asset Category ID", width: 100, hidden: true },
{ datafield: "statusIndicatorId", text: "Status Indicator ID", width: 100, hidden: true },
{ datafield: "visibilityIndicatorId", text: "Visibility Indicator ID", width: 100, hidden: true },
{ datafield: "displayedValues", text: "Display Values", width: 100, hidden: true },
{
datafield: "assetDescription",
text: "Description",
width: 250
},
{ datafield: "locationTypeId", text: "Location Type", width: 150 },
{ datafield: "uri", text: "URI", width: 150 },
{ datafield: "ownerId", text: "Owner", width: 150 },
{
//cellsformat: "d",
cellsformat: "MM/dd/yyyy",
datafield: "createdDate",
text: "Created Date",
width: 150
},
{
//cellsformat: "d",
cellsformat: "MM/dd/yyyy",
datafield: "updatedDate",
text: "Updated Date",
width: 100
},
{
text: "Delete ",
buttonclick: (): void => {
},
cellsrenderer: (): string => {
return "Delete";
},
columntype: "button",
datafield: "Delete",
width: 80
},
{
text: "Edit Asset",
buttonclick: (row: number): void => {
// show the popup window.
this.assetsEditWindow.current!.open();
},
cellsrenderer: (): string => {
return "Edit";
},
columntype: "button",
datafield: "Edit",
width: 80
}
];
const grid =
this.state.visible || this.state.assocAssetsVisible ? null : (
<div>
<JqxGrid
ref={this.assetsDataGrid}
width={"100%"}
height={"100%"}
theme={"arctic"}
source={dataAdapter}
columns={columns}
showtoolbar={true}
pageable={true}
pagesize={50}
scrollmode={"default"}
rendertoolbar={this.state.rendertoolbar}
sortable={true}
/>
<Button
label="Associate Project Spaces"
icon="pi pi-plus"
style={{ marginRight: ".25em", marginTop: ".25em" }}
onClick={e =>
this.setState({
assocAssetsVisible: true
})
}
/>
</div>
);
ReactDOM.render(grid, this.projectSpacesGridElement.current!);
};
private saveEditCDSBtn(): void {
if (this.editrow >= 0) {
this.assetsEditWindow.current!.hide();
}
}
private cancelEditCDSBtn(): void {
this.assetsEditWindow.current!.hide();
}
private savenewCDSpaceBtn(): void {
this.assetsAddWindow.current!.hide();
}
private cancelnewCDSpaceBtn(): void {
this.assetsAddWindow.current!.hide();
}
private initWidgets = (tab: any) => {
switch (tab) {
case 0:
this.projectSpacesGrid();
break;
}
};
private onTabSelected = (event: any) => {
if (event.args) {
let tabIndex = event.args.item;
switch (event.args.item) {
case 0:
this.assetsAddWindow.current!.setTitle(this.firstTabButtonContent);
break;
}
}
};
}
Error Below:
The above error occurred in the <JqxWindow> component:
in JqxWindow (created by Assets)
in div (created by Assets)
in Assets (created by ProjectTabView)
in div (created by TabView)
in div (created by TabView)
in div (created by TabView)
in TabView (created by ProjectTabView)
in ProjectTabView (created by ProjectView)
in div (created by ProjectView)
in ProjectView (created by Route)
in Route (created by Main)
in Switch (created by Main)
in div (created by Main)
in div (created by Main)
in Router (created by BrowserRouter)
in BrowserRouter (created by Main)
in Main
in ErrorBoundary
React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
TypeError: "h is undefined"
propertyChangedHandler webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxwindow.js?:8
setvalueraiseevent webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
set webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
each webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:8
set webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
jqxWidgetProxy webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
b.jqx.jqxWidget/b.fn[h]/< webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
each webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:8
each webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:8
h webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
setOptions webpack:///./node_modules/jqwidgets-scripts/jqwidgets-react-tsx/jqxwindow/react_jqxwindow.esm.js?:88
componentDidUpdate webpack:///./node_modules/jqwidgets-scripts/jqwidgets-react-tsx/jqxwindow/react_jqxwindow.esm.js?:82
React 6
unstable_runWithPriority webpack:///./node_modules/scheduler/cjs/scheduler.development.js?:818
React 5
unstable_runWithPriority webpack:///./node_modules/scheduler/cjs/scheduler.development.js?:818
React 6
Adding screenshots of complete error from the browser console:
Is it something related to associateAssetsVisible:true variable that I'm using?

How to handle the graph data when the graph component is called in loop using react-redux

I am displaying the graphs by getting data from API and then looping it.
Now I have a button in each of the graph components. when I click on one of the buttons only that graph data need to change, but I am seeing all the graphs are getting the change because of same reducers data is taking by graphs.
https://imgur.com/a/WNeDtLF
In the above graph image, you can see if we click on week link in one of the graphs only that graph data need to change but both the graphs data are getting change.
dashboard.js
<Col md="12" lg="12" className="mb-3">
{this.state.graphdata.map((data, i) => {
return (
<Col
sm="12"
md="6"
lg="6"
className="flt-lft pl-1 pr-1"
key={i}
>
<Electricity
graphinfo={data}
loading={this.props.GraphDataRequest}
grapherror={this.props.GraphDataError}
daytypeinfo={this.graphchange}
pidinfo={this.state.locationid}
size={"12"}
location={"LOCATION"}
/>
</Col>
)
})
</Col>
Electricty.js
import React, { Component, Fragment } from "react";
import Chart from "react-apexcharts";
import LineGraph from "./LineGraph";
import BarGraph from "./BarGraph";
import { connect } from "react-redux";
import { dashboardGraphDays } from "../../Actions";
class Electricity extends Component {
constructor(props) {
super(props);
this.state = {
optionsMixedChart1: {
chart: {
height: 300,
toolbar: {
show: false
}
},
legend: {
position: "top",
fontSize: "26px"
},
dataLabels: {
enabled: false
},
tooltip: {
followCursor: false,
x: {
show: false
}
},
labels: [],
xaxis: {
type: "month",
title: {
text: "hour"
},
labels: {
style: {
fontSize: this.props.size,
cssClass: "apexcharts-xaxis-label"
}
}
},
yaxis: {
title: {
text: "Kwh"
}
}
},
series: []
};
}
componentDidMount() {
this.setState(prevState => ({
...prevState,
optionsMixedChart1: {
...prevState.optionsMixedChart1,
labels: this.props.graphinfo.labels,
xaxis: {
...prevState.optionsMixedChart1.xaxis,
title: {
...prevState.optionsMixedChart1.xaxis.title,
text: this.props.graphinfo.xAxis.text
? this.props.graphinfo.xAxis.text
: ""
}
},
yaxis: {
...prevState.optionsMixedChart1.yaxis,
title: {
...prevState.optionsMixedChart1.yaxis.title,
text: this.props.graphinfo.yAxis.text
? this.props.graphinfo.yAxis.text
: ""
}
}
},
series: this.props.graphinfo.series,
header: this.props.graphinfo.header ? this.props.graphinfo.header : "",
uidetailid: this.props.graphinfo.uiDetailId
? this.props.graphinfo.uiDetailId
: "",
location: this.props.location
}));
}
componentDidUpdate(PrevPros, PrevState) {
if (PrevPros.GraphDataSuccess != this.props.GraphDataSuccess) {
this.setState(
prevState => ({
...prevState,
optionsMixedChart1: {
...prevState.optionsMixedChart1,
labels: this.props.GraphDataSuccess[0].labels,
xaxis: {
...prevState.optionsMixedChart1.xaxis,
title: {
...prevState.optionsMixedChart1.xaxis.title,
text: this.props.GraphDataSuccess[0].xAxis.text
? this.props.GraphDataSuccess[0].xAxis.text
: ""
}
},
yaxis: {
...prevState.optionsMixedChart1.yaxis,
title: {
...prevState.optionsMixedChart1.yaxis.title,
text: this.props.GraphDataSuccess[0].yAxis.text
? this.props.GraphDataSuccess[0].yAxis.text
: ""
}
}
},
series: this.props.GraphDataSuccess[0].series
}),
console.log(this.state)
);
this.setState({
header: this.props.GraphDataSuccess[0].header
? this.props.GraphDataSuccess[0].header
: "",
uidetailid: this.props.GraphDataSuccess[0].uiDetailId
? this.props.GraphDataSuccess[0].uiDetailId
: ""
});
}
}
changeColor = Selecteddaytype => {
this.setState({ selectedtype: Selecteddaytype });
const consumptiontaginfo = consumptiondaytag();
consumptiontaginfo.propertyId = this.props.pidinfo;
consumptiontaginfo.interval = Selecteddaytype;
consumptiontaginfo.uiDetailId = this.state.uidetailid;
consumptiontaginfo.labelName = this.state.location;
this.props.dashboardGraphDays(consumptiontaginfo);
};
showhidegraph = data => {
data == "bar"
? this.setState({
shown: true
})
: this.setState({
shown: false
});
};
renderData = () => {
if (this.props.grapherror == "invalid data") {
return <Error />;
} else {
if (
this.state.optionsMixedChart1 &&
this.state.optionsMixedChart1.length !== 0
) {
return (
<Card className="mb-3 energy-cons-graph">
<CardHeader className="card-header-tab p-4">
<div className="card-header-title text-capitalize">
{this.state.header}
</div>
<div className="btn-actions-pane-right text-capitalize actions-icon-btn">
<div className="btn-group dropdown">
<button
className="btn-danger btn btn-shadow mr-1"
onClick={() => this.showhidegraph("bar")}
title="bar graph"
>
<i className="fa fa-bar-chart" aria-hidden="true" />
</button>
<button
className="btn btn-success btn-shadow mr-1"
onClick={() => this.showhidegraph("line")}
title="line graph"
>
<i className="fa fa-line-chart" aria-hidden="true" />
</button>
</div>
</div>
</CardHeader>
<CardBody className="p-1 text-left">
<Button
color="link"
style={{ color: this.state.dailycolor }}
onClick={() => this.changeColor("DAILY")}
>
Daily
</Button>
<Button
color="link"
style={{ color: this.state.weeklycolor }}
onClick={() => this.changeColor("WEEKLY")}
>
Weekly
</Button>
<Button
color="link"
style={{ color: this.state.monthlycolor }}
onClick={() => this.changeColor("MONTHLY")}
>
Monthly
</Button>
</CardBody>
<CardBody className="pt-0">
{this.state.shown ? (
<BarGraph
options={this.state.optionsMixedChart1}
series={this.state.series}
/>
) : (
<LineGraph
options={this.state.optionsMixedChart1}
series={this.state.series}
/>
)}
</CardBody>
</Card>
);
} else {
return <NoDataFound />;
}
}
};
render() {
return (
<Fragment>
{this.state.loading == true ? <Loading /> : this.renderData()}
</Fragment>
);
}
}
const mapStateToProps = state => {
return {
GraphDataRequest: state.DashboardTable.MixedgraphdayFetching,
GraphDataSuccess: state.DashboardTable.ResponsedayGraph.responseData,
GraphDataError: state.DashboardTable.ResponsedayGraphError
};
};
export default connect(
mapStateToProps,
{ dashboardGraphDays }
)(Electricity);

how to copy table rows and columns to clipboard in react using react-copy-to-clipboard?

How can I copy rows and table content in react ? im using antd library however when i copy the table rows and contents and paste using react-copy -to clipboard currently table data is being store in json this.state.datasource but when i copy i just get [object Object],[object Object] instead of actuall row and column data , can someone pls help thanks!
/*eslint-disable */
import React, { Component } from 'react'
import { Table, Input, Button, Popconfirm, Form } from 'antd'
import { Helmet } from 'react-helmet'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { Menu, Icon } from 'antd';
import {CopyToClipboard} from 'react-copy-to-clipboard';
import styles from './style.module.scss'
const EditableContext = React.createContext();
const EditableRow = ({ form, index, ...props }) => (
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
);
const { SubMenu } = Menu;
const EditableFormRow = Form.create()(EditableRow);
class EditableCell extends React.Component {
state = {
editing: false,
copied: false,
};
onCopy() {
console.log("copied");
alert('copied to clipboard');
}
renderCell = form => {
this.form = form;
const { children, dataIndex, record, title } = this.props;
const { editing } = this.state;
return editing ? (
<Form.Item style={{ margin: 0 }}>
{form.getFieldDecorator(dataIndex, {
rules: [
{
required: true,
message: `${title} is required.`,
},
],
);
};
render() {
const {
editable,
dataIndex,
title,
record,
index,
handleSave,
children,
...restProps
} = this.props;
return (
<td {...restProps}>
{editable ? (
<EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
) : (
children
)}
</td>
);
}
}
class Campaign extends React.Component {
constructor(props) {
super(props);
this.columns = [
{
title: 'id',
dataIndex: 'id',
},
{
title: 'Campaign Name',
dataIndex: 'name',
editable: true,
},
{
title: 'Banners',
dataIndex: 'address',
editable: true,
},
{
title: 'Video',
dataIndex: 'Video',
editable: true,
},
{
title: 'Target',
dataIndex: 'Target',
editable: true,
},
{
title: 'Exchanges',
dataIndex: 'Exchanges',
editable: true,
},
{
title: 'Status',
dataIndex: 'Status',
editable: true,
},
{
title: 'Delete',
dataIndex: 'Banners',
render: (text, record) =>
this.state.dataSource.length >= 1 ? (
<Popconfirm title="Sure to delete?" onConfirm={() => this.handleDelete(record.key)}>
<a style={{color:'blue'}} href="javascript:;">Delete</a>
</Popconfirm>
) : null,
},
];
this.state = { //table data i want to copy
dataSource: [
{
key: '0',
name: 'Kates Campaign',
id: '32',
Video: 'London, Park Lane no. 0',
Target: 'bacon',
Exchanges: 'Eggs',
},
{
key: '1',
name: 'Fyber Tests',
id: '32',
address: 'Sample Banner Ad (ID 6 ECPM 20.0) ',
},
],
count: 2,
};
}
render() {
const { dataSource } = this.state;
const components = {
body: {
row: EditableFormRow,
cell: EditableCell,
},
};
const columns = this.columns.map(col => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: record => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave: this.handleSave,
}),
};
});
return (
<div>
<br></br>
<h1> Campaigns </h1>
<br></br><br></br>
<Menu
className={styles.menu}
onClick={this.handleClick}
style={{ marginleft: 80}}
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
mode="inline"
>
<SubMenu className={styles.sub}
key="sub4"
title={
<span>
<Icon type="setting"style={{
color: '#8c54ff'}} />
<span className={styles.title}>Options</span>
</span>
}
>
<span className={styles.icon}> <Icon type="arrow-down" style={{
color: '#8c54ff'}} /></span>
<Menu.Item key="9"> CSV</Menu.Item>
<span className={styles.icon}><Icon type="sync" style={{
color: '#8c54ff'}}/> </span>
<Menu.Item key="11"> Sync</Menu.Item>
<span className={styles.icon}>
<Icon
type="copy"
style={{
color: '#8c54ff',
}}
/>
</span>// this is function to copy table data
<CopyToClipboard text={dataSource} onCopy={() => this.setState({copied: true})}>
</SubMenu>
</Menu>
<br></br>
);
}
}
export default Campaign

Is there is way to set pagination arrows to be enabled even there is no data?

how can i set pagination arrows to be enabled even there is no data or even if i'll use a condition to switch disable/enablePagination Arrows
import React from 'react';
import PropTypes from 'prop-types';
import { Helmet } from 'react-helmet';
import { NavLink } from 'react-router-dom';
import Truncate from 'react-truncate';
// Material-UI
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
import AddIcon from '#material-ui/icons/Add';
import EditIcon from '#material-ui/icons/Edit';
import MaterialTable, { MTableToolbar, TablePagination } from 'material-table';
import IconButton from '#material-ui/core/IconButton';
import Tooltip from '#material-ui/core/Tooltip';
import Typography from '#material-ui/core/Typography';
import Zoom from '#material-ui/core/Zoom';
// Components
import Entity from '~/Components/Entity';
import violationsStyles from './styles';
import Strings from '~/Services/Strings';
// Services
import Navigate from '~/Services/Navigate';
#withStyles(violationsStyles)
class Violations extends React.Component {
state = {
data : [],
pageIndex: 0,
pageSize: 1,
totalCount: 0
}
componentDidMount() {
this.get();
}
get() {
const { pageIndex, pageSize } = this.state;
this.entity.get({ pageIndex, pageSize });
}
get options() {
return {
actionsColumnIndex: -1,
pageSize: 10,
filtering: true,
columnsButton: true,
maxBodyHeight: 550,
doubleHorizontalScroll: true,
headerStyle: {
color: '#434343',
fontSize: 13
}
};
}
get localization() {
return {
header: {
actions: '',
},
body: {
emptyDataSourceMessage: Strings.listEmptyLabel,
},
pagination: {
labelRowsPerPage: Strings.rowsPerPageLabel,
labelDisplayedRows: `{from}-{to} ${Strings.fromText} {count}`,
},
toolbar: {
addRemoveColumns: Strings.addRemoveColumns,
showColumnsTitle: Strings.showColumnsTitle
},
};
}
get columns() {
const { classes } = this.props;
return [
{ title: Strings.violationReferenceNumber, field: 'referenceNumber', cellStyle: { width: 110 } },
{
title: Strings.violationDescription,
field: 'description',
render: rowData => (
<Typography>
<Truncate lines={1} ellipsis={<span>... </span>}>
{rowData.description}
</Truncate>
</Typography>
),
cellStyle: { paddingLeft: 0 }
},
{ title: Strings.violationPenalty,
field: 'penaltyTypeId',
lookup: {
1: Strings.inform,
2: Strings.alert,
3: Strings.suspension,
},
cellStyle: { width: '120px' }
},
{
title: Strings.violationStatus,
field: 'isArchived',
lookup: {
false: Strings.violationIsNotSettled,
true: Strings.violationIsSettled,
},
cellStyle: { width: '130px' },
defaultFilter: [ 'false' ]
},
{
title: Strings.listActionsLabel,
field: 'isArchived',
render: rowData => (
<div className={classes.iconWrapper}>
<Choose>
<When condition={rowData.isArchived === 'true'}>
<Tooltip TransitionComponent={Zoom} title={Strings.violationEditActionOn}>
<span>
<IconButton disabled={rowData.isArchived === 'true'}>
<EditIcon fontSize="default"/>
</IconButton>
</span>
</Tooltip>
</When>
<Otherwise>
<IconButton disabled={rowData.isArchived === 'true' ? true : false} onClick={() => Navigate.go(`/violations/editor/${rowData.id}`)}>
<Tooltip TransitionComponent={Zoom} title={Strings.violationListEditLabel}>
<EditIcon fontSize="default"/>
</Tooltip>
</IconButton>
</Otherwise>
</Choose>
</div>
),
filtering: false,
cellStyle: { paddingLeft: 35, paddingRight: 75, textAlign: 'left', justifyContent: 'flex-end', display: 'flex' },
headerStyle: { paddingLeft: 35, textAlign: 'left', }
},
];
}
get components() {
const { classes } = this.props;
return {
Toolbar: props => (
<div className={classes.toolbar}>
<MTableToolbar {...props} />
<div className={classes.customActionsBar}>
<Button component={NavLink} to={'/violations/editor'} variant={'outlined'} color={'primary'}>
<AddIcon className={classes.rightIcon} />
{Strings.addNewViolation}
</Button>
</div>
<div className={classes.tabelSecondHeader}>
<Typography variant='h6'>
{Strings.listOfViolations}
</Typography>
</div>
</div>
),
Pagination: props => (
<TablePagination {...props}
count={this.state.totalCount}
/>
),
};
}
onEntityReceived(data) {
const arr = data.result;
const mutableList = [];
if(arr && arr.length > 0) {
arr.map(item => {
mutableList.push({
...item,
isArchived: item.isArchived.toString()
});
});
this.setState({
data: mutableList,
totalCount: data.totalCount
});
}
}
render() {
const { data } = this.state;
return (
<React.Fragment>
<Helmet>
<title>
{Strings.violationsManegment}
</title>
</Helmet>
<Entity
storeId={'Supervision-Violations'}
entityRef={ref => { this.entity = ref; }}
onEntityPosted={() => this.onEntityPosted()}
onEntityReceived={data => this.onEntityReceived(data)}
render={store => (
<MaterialTable
title={Strings.violationsManegment}
data={data}
isLoading={store.loading}
options={this.options}
localization={this.localization}
columns={this.columns}
components={this.components}
onChangePage={pageIndex => this.setState({ pageIndex })}
onChangeRowsPerPage={pageSize => this.setState({ pageSize })}
/>
)}
/>
</React.Fragment>
);
}
}
Violations.propTypes = {
classes: PropTypes.object,
};
export default Violations;
i need to update the count of table because i'm getting the data from back-end and i'm using server side pagination technique and it appears that the total counts automatically be the total rows received unless i mutated it to be be total count that i received from endpoint because i receive some data per page
Use nextIconButtonProps={{disabled:false}} and backIconButtonProps={{disabled:false}}
could you try using the override that is explained here https://material-table.com/#/docs/features/component-overriding.
Use the code above to try to find a way of that you want. Right now there isnt a property that you can do that in a easy way.
components={{
Pagination: props => (
<TablePagination
{...props}
rowsPerPageOptions={[5, 10, 20, 30]}
rowsPerPage={this.state.numberRowPerPage}
count={this.state.totalRow}
page={
firstLoad
? this.state.pageNumber
: this.state.pageNumber - 1
}
onChangePage={(e, page) =>
this.handleChangePage(page + 1)
}
onChangeRowsPerPage={event => {
props.onChangeRowsPerPage(event);
this.handleChangeRowPerPage(event.target.value);
}}
/>
),
}}

Resources