The idea was to create an advanced search page that would enable users to filter data as per their choice by selecting as many as five options to narrow down their search. The results would then later get displayed on a table. Having said that, a user may decide to filter by either using only a single option i.e By state, or by taking multiple options i.e By Name, By District, and By Category or as said earlier up to 5 options. However, I have no way of figuring out how this can be done. You would find screenshots followed by the code below:
A scenario where the user chooses to filter using the By State option
Scenario, where the options are chosen are multiple to narrow down the search
The code is as follows:
const AdvanceFilterScreen = () => {
const [byNameFilter, setByNameFilter] = useState(false);
const [name, setName] = useState('');
const [byDateFilter, setByDateFilter] = useState(false);
const [byCategoryFilter, setByCategoryFilter] = useState(false);
const [category, setCategory] = useState('');
const [byDistrictFilter, setByDistrictFilter] = useState(false);
const [district, setDistrict] = useState('');
const [byStateFilter, setByStateFilter] = useState(false);
const [status, setStatus] = useState('');
const [bySerialNumberFilter, setBySerialNumberFilter] = useState(false);
const [serialNumber, setSerialNumber] = useState('');
const [byIssueFilter, setbyIssueFilter] = useState(false);
const [buttonValue, setFilterButtonValue] = useState('');
//What the following methods do is set the value of setFilterButtonValue to '' so that
//the value of the current selected option turns to blank upon de-selecting them
//On-Click methods that store the values to choiceArray
const nameFilter = () => {
setByNameFilter(prev => !prev);
setFilterButtonValue('');
setName('')
}
const categoryFilter = () => {
setByCategoryFilter(prev => !prev);
setFilterButtonValue('');
setCategory('')
}
const districtFilter = () => {
setByDistrictFilter(prev => !prev);
setFilterButtonValue('');
setDistrict('')
}
const stateFilter = () => {
setByStateFilter(prev => !prev);
setFilterButtonValue('');
setStatus('')
}
const serialNumberFilter = () => {
setBySerialNumberFilter(prev => !prev);
setFilterButtonValue('');
setSerialNumber('')
}
return (
<div className="advanceFilterScreen">
<div className="navBarFilter">
<NavBar></NavBar>
</div>
<div className="chooseFilters">
<div className="chooseColumn">
<div className="caption">Choose Filters (Upto 5 filters at a time)</div>
<div className="filterOptions">
<div onClick={nameFilter}>
<div className={byNameFilter ? "nameSelectedFilter" : "byNameFilter"}>By Name</div>
</div>
<div onClick={() => setByDateFilter(prev => !prev)}>
<div className={byDateFilter ? "dateSelectedFilter" : "byDateFilter"}>By Date</div>
</div>
<div onClick={categoryFilter}>
<div className={byCategoryFilter ? "categorySelectedFilter" : "byCategoryFilter"}>By Category</div>
</div>
<div onClick={districtFilter}>
<div className={byDistrictFilter ? "districtSelectedFilter" : "byDistrictFilter"}>By District</div>
</div>
<div onClick={stateFilter}>
<div className={byStateFilter ? "stateSelectedFilter" : "byStatesFilter"}>By States</div>
</div>
<div onClick={serialNumberFilter}>
<div className={bySerialNumberFilter ? "serialNumberSelectedFilter" : "bySerialNumberFilter"}>By Serial Number</div>
</div>
<div onClick={() => setbyIssueFilter(prev => !prev)}>
<div className={byIssueFilter ? "issueSelectedFilter" : "byIssueFilter"}>By Issue</div>
</div>
</div>
</div>
</div>
<div className={(byNameFilter || byDateFilter || byCategoryFilter || byDistrictFilter || byStateFilter || bySerialNumberFilter || byIssueFilter) ? "filterDropdowns" : "noFilter"}>
<div className="filterClass">
{byNameFilter ? <div style={{ marginRight: "15px" }}>
<NameFilter setName={setName}></NameFilter>
</div> : null}
{byDateFilter ? <div style={{ marginRight: "15px" }}>Search By Date</div> : null}
{byCategoryFilter ? <div style={{ marginRight: "15px" }}>
<CategoryFilter setCategory={setCategory}></CategoryFilter>
</div> : null}
{byDistrictFilter ? <div style={{ marginRight: "15px" }}>
<DistrictFilter setDistrict={setDistrict}></DistrictFilter>
</div> : null}
{byStateFilter ? <div style={{ marginRight: "15px" }}>
<StatusFilter setStatus={setStatus}></StatusFilter>
</div> : null}
{bySerialNumberFilter ? <div style={{ marginRight: "15px" }}>
<SerialNumberFilter setSerialNumber={setSerialNumber}></SerialNumberFilter>
</div> : null}
{byIssueFilter ? <div>Search By Issue</div> : null}
</div>
<div>
<FilterSearchButton name={name} category={category} district={district} status={status} serialNumber={serialNumber} setFilterButtonValue={setFilterButtonValue}></FilterSearchButton>
</div>
</div>
<div style={{ marginTop: "50px" }}>
{district ? <DistrictTable district={district}></DistrictTable> : null}
<Table buttonValue={buttonValue}></Table>
</div>
</div>
);
};
export default AdvanceFilterScreen;
FilterSearchButton component
This is where the filtering occurs using the props received from the selected options. Right now, this component is configured only to filter using one prop value (i.e either using the name, category, district props etc.). What should I do to filter using multiple conditions using? Just to remind you again, the selected options have been passed on as props to this component.
const FilterSearchButton = ({ name, category, district, status, serialNumber, setFilterButtonValue }) => {
const [multiFilter, setMultiFilter] = useState([]);
useEffect(() => {
setMultiFilter(dummyData.flatMap(value => value.ward_no.flatMap(
valueArray => ['grievances', 'general', 'urgent', 'services'].flatMap(
value => valueArray[value]))).filter(value => value.name === name ||
value.districtName === district ||
value.type === category ||
value.status === status ||
value.serial_number === serialNumber
)
)
}, [name, category, district, status, serialNumber, setFilterButtonValue]);
const searchFilter = () => {
setFilterButtonValue(multiFilter)
}
return (
<div className="searchFilterButton" onClick={searchFilter}>Search</div>
);
}
export default FilterSearchButton;
P.S: dummyData is a JSON file on which the filtering occurs. The ['grievances', 'general', 'urgent', 'services'] represents the keys over which the filtering occurs. An extract of the JSON data is below. I have removed most of the properties to keep them short.
[
{
"district": "Kolkata",
"ward_no": [
{
"ward": "6",
"grievance": [
{
"serial_number": "0001",
"name" : "Mr.A"
},
{
"serial_number": "0002",
"name" : "Mr.B"
}
],
"general": [
{
"serial_number": "0003",
"name" : "Mr.C"
},
{
"serial_number": "0004",
"name" : "Mr.D"
}
]
},
{
"ward": "7",
"grievance": [
{
"serial_number": "0005",
"name" : "Mr.E"
},
{
"serial_number": "0006",
"name" : "Mr.F"
}
],
"general": [
{
"serial_number": "0007",
"name" : "Mr.G"
},
{
"serial_number": "0008",
"name" : "Mr.H"
}
]
}
]
},
{
"district": "Hooghly",
"ward_no": [
{
"ward": "8",
"grievance": [
{
"serial_number": "0009",
"name" : "Mr.I"
},
{
"serial_number": "0010",
"name" : "Mr.J"
}
],
"general": [
{
"serial_number": "0011",
"name" : "Mr.K"
},
{
"serial_number": "0012",
"name" : "Mr.L"
}
]
},
{
"ward": "9",
"grievance": [
{
"serial_number": "0013",
"name" : "Mr.M"
},
{
"serial_number": "0014",
"name" : "Mr.N"
}
],
"general": [
{
"serial_number": "0015",
"name" : "Mr.O"
},
{
"serial_number": "0018",
"name" : "Bruno Fernandes"
}
]
}
]
}
]

