How to control programmatically the toggling of a row? - reactjs

I'm using MaterialTable with REACT (Datatable for React based on Material-UI Table. material-table.com) more precisely the detailed-panel - material-table.com/#/docs/features/detail-panel
What do I need? user should open/close detailed panels and drag/drop items between them.
The problem: each time I React rendering the table all detailed panels are closes.
I'm seeking for a solution that will allow me to set a flag for each row that notes whether it's hidden or open. So while rendering .. React will not close all rows automatically.
I tried setting options and events on the table and panels - None were able to control the row toggling.
The code is very simple:
<MaterialTable
title = "Group Keywords Preview"
columns = {[
{ title : "Group", field : "group" },
{ title : "Weight", field : "weight" }
]}
options={{
selection: true
}}
data = { my data ...}
detailPanel = {[
{
tooltip : 'Show Group',
render : rowData => {
return <my react component .. />
}
}
]}
/>
Does material-table have any flag/method to toggle a row programmatically?
Can I do it in another way?
Thanks in advance.

class DetailPanelWithRowClick extends React.Component {
constructor(props) {
super(props);
this.tableRef = React.createRef();
}
render() {
return (
<>
<MaterialTable
tableRef={this.tableRef}
columns={[
{ title: 'Name', field: 'name' },
{ title: 'Surname', field: 'surname' },
{ title: 'Birth Year', field: 'birthYear', type: 'numeric' },
{
title: 'Birth Place',
field: 'birthCity',
lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' },
},
]}
data={[
{ name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
{ name: 'Zerya Betül', surname: 'Baran', birthYear: 1987, birthCity: 63 },
]}
title="Detail Panel With RowClick Preview"
detailPanel={rowData => {
return (
<iframe
width="100%"
height="315"
src="https://www.youtube.com/embed/C0DPdy98e4c"
frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
/>
)
}}
onRowClick={(event, rowData, togglePanel) => togglePanel()}
/>
<button onClick={() => {
this.tableRef.current.onToggleDetailPanel([0], rowData => <div>{rowData.name}</div>)
}}>toggle second line</button>
</>
)
}
}
You can use as used in above example.

Yes you can do that. Material table mutates your data by adding a tableData object to each item.
It looks like this:
"tableData":{"id":0,"checked":true}}
This controls the row id, if the item is checked and other things like filtering etc.
By changing the checked key to true/false, you can control the selection of the items programmatically.
Hope this helps. Happy coding.

Related

Creative Tim: Material Table data does not align data when used with Creative Tim template

I am trying to use 'material-table' in my Material dashboard 2 pro react dashboard by Creative Tim, but while adding the data in the table, the data is not aligned with the and has a lot of gaps.
My component code:
import { Grid } from "#mui/material";
import MaterialTable from "material-table";
import EditableTable from "examples/Tables/EditableTable";
function AdminTable() {
return (
<Grid>
<MaterialTable
title="Multiple Actions Preview"
columns={[
{ title: 'Name', field: 'name' },
{ title: 'Surname', field: 'surname' },
{ title: 'Birth Year', field: 'birthYear', type: 'numeric' },
]}
data={[
{ name: 'Mehmet', surname: 'Baran', birthYear: 2017 },
]}
/>
</Grid>
)
}
export default AdminTable
Can someone tell me why this is happening? Material table works fine when I use it outside this template but inside this template it does not align.

React MaterialTable clear all filters action - column and global filter

