Reputation:
I need some help actually I am using Material UI & React and need to have two implementation that is
Code are as follow
import React from 'react';
import {
Typography,
Table,
TableHead,
TableRow,
TableCell,
TableContainer,
TableBody,
Button
} from '@material-ui/core';
const Table = props => {
const { columnHeaders, data } = props;
return (
<>
<TableContainer >
<Table>
<TableHead>
<TableRow >
{columnHeaders.map((k, index) => (
<TableCell
key={k}
className={'product-line-tablehead '}
style={{
width: `${100 / columnHeaders.length}%`
}}
>
{k.title}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{data.map((k, index) => (
<TableRow key={index}>
<TableCell>
<Typography variant='body1'
>
{k.Product}
</Typography>
</TableCell>
<TableCell>
<Typography
>
{k.Code}
</Typography>
</TableCell>
<TableCell>
<Typography
>
{k.Branding}
</Typography>
</TableCell>
<TableCell align='center'>
<Typography
>
<img
src={DeleteIcon}
/>
<Button
>
Clear
</Button>
</Typography>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</>
);
};
export default Table;
where i am getting the value and the parent component is something like this
import React, { useEffect } from 'react';
import { Grid, Typography } from '@material-ui/core';
import Table from './Table';
const mocklabels = [
{
title: 'Teacher',
link: '' },
{
title: 'Student',
link: '' }
];
const columnHeaders = [
{
title: 'Name'
},
{
title: 'Class'
},
{
title: 'Gender'
},
{
title: ''
}
];
const data = [
{
Product: 'Lorum Ipsum Dolar',
Code: 'Lorum Ipsum Dolar',
Branding: 'Lorum Ipsum Dolar'
},
{
Product: 'Lorum Ipsum Dolar',
Code: 'Lorum Ipsum Dolar',
Branding: 'Lorum Ipsum Dolar'
}
];
);
};
;
Image 1
Image 2
Image 3
Image 4
Upvotes: 1
Views: 732
Reputation: 500
Starting out, whenever you want to 'filter' an array of items in a React App based on a condition(s). Please make sure to save an original copy of the data. This is absolutely important since once the filters are removed, you'd probably want to go back to display the original data.
const [mainData, setMainData] = useState(data); //orignial array
const [appData, setAppData] = useState(data.slice()); //copied array that is rendered
With that being said, your use case requires you to toggle a filtering option on the table headers and based on which column the filter is applied to, you need to filter the items on that property.
You seemed to have used an array of columns to render the table headers, so I just added an additional property of 'key' on each object. This property's value should match the property on the object that is rendered out as a table row.
const columnHeaders = [
{
title: "Product Name",
key: "Product", //should match your data's object key
value: ""
},
{
title: "Product Name",
key: "Code", //should match your data's object key
value: ""
},
{
title: "Product Name",
key: "Branding", //should match your data's object key
value: ""
},
{
title: ""
}
];
Table headers should now render like this:
<TableRow>
{props.tableHeaders.map((k, index) => (
<TableCell
key={index}
className={"product-line-tablehead "}
style={{
width: `${100 / props.tableHeaders.length}%`
}}
>
{k.title ? (
<>
<h3>{k.title}</h3>
{props.isSearching && (
<Input
value={k.value}
onChange={(e) => {
props.handleHeaderChange(e, index, k.key);
}}
/>
)}
</>
) : props.isSearching ? (
<CancelIcon
onClick={() => {
props.setSearching(false);
}}
/>
) : (
<SearchIcon
onClick={() => {
props.setSearching(true);
}}
/>
)}
</TableCell>
))}
</TableRow>
Next, the onChange handler handleHeaderChange(e, index, k.key);
is responsible to trigger the filtering on the table's records. The implementation should be as follows:
const handleHeaderChange = (e, index, prop) => {
tableHeaders[index].value = e.target.value;
setTableHeaders(tableHeaders);
let _newAppData = mainData.filter((f) => {
let _condition = tableHeaders
.filter((h) => h.value)
.map((a) => {
let _obj = f[a.key];
return (
_obj !== undefined &&
_obj.toString().toLowerCase().indexOf(a.value.toLowerCase()) >= 0
);
});
return _condition.indexOf(false) >= 0 ? false : true;
});
setAppData(_newAppData);
};
So in here, we are just filtering the original data by iterating over header input values and associating to the respective object property value.
f
is each item in the data array, a
is each item on the header array which has key
(that is the name of the property on f
) and value
that is the filter input of that column.
_condition
is an array of boolean values and _condition.indexOf(false) >= 0 ? false : true;
simply signifies an AND condition.
full code can be found here: https://codesandbox.io/s/trusting-sound-5lo12z?file=/src/App.js:564-667
Upvotes: 1