ReactJs MaterialUi onRowUpdate field validation - reactjs

I have a MaterialTable and I want to validate the fields when editing a line.
For example the following code:
https://codesandbox.io/s/broken-snow-i4jbi?fontsize=14&hidenavigation=1&theme=dark
I have the function setNameError
const [nameError, setNameError] = useState({
error: false,
label: '',
helperText: '',
});
Then the onRowUpdate:
onRowUpdate: (newData, oldData) =>
new Promise((resolve, reject) => {
setTimeout(() => {
if(newData.name === '') {
setNameError({
error: true,
label: 'required',
helperText: 'Required helper text'
});
reject();
return;
}
resolve();
...
}, 600);
})
I want to validate if the field name is empty, if it is empty I want to have this aspect:
validation in the field after click Save button
I can't show the error label, it looks like the setNameError inside the Promise is not working and I don't understand how can I do this.

Found the problem
I was storing the columns in state
const [state, setState] = React.useState({
columns: [
{ title: 'Name', field: 'name',
editComponent: props => (
<TextField
type="text"
required={true}
error = {nameError.error}
label = {nameError.label}
helperText = {nameError.helperText}
value={props.value ? props.value : '' }
onChange={e => props.onChange(e.target.value)}
/>
)
},
{ 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,
},
],
});
And then passing the state.columns to the MaterialTable component:
<MaterialTable
title="Editable Example"
columns={state.columns}
data={state.data}
...
The solution was to put the columns definition in the MaterialTable component:
return (
<MaterialTable
title="Editable Example"
columns= {[
{ title: 'Name', field: 'name',
editComponent: props => (
<TextField
type="text"
required={true}
error = {nameError.error}
label = {nameError.label}
helperText = {nameError.helperText}
value={props.value ? props.value : '' }
onChange={e => props.onChange(e.target.value)}
/>
)
},
{ title: 'Surname', field: 'surname' },
{ title: 'Birth Year', field: 'birthYear', type: 'numeric' },
{
title: 'Birth Place',
field: 'birthCity',
lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' },
},
]}
data={state.data}
...

Related

Material table onBulkUpdate click don't change icons

I'm using "material-table": "^2.0.3" version. I want to editable all my data and I used onBulkUpdate option in material table document. but after I click the icon next to the search form change to editable but icon doesn't change at all and to give me submit or reject actions to call any function and save my changes.
here is my code:
const [columns, setColumns] = useState([
{ title: 'Name', field: 'name' },
{
title: 'Surname',
field: 'surname',
},
{ title: 'Birth Year', field: 'birthYear' },
{
title: 'Birth Place',
field: 'birthCity',
lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' },
},
]);
const [data, setData] = useState([
{ name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
{ name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
]);
return (
<div className={styles.container}>
<MaterialTable
title='Bulk Edit Preview'
columns={columns}
data={data}
editable={{
onBulkUpdate: (changes) =>
new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 1000);
}),
}}
/>
</div>
);
I solved my problem by change my package version.
in package.json
"#material-ui/core": "^4.11.4",
"#material-ui/icons": "^4.11.2",
"material-table": "^1.69.3"

How to auto fill in react material table

I am trying to do something like auto fill rowData.properties on material table. But props.value always is undefined. Thisis my code
<MaterialTable
title="Simple 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' },
},
{
title: 'Full name',
field: 'fullName',
editComponent: (props)=>{
return <div onClick={()=> handleClick(props) > // props.value at here always null
<TextField
value={`${props.rowData.name} ${props.rowData.surname}` // fullname with edit component auto fill here
onChange={(e)=>props.onChange(e.target.value)}
/>
</div>
},
}
]}
data={[
{ name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 , fullName: 'Mehmet Baran'},
{ name: 'Zerya', surname: 'Baran', birthYear: 2017, birthCity: 34 , fullName: 'Zerya Baran'},
]}
actions={[
{
icon: 'save',
tooltip: 'Save User',
onClick: (event, rowData) => alert("You saved " + rowData.name)
}
]}
/>
How to auto fill rowData.fieldName in material table? With fullName is example.
Please help me resolve it