I am absolutely new to react.
It may trivial but I can't figure how to implement action that will clear all table filters.
In my table, I use date filter, drop-down, text, and global filters looking for one-click clear all filters
https://codesandbox.io/s/eager-thunder-ejlg5?file=/src/index.js
<MaterialTable
title="Free Action Preview"
columns={[
{ title: "Name", field: "name" },
{ title: "Surname", field: "surname" },
{ title: "Birth Year", field: "birthYear", type: "numeric" },
{
title: "Birth Place",
field: "birthCity",
lookup: { 34: "İstanbul", 63: "Şanlıurfa" }
}
]}
data={[
{ name: "Mehmet", surname: "Baran", birthYear: 1987, birthCity: 63 },
{
name: "Zerya Betül",
surname: "Baran",
birthYear: 2017,
birthCity: 34
}
]}
actions={[
{
icon: () => <FilterNoneIcon />,
tooltip: "clear all filters",
isFreeAction: true,
onClick: (event) => alert("clear all filters logic")
}
]}
options={{
filtering: true,
sorting: true
}}
/>
As of this writing, it does not look like they have a clear filter functionality - according to this issue at least: https://github.com/mbrn/material-table/issues/1132 since they tagged it as wontfix - meaning they are not planning to work on it. However, on the same issue, 1 of the users recommended using a ref and manually accessing the table to filter the data (although that user later advised against it) - so you can try that as well.
Another way you could do this is to just remount the component. Since the component is remounted, it will begin at its initial state including unfiltered data
function App() {
const [muiTableKey, setMuiTableKey] = React.useState(0);
return (
<MaterialTable
key={muiTableKey}
actions={[
{
icon: () => <FilterNoneIcon />,
tooltip: "clear all filters",
isFreeAction: true,
onClick: (event) => {
setMuiTableKey(muiTableKey + 1); // set new key causing remount
}
}
]}

Ant Design for React : Show/Hide particular column

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"));

material-table How to do selectable and editable table?

i want to do this one(some actions for selected and some actions for each row). Help please, thanks!
I use material-table with ReactJS. Now I have actions on each row without selectable, if add selection prop these actions disappear. I don't know how to combine each row actions with multiple actions..
You can add the position: 'row' prop to actions. There are 4 options available for the position prop: auto', toolbar, toolbarOnSelect, row
This minimal code snippet should work
<MaterialTable
actions={[
{
icon: 'save',
tooltip: 'Save User',
position: 'row',
onClick: (event, rowData) => alert('You saved ' + rowData.name)
},
{
icon: 'delete',
tooltip: 'Delete User',
position: 'row',
onClick: (event, rowData) =>
alert('You want to delete ' + rowData.name)
}
]}
columns={[
{ title: 'Name', field: 'name' },
{ title: 'Surname', field: 'surname' },
{ title: 'Birth Year', field: 'birthYear', type: 'numeric' },
{
title: 'Birth Place',
field: 'birthCity',
lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' }
}
]}
data={[
{
name: 'Mehmet',
surname: 'Baran',
birthYear: 1987,
birthCity: 63
},
{
name: 'Zerya Betül',
surname: 'Baran',
birthYear: 2017,
birthCity: 34
}
]}
options={{
selection: true,
actionsColumnIndex: -1
}}
title="Positioning Actions Column Preview"
/>
Here's the exact place in the source where it is decided whether to show actions column when selection property is set to true:
if (this.props.actions && this.props.actions.filter(a => !a.isFreeAction && !this.props.options.selection).length > 0) {
// ...
}
Another such place is in renderActions method:
const actions = this.props.actions.filter(a => !a.isFreeAction && !this.props.options.selection);
So it either has to be a isFreeAction or selection should be set to false. The only way you can customize this at the moment is to override a Row component - basically copy/paste it, modify those conditions, import the result as a new component and supply it in components property of the material-table config as an override for Row.
CodeSandbox: https://codesandbox.io/s/jovial-architecture-ggnrl

antd table won't render. Objects are not valid as a React child

I really like what I've seen in antd so far, and I'm trying to introduce it to my current code base, but I can't seem to get a table to render, even when I just copy and paste examples into a new project. For example:
I ran create-react-app to get a fresh project, and updated the app component like so:
import React, { Component } from 'react'
import logo from './logo.svg'
import './App.css'
import {Table} from 'antd'
class App extends Component {
render() {
const columns = [{
title: 'Name',
dataIndex: 'name',
render: text => {text},
}, {
title: 'Age',
dataIndex: 'age',
}, {
title: 'Address',
dataIndex: 'address',
}]
const data = [{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
}, {
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
}, {
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
}, {
key: '4',
name: 'Disabled User',
age: 99,
address: 'Sidney No. 1 Lake Park',
}]
// rowSelection object indicates the need for row selection
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
},
getCheckboxProps: record => ({
disabled: record.name === 'Disabled User', // Column configuration not to be checked
name: record.name,
}),
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
<Table>
columns={columns}
dataSource={data}
rowSelection={rowSelection}
</Table>
</p>
</div>
)
}
}
export default App
Note that the column, data, and rowSelection definitions were copied directly from the antd Table docs.
When the page attempts to render, I get the error "Objects are not valid as a React child"
I'm running React 16.2, but can't seem to find any version compatibility info in the antd docs so I'm not sure if that's an issue here.
Following the advice on the antd website, I used their sandbox template, and the table won't render there either. https://codesandbox.io/s/mml3lz31ox
If anyone can offer some insight here on how to use this table, I'd love to hear it!
The syntax is incorrect. It should be this:
<Table
columns={columns}
dataSource={data}
rowSelection={rowSelection}
/>
What your code is doing now is passing children instead, with columns=, dataSource= etc. being passed down as text, with {columns} and the like being interpreted as react element children. Objects are not valid there, hence the error.

Resources