I want to customize the row hat data in mui-datatble in such a way that if I get Yes in the option, background color should be Red and if I say No, background color should be Blue. I am using mui-datatable first time.
I am unable to use customRowRender or customRender. How do we use it in mui-datatable
import React from 'react';
import MUIDataTable from "mui-datatables";
class Datatable extends React.Component {
render() {
const columns = [
{
name: "name",
label: "Name",
options: {
filter: true,
sort: true,
customRowRender:(data, dataIndex, rowIndex) => {
console.log('data' + data);
return (
<div>
{data}{' '}{dataIndex}{' '}{rowIndex}
</div>
);
}
}
},
{
name: "company",
label: "Company",
options: {
filter: true,
sort: false,
}
}
];
const data = [
{ name: "Joe James", company: "Test Corp" },
{ name: "John Walsh", company: "Test Corp" }
];
const options = {
filterType: 'checkbox',
};
return (
<React.Fragment>
<MUIDataTable
title={"Employee List"}
data={data}
columns={columns}
options={options}
/>
</React.Fragment>
);
}}
export default Datatable;
I should be able to render data in customRender where I will add a conditional render with a <div> and style depending on Yes/No
You have put the customRowRender property in the columns object, according to the doc it should be in the options object :
const options = {
filterType: 'checkbox',
customRowRender:(data, dataIndex, rowIndex) => {
console.log('data' + data);
return (
<div>
{data}{' '}{dataIndex}{' '}{rowIndex}
</div>
);
}
};
// render
<MUIDataTable
title={"Employee List"}
data={data}
columns={columns}
options={options}
/>
But this is for rendering a custom row, if you want to render a custom column, then you can use customBodyRender property in the columns object.
Related
I am using react hooks and have a dynamically filled array of values after a backend call. How can I then insert these values (which I don't know a priori) in a checkbox?
I get some properties from another component.
These properties change based on a selection from a table.
I would like to be able to add / remove these properties based on a selection on a checkbox when I open the "Available roles list"
const UsersList = (props) => {
const { loadedRoles } = props;
const [checked, setChecked] = useState([]);
const selectHandler = (Event, selected) => {
loadedRoles(selected.roles);
};
const handleChange = (Event) => {
setChecked({ ...props.roles, [Event.target.name]: Event.target.checked });
};
return (
<div>
<MaterialTable
title=" Users List"
data={props.users}
columns={[
{ title: "User Id", field: "id" },
{ title: "Active", field: "active" },
{ title: "System", field: "system" },
{ title: "Roles", field: "roles" },
]}
options={{
cellStyle: {
width: 100,
minWidth: 100,
height: 1,
},
headerStyle: {
width: 100,
minWidth: 100,
},
}}
onRowClick={selectHandler}
/>
<Card>Current Role: {props.current}</Card>
<Card>
<label>Available Roles: {props.roles}</label>
<Checkbox name={props.roles} onChange={handleChange} />
</Card>
</div>
I can assume that you receive from your backend an array of objects, containing the label, keys, and values for the checkboxes?
[
{ label: 'Checkbox #1', key: 'checkbox1', checked: true },
{ label: 'Checkbox #2', key: 'checkbox2', checked: false },
{ label: 'Checkbox #3', key: 'checkbox3', checked: true },
]
You can make the call to the API in a useEffect, store the result in a local state via useState, then iterate through the values in the rendering:
const [checkboxes, setCheckboxes] = useState(null)
useEffect(() => {
fetch('/your/api')
.then(res => res.json())
.then(checkboxes => setCheckboxes(checkboxes))
}, [])
return (
<ul>
{checkboxes === null
? <li>Loading...</li>
: checkboxes.map(checkbox => (
<li key={checkbox.key}>
<label>
<input type="checkbox" name={key} defaultChecked={checkbox.checked} />
{checkbox.label}
</label>
</li>
))
}
</ul>
)
The checkboxes here are not controlled (defaultChecked). To use controlled checkboxes instead, you’ll need to create another local state and initialize it from the values returned by the backend, and use checked & onChange props instead.
In my react/redux app, i have data already in the state found in redux and i want to pass that data to my react useState in order to serve the component with the data in terms of getting the current state data or updating the state data.
I have tried but my way is not working. What is the most efficient way of going about solving this issue with react hook. Also how to configure the react useEffect properly.
// action
import { HrEmployeeData } from "../../actions/employeeHR";
const EmployeeTable = ({ employeesDetail, HrEmployeeData }) => {
const [employeesDetail, setEmployeesDetail] = React.useState([]);
useEffect(() => {
HrEmployeeData();
}, []);
const classes = useStyles();
const columns = [
{ name: "name", label: "Name" },
{ name: "phone_no", label: "Contact" },
{ name: "email", label: "Email" },
{ name: "department", label: "Department" },
{ name: "job_title", label: "Title" },
{ name: "salary", label: "Salary" },
{ name: "date_employed", label: "Date Employed" },
{
name: "Action",
options: {
filter: true,
sort: false,
empty: true,
customBodyRender: (value, tableMeta, updateValue) => {
return (
<button
onClick={() =>
window.alert(`Clicked "Edit" for row ${tableMeta.rowIndex}`)
}
>
Edit
</button>
);
},
},
},
];
return (
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={classes.paper}>
<MUIDataTable
title={"Employees Records"}
data={employeesDetail} <--- WHERE THE DATA IS BEEING USED
columns={columns}
options={options}
/>
</Paper>
</Grid>
</Grid>
</div>
);
};
EmployeeTable.propTypes = {
employeesDetail: PropTypes.object,
};
const mapStateToProps = (state) => ({
employeesDetail: state.employeeHR.employeesDetail,
});
export default connect(mapStateToProps, { HrEmployeeData })(EmployeeTable);
You don't have to pass the data from the redux store the state.
The mechanism to use the redux store in components is "props".
In this case you're already mapping store to props and you can use it in the components.
Just remove the useState line.
I need a bit of help here, In an Ant Design table, I need to hide/show a particular column of a table depending on a state value. In the given sandbox link, I need to hide the surname column whenever the switch is Off and show when the switch is On.
Please, someone, look into this, and help me out.
Reference: https://codesandbox.io/s/purple-sun-1rtz1?file=/index.js
There is a working code, but it should be more customize, interactivize, and refactorize depending on your need:
// You can also modify the data in the `handleChnage`
// Or conditionally display it like here:
class EditableTable extends React.Component {
state = {
surNameShow: false
};
constructor(props) {
super(props);
this.columns = [
{
title: "Name",
dataIndex: "name",
width: "30%"
},
{
title: "Surname",
dataIndex: "surname",
width: "30%"
}
];
this.state = {
dataSource: [
{
key: "0",
name: "Edward 1",
surname: "King 1"
},
{
key: "1",
name: "Edward 2",
surname: "King 2"
}
]
};
}
handleChnage = key => {
this.setState({ surNameShow: !this.state.surNameShow }, () => {
console.log(this.state.surNameShow);
});
};
render() {
const { dataSource } = this.state;
const columns = this.columns;
return (
<div>
<p className="mr-3"> Show surname</p>
<Switch onChange={() => this.handleChnage()} />
<Table
bordered
dataSource={dataSource}
columns={
this.state.surNameShow
? columns
: columns.filter(ea => ea.dataIndex !== "surname")
}
pagination={false}
/>
</div>
);
}
}
ReactDOM.render(<EditableTable />, document.getElementById("container"));
I have a requirement to display a boolean value in a switch. for eg my data is in {id:1,first_name:ABC,last_name:XYZ,allow: true}. I need to display allow in a switch. I am using mui-datatables
Please check this example
import React from "react";
import MUIDataTable from "mui-datatables";
import Switch from "#material-ui/core/Switch";
export default class MuiDatatableSwitch extends React.Component {
render() {
const columns = [
{label: "Name", name: "Name"},
{label: "Title", name: "Title"},
{name: "Location"},
{name: "Age"},
{name: "Salary"},
{
name: "Allow",
options: {
filter: true,
sort: false,
customBodyRender: (value, tableMeta, updateValue) => {
return <div>
<Switch checked={value}/>
</div>;
}
},
},
];
const data = [
["Gabby George", "Business Analyst", "Minneapolis", 30, "$100,000", true],
["Aiden Lloyd", "Business Consultant", "Dallas", 55, "$200,000", false]
];
const options = {
selectableRows: "multiple",
selectableRowsHeader: data.length > 0,
};
return (
<MUIDataTable
title={"ACME Employee list"}
data={data}
columns={columns}
options={options}
/>
);
}
}
I have a table which displays clinics. I have also a onPageChange prop which handles the pageIndex and then i fetch the data based on that page. Below is my table configuration
import 'react-table/react-table.css'
import React, { Component } from 'react';
import ClinicFormComponent from './newClinicForm';
import SearchFormComponent from '../search/searchForm';
import { connect } from 'react-redux';
import { fetchClinics, fetchClinic, deleteClinic, searchClinics, pushBreadcrumb, popBreadcrumb } from '../../actions/index.js';
import { toast } from 'react-toastify';
import ReactTable from 'react-table'
import store from '../../helpers/store';
import { ic_search } from 'react-icons-kit/md/ic_search';
import SvgIcon from 'react-icons-kit';
require('normalize.css/normalize.css');
// require('styles/App.css');
class ClinicsPage extends Component {
constructor() {
super();
this.handleClickForm = this.handleClickForm.bind(this);
this.handleClickFormSearch = this.handleClickFormSearch.bind(this);
this.closeForm = this.closeForm.bind(this);
this.onPageChange = this.onPageChange.bind(this);
}
componentDidMount(){
this.props.searchClinics({ country: 'Australia' });
}
onPageChange(pageIndex) {
this.props.fetchClinics(pageIndex, null);
}
render() {
let { devs } = this.props;
const columns = [{
Header: 'Id',
accessor: 'id' // String-based value accessors!
}, {
Header: 'Name',
accessor: 'name'
}, {
Header: 'Description', // Required because our accessor is not a string
accessor: 'description',
sortable: true
// accessor: d => d.friend.name // Custom value accessors!
},
{
Header: 'Country', // Required because our accessor is not a string
accessor: 'country',
sortable: true
// accessor: d => d.friend.name // Custom value accessors!
},
{
Header: 'Area', // Required because our accessor is not a string
accessor: 'area',
sortable: true
// accessor: d => d.friend.name // Custom value accessors!
},
{
Header: 'Latitude', // Required because our accessor is not a string
accessor: 'latitude',
sortable: true
// accessor: d => d.friend.name // Custom value accessors!
},
{
Header: 'Longitude', // Required because our accessor is not a string
accessor: 'longitude',
sortable: true
// accessor: d => d.friend.name // Custom value accessors!
},
{
Header: 'Tags', // Required because our accessor is not a string
accessor: 'tags',
sortable: true,
Cell: (row) => {if (row.original.tags.length>1) { return row.original.tags.join(', ') } else { return row.original.tags } }
},
{
Header: () => <span className="text-center">Actions</span>,
accessor: 'id',
id: 'actions',
sortable: true,
Cell: (row) => (<span><button className="text-center btn btn-primary-zoetis margin_right_5" onClick={()=>{this.props.history.push('/editClinic/'+ row.original.id)}}>Edit</button ><button className="text-center btn btn-danger" onClick={()=>{this.props.deleteClinic(row.original.id, row.original)}}>Delete</button ></span>)
}
]
return (
<div className="wrap">
<div className="row margin_top_10 margin_bottom_5">
<div className="col-sm-6">
<a className="btn btn-link color_zoetis btn_zoetis_alt" data-toggle="collapse" role="button" aria-expanded="false" aria-controls="collapseExample2" onClick={this.handleClickForm}>NEW CLINIC</a>
</div>
<div className="col-sm-6">
<a className="nav-link float_right search-clinic-btn" data-toggle="collapse" onClick={this.handleClickFormSearch} role="button" aria-expanded="false" aria-controls="collapseExample"><span className="search_label">Search data entries...</span> <SvgIcon size={25} icon={ic_search}/></a>
</div>
</div>
<div id="nav-tabContent">
<ReactTable
data={devs.clinics}
pageSizeOptions= {[10]}
defaultPageSize= {10}
columns={columns}
pages={devs.paginationData.totalPages || ''}
sortable={true}
multiSort={true}
//manual
filterable
page={devs.paginationData.pageNumber}
loading={devs.isFetching}
onPageChange={this.onPageChange}
noDataText='No Data Found'
className='-striped -highlight'
/>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
devs: state.reducer.devs,
showMenu: state.reducer.devs.showMenu,
showEditMenu: state.reducer.devs.showEditMenu,
paginationData: state.reducer.devs.paginationData,
location: state.router.location.pathname
}
}
export const mapDispatchToProps = {
fetchClinics,
searchClinics,
fetchClinic,
deleteClinic,
pushBreadcrumb,
popBreadcrumb
}
export default connect(mapStateToProps, mapDispatchToProps)(ClinicsPage);
Notice that i have disabled manual prop. If i enable the manual prop then i can navigate through next and previous pages but i cannot sort or filter the data.
With the manual prop disabled the filtering and the sorting works correct but when i navigate in the next page the table is showing empty. The first page displays correct the first 10 data. Also i have tested the api and returns correct the next 10 data.
Is there any workaround? To keep both server side pagination and alse the default sorting and filtering?
Test decomposing manual property
<ReactTable
filtered={this.state.filtered}
onFilteredChange={this.onFilteredChange.bind(this)}
defaultFilterMethod={(filter, row) =>
String(row[filter.id]) === filter.value
}
columns={columns}
ref={r => (this.selectTable = r)}
className="-striped -highlight"
defaultPageSize={10}
data={this.state.data}
pages={this.state.pages}
loading={this.state.loading}
manual <-------
resizable={true}
filterable
filterAll={true}
onFetchData={(state, instance) => {
this.setState({loading: true})
axios.get(`${API}${controller}`, {
params: {
pages: state.page,
pageSize: state.pageSize,
filtered: state.filtered,
typeOption: `${type}`,
dateinit: `${this.state.dateinit}`,
datefinal: `${this.state.datefinal}`,
data: this.props.data
},
headers: { 'Authorization': `${tokenCopyPaste()}` }
})
.then((res) => {
this.props.exportTable(res.data, type);
this.setState({
data: res.data.data,
fulldata: res.data,
pages: Math.ceil(res.data.pages / state.pageSize),
loading: false
})
})
}
}
/>