Filter a range of data - Ant Design Table

In my react project I'm adding ANT Design table and I implemented a customized column search to filter my data.
Is there any way to filter data in a range in ANT Table? Like in my 'attendance' column, I want to filter student(s) with attendance from 50 to 80. How can I achieve this within ANT Table?
Thanks.
CODE
import React, { useState, useRef } from 'react';
import { Table, Input, Button, Space } from 'antd';
import Highlighter from 'react-highlight-words';
import { SearchOutlined } from '#ant-design/icons';
import '../node_modules/antd/dist/antd.css';
const App = () => {
const [searchText, setSearchText] = useState('');
const [searchedColumn, setSearchedColumn] = useState('');
const searchInput = useRef(null);
let student = [
{
rollNo: 1, name: "Rohit", fatherName: "Lalit", motherName: "Abha", age: 22, marks: 54, address: "Delhi", attendance: 85, contact: 7097991361
},
{
rollNo: 2, name: "Rohan", fatherName: "Ram", motherName: "Akanksha", age: 23, marks: 60, address: "Mumbai", attendance: 56, contact: 7097775553
},
{
rollNo: 3, name: "Ishfaq", fatherName: "Maqbool", motherName: "Amala", age: 24, marks: 49, address: "Chennai", attendance: 73, contact: 7097891779
},
{
rollNo: 4, name: "Sanjay", fatherName: "Ramesh", motherName: "Aditi", age: 24, marks: 44, address: "Mohali", attendance: 55, contact: 7097683032
},
{
rollNo: 5, name: "Anuj", fatherName: "Narayan", motherName: "Amita", age: 23, marks: 56, address: "Delhi", attendance: 60, contact: 7097574082
},
]
const getColumnSearchProps = dataIndex => ({
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
<div style={{ padding: 8 }}>
<Input
type={dataIndex === 'age' ? 'number' : dataIndex === 'marks' ? 'number' : dataIndex === 'attendance' ? 'number' : dataIndex === 'contact' ? 'number' : 'text'}
ref={searchInput}
placeholder={`Search ${dataIndex}`}
value={selectedKeys[0]}
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)}
style={{ marginBottom: 8, display: 'block' }}
/>
<Space>
<Button
type="primary"
onClick={() => handleSearch(selectedKeys, confirm, dataIndex)}
icon={<SearchOutlined />}
size="small"
style={{ width: 90 }}
>
Search
</Button>
<Button onClick={() => handleReset(clearFilters)} size="small" style={{ width: 90 }}>
Reset
</Button>
<Button
type="link"
size="small"
onClick={() => {
confirm({ closeDropdown: false });
setSearchText({
searchText: selectedKeys[0],
});
setSearchedColumn({
searchedColumn: dataIndex,
});
}}
>
Filter
</Button>
</Space>
</div>
),
filterIcon: filtered => <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />,
onFilter: (value, record) =>
record[dataIndex]
? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
: '',
onFilterDropdownVisibleChange: visible => {
if (visible) {
setTimeout(() => searchInput.current.select(), 100);
}
},
render: text =>
searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
searchWords={[searchText]}
autoEscape
textToHighlight={text ? text.toString() : ''}
/>
) : (
text
),
});
const handleSearch = (selectedKeys, confirm, dataIndex) => {
confirm()
setSearchText({
searchText: selectedKeys[0],
});
setSearchedColumn({
searchedColumn: dataIndex,
});
};
const handleReset = clearFilters => {
clearFilters();
setSearchText({ searchText: '' });
};
const columns = [
{
title: 'Roll No.',
dataIndex: 'rollNo',
key: 'rollNo',
},
{
title: 'Name',
dataIndex: 'name',
key: 'name',
...(getColumnSearchProps)('name'),
},
{
title: 'Father Name',
dataIndex: 'fatherName',
key: 'fatherName',
...(getColumnSearchProps)('fatherName'),
},
{
title: 'Mother Name',
dataIndex: 'motherName',
key: 'motherName',
...(getColumnSearchProps)('motherName'),
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
...(getColumnSearchProps)('age'),
},
{
title: 'Marks',
dataIndex: 'marks',
key: 'marks',
...(getColumnSearchProps)('marks'),
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
...(getColumnSearchProps)('address'),
},
{
title: 'Attendance',
dataIndex: 'attendance',
key: 'attendance',
...(getColumnSearchProps)('attendance'),
},
{
title: 'Fine',
dataIndex: 'fine',
key: 'fine',
},
{
title: 'Status',
dataIndex: 'status',
key: 'status',
},
{
title: 'Contact',
dataIndex: 'contact',
key: 'contact',
...(getColumnSearchProps)('contact'),
},
];
return <Table columns={columns} dataSource={student} />;
}
export default App;

