I want to create a search filter for my data array.it has multiple objects and keys like this one,
[
{
\"fname\": \"Jayne\",
\"lname\": \"Was
Search filter for multiple objects key values and also highlights the search terms
Implemented two functions - highlighter
and filterHandler
.
filterHandler
function filters the data based on the input given and then it sends the filtered data to highlighter function for highlighting.
highlighter
function takes two arguments obj and input and it returns highlightable HTML code as a string.
class App extends React.Component {
state = {
input: "",
fData: [{
fname: "Jayne",
lname: "Washington",
email: "jaynewashington@exposa.com",
gender: "female"
},
{
fname: "Peterson",
lname: "Dalton",
email: "petersondalton@exposa.com",
gender: "male"
},
{
fname: "Velazquez",
lname: "Calderon",
email: "velazquezcalderon@exposa.com",
gender: "male"
},
{
fname: "Norman",
lname: "Reed",
email: "normanreed@exposa.com",
gender: "male"
}
],
data: [{
fname: "Jayne",
lname: "Washington",
email: "jaynewashington@exposa.com",
gender: "female"
},
{
fname: "Peterson",
lname: "Dalton",
email: "petersondalton@exposa.com",
gender: "male"
},
{
fname: "Velazquez",
lname: "Calderon",
email: "velazquezcalderon@exposa.com",
gender: "male"
},
{
fname: "Norman",
lname: "Reed",
email: "normanreed@exposa.com",
gender: "male"
}
]
};
handleChange = event => {
this.setState({
input: event.target.value
}, this.filterHandler);
};
highlighter = (obj, lowercasedInput) => {
let rawObj = obj.replace(``, '').replace(``, '');
if (rawObj.indexOf(lowercasedInput) != -1) {
const startIndex = rawObj.indexOf(lowercasedInput);
const endIndex = startIndex - 1 + lowercasedInput.length;
if (startIndex != 0) {
return rawObj.slice(0, startIndex) + `${lowercasedInput}` + rawObj.slice(endIndex + 1, rawObj.length);
} else {
return rawObj.slice(0, startIndex) + `${lowercasedInput}` + rawObj.slice(endIndex + 1, rawObj.length);
}
} else {
return rawObj
}
}
filterHandler = () => {
const {
input,
data
} = this.state;
const lowercasedInput = input.toLowerCase();
const filteredData = data.filter(item => {
return Object.keys(item).some(key =>
item[key].toLowerCase().includes(lowercasedInput)
);
});
let highlightFD = [];
filteredData.map((values, index) => {
highlightFD.push({ ...values
});
})
if (lowercasedInput.trim().length > 0) {
highlightFD.map((val, index) => {
for (let key in val) {
highlightFD[index][key] = this.highlighter(val[key].toLowerCase(), lowercasedInput);
}
});
}
this.setState({
fData: highlightFD
});
}
render() {
const {
input,
fData
} = this.state;
return ( <
div >
<
input value = {
input
}
onChange = {
this.handleChange
}
/> {
fData.map(item => (
|
|
|
))
}
.results {
display: flex
}
span {
background-color:black;
color:white;
}
Note: dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack.
To read more: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
Using Regular expressions :
class App extends React.Component {
state = {
input: "",
fData: [{
fname: "Jayne",
lname: "Washington",
email: "jaynewashington@exposa.com",
gender: "female"
},
{
fname: "Peterson",
lname: "Dalton",
email: "petersondalton@exposa.com",
gender: "male"
},
{
fname: "Velazquez",
lname: "Calderon",
email: "velazquezcalderon@exposa.com",
gender: "male"
},
{
fname: "Norman",
lname: "Reed",
email: "normanreed@exposa.com",
gender: "male"
}
],
data: [{
fname: "Jayne",
lname: "Washington",
email: "jaynewashington@exposa.com",
gender: "female"
},
{
fname: "Peterson",
lname: "Dalton",
email: "petersondalton@exposa.com",
gender: "male"
},
{
fname: "Velazquez",
lname: "Calderon",
email: "velazquezcalderon@exposa.com",
gender: "male"
},
{
fname: "Norman",
lname: "Reed",
email: "normanreed@exposa.com",
gender: "male"
}
]
};
handleChange = event => {
this.setState({
input: event.target.value
}, this.filterHandler);
};
highlighter = (obj, lowercasedInput) => {
let rawObj = obj.replace(``, '').replace(``, '');
if (rawObj.indexOf(lowercasedInput) != -1) {
const startIndex = rawObj.indexOf(lowercasedInput);
const endIndex = startIndex - 1 + lowercasedInput.length;
if (startIndex != 0) {
return rawObj.slice(0, startIndex) + `${lowercasedInput}` + rawObj.slice(endIndex + 1, rawObj.length);
} else {
return rawObj.slice(0, startIndex) + `${lowercasedInput}` + rawObj.slice(endIndex + 1, rawObj.length);
}
} else {
return rawObj
}
}
filterHandler = () => {
const {
input,
data
} = this.state;
const lowercasedInput = input.toLowerCase();
const filteredData = data.filter(item => {
return Object.keys(item).some(key =>{
const regex= new RegExp(`^${lowercasedInput.trim()}`,'i');
return regex.test(item[key].toLowerCase()) ;
}
);
});
let highlightFD = [];
filteredData.map((values, index) => {
highlightFD.push({ ...values
});
})
if (lowercasedInput.trim().length > 0) {
highlightFD.map((val, index) => {
for (let key in val) {
highlightFD[index][key] = this.highlighter(val[key].toLowerCase(), lowercasedInput);
}
});
}
this.setState({
fData: highlightFD
});
}
render() {
const {
input,
fData
} = this.state;
return ( <
div >
<
input value = {
input
}
onChange = {
this.handleChange
}
/> {
fData.map(item => (
|
|
|
))
}
.results {
display: flex
}
span {
background-color:black;
color:white;
}