Value is not updating in MaterialTable

I try to edit the value and update the same but its not updating in MaterialTable
Below is the link which am refering
https://material-table.com/#/docs/features/editable
under this am refering Cell Editable Example
what am missing here
any suggestion?
please refer below snippet
import React from "react";
import MaterialTable from "material-table";
export default function CellEditable() {
const { useState } = React;
const [columns, setColumns] = useState([
{ title: "Name", field: "name" },
{
title: "Surname",
field: "surname",
initialEditValue: "initial edit value"
},
{ title: "Birth Year", field: "birthYear", type: "numeric" },
{
title: "Birth Place",
field: "birthCity",
lookup: { 34: "İstanbul", 63: "Şanlıurfa" }
}
]);
const [data, setData] = useState([
{ name: "Mehmet", surname: "Baran", birthYear: 1987, birthCity: 63 },
{ name: "Zerya Betül", surname: "Baran", birthYear: 2017, birthCity: 34 }
]);
return (
<MaterialTable
title="Cell Editable Preview"
columns={columns}
data={data}
cellEditable={{
onCellEditApproved: (newValue, oldValue, rowData, columnDef) => {
return new Promise((resolve, reject) => {
console.log("newValue: " + newValue);
setTimeout(resolve, 1000);
});
}
}}
/>
);
}
The code you are using never sets the state, it just logs to the console.
You need to set the state at some point. I was able to get this working, though I am uncertain if this is the correct approach.
Update
If you wish to disable a specific column you can add editable: 'never' to the specific column. See below where I added this to the birthYear.
function CellEditable() {
const { useState } = React;
const [columns, setColumns] = useState([
{ title: 'Name', field: 'name' },
{ title: 'Surname', field: 'surname', initialEditValue: 'initial edit value' },
{ title: 'Birth Year', field: 'birthYear', type: 'numeric', editable: 'never' },
{
title: 'Birth Place',
field: 'birthCity',
lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' },
},
]);
const [data, setData] = useState([
{ name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
{ name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
]);
return (
<MaterialTable
title="Cell Editable Preview"
columns={columns}
data={data}
cellEditable={{
onCellEditApproved: (newValue, oldValue, rowData, columnDef) => {
return new Promise((resolve, reject) => {
const clonedData = [ ...data ]
clonedData[rowData.tableData.id][columnDef.field] = newValue
setData(clonedData)
setTimeout(resolve, 1000);
});
}
}}
/>
)
}

Get Fetched Data to table data in material ui react

I Have Fetched Some Data from a url via axios .I want to display those data to material ui table data in React. Here, 'patient' is the array where fetched data stored.
Code:
const [patient, setPatient] = React.useState([])
const [state, setState] = React.useState({
columns: [
{ title: 'Name', field: 'name' },
{ title: 'Gender', field: 'gender' },
{ title: 'Age', field: 'age', type : 'numeric' },
{ title: 'Birth Year', field: 'birthYear', type : 'numeric' },
{ title: 'Phone Number', field: 'phoneNumber', type : 'tele'
},
],
data: [
],
});
React.useEffect(()=>{
axios.get('http://127.0.0.1:8000/patient/AppModel/')
.then(res =>{
setPatient(res.data)
})
.catch(err=>{
console.log(err)
})
},[])
return (
<MaterialTable
title="Patient List"
columns={state.columns}
data={state.data}
/>
})}
But actually i don't how to get an array data to an array of objects.

Resources