I have the following code below which displays records from an array and is working fine. now I want to add ability to search data
and I have added the following script to enable the search
filterRecord = record =>
record.name.toUpperCase().indexOf(this.state.searchdata.toUpperCase()) >
-1 ||
record.Age.indexOf(this.state.searchdata) > -1 ||
record.gender.toUpperCase().indexOf(this.state.searchdata.toUpperCase()) >
-1;
I have also tried
filterRecord = (record) => (record.name.indexOf(this.state.searchdata) > -1 ||
record.Age.indexOf(this.state.searchdata) > -1 ||
record.gender.indexOf(this.state.searchdata) > -1);
both code give error unexpected token pointing at equal to (=) at this line filterRecord =
here is the screenshot
Here is the full code
class Application extends React.Component {
constructor(props) {
super(props);
this.filterRecord = this.filterRecord.bind(this);
this.handleChange = this.handleChange.bind(this);
this.state = {
rec: [
{ name: "Tony", Age: "18", gender: "male" },
{ name: "John", Age: "21", gender: "female" },
{ name: "Luke", Age: "78", gender: "male" },
{ name: "Mark", Age: "90", gender: "female" },
{ name: "Jame", Age: "87", gender: "female" },
{ name: "Franco", Age: "34", gender: "male" },
{ name: "Franco", Age: "34", gender: "male" },
{ name: "Biggard", Age: "19", gender: "male" },
{ name: "tom", Age: "89", gender: "female" }
],
value: "",
searchdata: ""
};
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
filterRecord = record =>
record.name.toUpperCase().indexOf(this.state.searchdata.toUpperCase()) >
-1 ||
record.Age.indexOf(this.state.searchdata) > -1 ||
record.gender.toUpperCase().indexOf(this.state.searchdata.toUpperCase()) >
-1;
render() {
return (
<div>
<div>
<h3>Search/Filter Records by name, Age and gender</h3>
<input
type="text"
placeholder="Search by name, Age and gender"
id="searchdata"
name="searchdata"
type="text"
value={this.state.searchdata}
onChange={this.handleChange}
/>
<ul>
{this.state.rec.filter(this.filterRecord).map((obj, i) => (
<li key={i}>
{obj.name} - {obj.Age} - {obj.gender}
</li>
))}
</ul>
</div>
</div>
);
}
}
It works well.
I think you didn't install babel and es6/es2015.
class App extends React.Component {
constructor(props) {
super(props);
this.filterRecord = this.filterRecord.bind(this);
this.handleChange = this.handleChange.bind(this);
this.state = {
rec: [
{ name: "Tony", Age: "18", gender: "male" },
{ name: "John", Age: "21", gender: "female" },
{ name: "Luke", Age: "78", gender: "male" },
{ name: "Mark", Age: "90", gender: "female" },
{ name: "Jame", Age: "87", gender: "female" },
{ name: "Franco", Age: "34", gender: "male" },
{ name: "Franco", Age: "34", gender: "male" },
{ name: "Biggard", Age: "19", gender: "male" },
{ name: "tom", Age: "89", gender: "female" }
],
value: "",
searchdata: ""
};
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
filterRecord = record =>
(record.name.toUpperCase().indexOf(this.state.searchdata.toUpperCase()) >
-1 ||
record.Age.indexOf(this.state.searchdata) > -1 ||
record.gender.toUpperCase().indexOf(this.state.searchdata.toUpperCase()) >
-1);
render() {
return (
<div>
<div>
<h3>Search/Filter Records by name, Age and gender</h3>
<input
type="text"
placeholder="Search by name, Age and gender"
id="searchdata"
name="searchdata"
type="text"
value={this.state.searchdata}
onChange={this.handleChange}
/>
<ul>
{this.state.rec.filter(this.filterRecord).map((obj, i) => (
<li key={i}>
{obj.name} - {obj.Age} - {obj.gender}
</li>
))}
</ul>
</div>
</div>
);
}
}
ReactDOM.render( < App / > , document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
I might be silly here but i think your syntax for arrow function is wrong. You didnt wrap your function body in curly braces.
Try this:
filterRecord = (record) => {
return (record.name.toUpperCase().indexOf(this.state.searchdata.toUpperCase()) > -1 ||
record.Age.indexOf(this.state.searchdata) > -1 ||
record.gender.toUpperCase().indexOf(this.state.searchdata.toUpperCase()) > -1);
}
Hope this helps!!
Related
const data = [
{ id: 1, name: Mike, city: philps, state: New York },
{ id: 2, name: Steve, city: Square, state: Chicago },
{ id: 3, name: Jhon, city: market, state: New York },
{ id: 4, name: philps, city: booket, state: Texas },
{ id: 5, name: smith, city: brookfield, state: Florida },
{ id: 6, name: Broom, city: old street, state: Florida },
]
const tags = [
{ state: New York },
{ state: Texas },
{ state: Florida },
]
const [tags, setTgas] = useState(tags)
onChange={(e) => {
setTgas([...tags,{state: new_tag},]);
}
how can I get data by filtering using multiple tags? if i remove and add tag data will be displayed accordingly tags and is there is no tag all data will be displayed.
you can use array filter
const data = [
{ id: 1, name: "Mike", city: "philps", state: "New York" },
{ id: 2, name: "Steve", city: "Square", state: "Chicago" },
{ id: 3, name: "Jhon", city: "market", state: "New York" },
{ id: 4, name: "philps", city: "booket", state: "Texas" },
{ id: 5, name: "smith", city: "brookfield", state: "Florida" },
{ id: 6, name: "Broom", city: "old street", state: "Florida" },
]
const tags = [
{ state: "New York" },
{ state: "Texas" },
{ state: "Florida" },
]
const newTags = tags.map(item => item.state)
const newArr = data.filter(item => newTags.includes(item.state))
console.log(newArr)
I hope your logic to add and remove tags is already working as expected. Based on that your requirement can be fulfilled by following:
const data = [{
id: 1,
name: "Mike",
city: "philps",
state: "New York",
},
{
id: 2,
name: "Steve",
city: "Square",
state: "Chicago",
},
{
id: 3,
name: "Jhon",
city: "market",
state: "New York",
},
{
id: 4,
name: "philps",
city: "booket",
state: "Texas",
},
{
id: 5,
name: "smith",
city: "brookfield",
state: "Florida",
},
{
id: 6,
name: "Broom",
city: "old street",
state: "Florida",
},
]
const tags = [{
state: "New York"
},
{
state: "Texas"
},
{
state: "Florida"
},
]
/*
// Your react logic for adding and removing tags
const [tags, setTgas] = useState(tags)
onChange = {
(e) => {
setTgas([...tags, {
state: new_tag
}, ]);
};
*/
// Logic to display data based on filtered tags
const dataToDisplay = tags.length ? data.filter(item => tags.some(tag => tag.state === item.state)) : data;
console.log(dataToDisplay); //This will display all data when the tags is an empty array.
// Get a hook function
const {
useState,
useRef,
useEffect
} = React;
const Example = () => {
const data = [{
id: 1,
name: "Mike",
city: "philps",
state: "New York"
},
{
id: 2,
name: "Steve",
city: "Square",
state: "Chicago"
},
{
id: 3,
name: "Jhon",
city: "market",
state: "New York"
},
{
id: 4,
name: "philps",
city: "booket",
state: "Texas"
},
{
id: 5,
name: "smith",
city: "brookfield",
state: "Florida"
},
{
id: 6,
name: "Broom",
city: "old street",
state: "Florida"
},
];
const [FilteredData, setFilteredData] = useState([]);
const [Tags, setTags] = useState([]);
const selectRef = useRef();
useEffect(() => {
if (Tags.length !== 0) {
setFilteredData(data.filter(item => Tags.includes(item.state)))
} else {
setFilteredData([...data]);
}
}, [Tags]);
const OnAddTag = () => {
if (!Tags.includes(selectRef.current.value)) {
setTags((prev) => [...prev, selectRef.current.value]);
}
};
const OnRemoveTag = () => {
const tags = [...Tags]
const index = tags.indexOf(selectRef.current.value)
if (index > -1) {
tags.splice(tags.indexOf(selectRef.current.value), 1)
}
setTags(tags)
};
const List = FilteredData.map((item) => < li key = {
item.id
} > {
`${item.name} - ${item.state}`
} < /li>);
return ( <
div >
<
div >
<
button onClick = {
OnAddTag
} > Add < /button> <
select ref = {
selectRef
} >
<
option > select < /option> <
option value = {
"New York"
} > New York < /option> <
option value = {
"Texas"
} > Texas < /option> <
option value = {
"Florida"
} > Florida < /option> < /
select >
<
button onClick = {
OnRemoveTag
} > Remove < /button> < /
div >
<
div > Tags = [{
Tags
}] < /div> <
ul > {
List
} < /ul> < /
div >
);
};
// Render it
ReactDOM.createRoot(
document.getElementById("root")
).render( <
Example / >
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
var namePerson = [{ name: "Andi", age: "25", hobbies: ["Soccer", "Badminton"],},
{ name: "Robert", age: "25", hobbies: ["Read", "Swim", "Soccer"],},
{ name: "Julia", age: "28", hobbies: ["Music", "Swim"],},];
var arrayPersonFilter = namePerson.filter(function (item) { return item.age == 25;});
var arrayPersonFilter2 = namePerson.filter(function (item) { return item.hobbies == Music";
});
console.log("==========Age============");
console.log(arrayPersonFilter);
console.log("==========Hobbies============");
console.log(arrayPersonFilter2);
I can't filter hobbies with the same method that age filterthis is a result
To filter from an array you can use array.includes. Also, you can use arrow functions here to make it slimmer, easier to read and best practices.
let arrayPersonFilter = namePerson.filter(item => item.age == 25);
let arrayPersonFilter2 = namePerson.filter(item => item.hobbies.includes("Music"));
let namePerson = [{
name: "Andi",
age: "25",
hobbies: ["Soccer", "Badminton"],
},
{
name: "Robert",
age: "25",
hobbies: ["Read", "Swim", "Soccer"],
},
{
name: "Julia",
age: "28",
hobbies: ["Music", "Swim"],
},
];
let arrayPersonFilter = namePerson.filter(item => item.age == 25);
let arrayPersonFilter2 = namePerson.filter(item => item.hobbies.includes("Music"));
console.log("==========Age============");
console.log(arrayPersonFilter);
console.log("==========Hobbies============");
console.log(arrayPersonFilter2);
age is a value, hobbies is an array, so you need to do some check on the items in the array, maybe something like this. Not sure if includes is the right function, but hope it makes sense.
var arrayPersonFilter2 = namePerson.filter(function (item) { return
item.hobbies.includes("Music");
});
So I made an array of object and map the array. I also make a simple collapsible.
The thing is, the collapsible didn't work correctly. It should only show the content where the user clicked on. i.e. when the user click the button belongs to John Doe, the collapsible should show the status belongs to him. What happen to my code is, it shows everyone's status. I have tried with key={index} but still no result.
Here's my code so far...
import { useState } from "react";
const App = () => {
const [showCollapsible, setShowCollapsible] = useState(false);
const myDatas = [
{
id: 1,
fullName: "John Doe",
age: 28,
status: "On Duty",
},
{
id: 2,
fullName: "Jane Doe",
age: 27,
status: "Rest",
},
{
id: 3,
fullName: "James Doe",
age: 32,
status: "Take a leave",
},
];
return (
<div>
{myDatas.map((data, index) => {
return (
<div>
<p>{data.fullName}</p>
<p>{data.age}</p>
<button
key={index}
onClick={() => setShowCollapsible(!showCollapsible)}
>
Status
</button>
{showCollapsible && <div>{data.status}</div>}
</div>
);
})}
</div>
);
};
export default App;
You are using the same single boolean state to toggle all of the collapsible divs. Instead, store some state that uniquely identifies a mapped element, like the data's id property. Use the id to check if the div should be collapsed or visible.
const App = () => {
const [showCollapsible, setShowCollapsible] = useState({});
const myDatas = [
{
id: 1,
fullName: "John Doe",
age: 28,
status: "On Duty"
},
{
id: 2,
fullName: "Jane Doe",
age: 27,
status: "Rest"
},
{
id: 3,
fullName: "James Doe",
age: 32,
status: "Take a leave"
}
];
const toggleCollapsable = (id) => () => {
setShowCollapsible((set) => ({
...set,
[id]: !set[id]
}));
};
return (
<div>
{myDatas.map((data) => {
return (
<div>
<p>{data.fullName}</p>
<p>{data.age}</p>
<button onClick={toggleCollapsable(data.id)}>Status</button>
{showCollapsible[data.id] && <div>{data.status}</div>}
</div>
);
})}
</div>
);
};
It would be a little more clean to abstract a Collapsible component that manages that state.
const CollapsibleDiv = ({ children }) => {
const [showCollapsible, setShowCollapsible] = useState(false);
return (
<>
<button onClick={() => setShowCollapsible((show) => !show)}>
Status
</button>
{showCollapsible && children}
</>
);
};
const App = () => {
const myDatas = [
{
id: 1,
fullName: "John Doe",
age: 28,
status: "On Duty"
},
{
id: 2,
fullName: "Jane Doe",
age: 27,
status: "Rest"
},
{
id: 3,
fullName: "James Doe",
age: 32,
status: "Take a leave"
}
];
return (
<div>
{myDatas.map((data) => {
return (
<div>
<p>{data.fullName}</p>
<p>{data.age}</p>
<CollapsibleDiv>
<div>{data.status}</div>
</CollapsibleDiv>
</div>
);
})}
</div>
);
};
I do have a problem on my code. What I am trying to do, is that when I want to click on a button, I want that this button become "HIDE" (it's show in the beginning), and show the specific Id's information. I tryed to do it with many example but the others buttons change this specific button too. Then, I didn't find the issue. If someone can help me with it. Thank you very much.
import React, { Component } from "react";
import "./IlkOnbir.css";
export default class IlkOnbir extends Component {
state = {
info: false,
btn: true,
players: [
{
id: 1,
name: "Altay Bayindir",
age: "21",
mevki: "Kaleci",
},
{
id: 2,
name: "Serdar Aziz",
age: "29",
mevki: "Stoper",
},
{
id: 3,
name: "Simon Falette",
age: "23",
mevki: "Stoper",
},
{
id: 4,
name: "Nabil Dirar",
age: "33",
mevki: "Sag Bek",
},
{
id: 5,
name: "Hasan Ali Kaldirim",
age: "32",
mevki: "Sol Bek",
},
{
id: 6,
name: "Emre Belözoglu",
age: "37",
mevki: "Orta Saha",
},
{
id: 7,
name: "Luiz Gustavo",
age: "32",
mevki: "Orta Saha",
},
{
id: 8,
name: "Ozan Tufan",
age: "25",
mevki: "Orta Saha",
},
{
id: 9,
name: "Deniz Türüç",
age: "28",
mevki: "Orta Saha",
},
{
id: 10,
name: "Gary Rodriguez",
age: "29",
mevki: "Kanat",
},
{
id: 11,
name: "Tolga Cigerci",
age: "29",
mevki: "Orta Saha",
},
{
id: 12,
name: "Ferdi",
age: "21",
mevki: "Stoper",
},
{
id: 13,
name: "Mevlüt",
age: "33",
mevki: "Stoper",
},
{
id: 14,
name: "Vedat",
age: "26",
mevki: "Stoper",
},
],
}
showInfo = (i) => {
this.setState({ info: !this.state.info});
}
handleClick = event => {
event.currentTarget.classList.toggle('active');
}
btnDisplay = (e) => {
console.log(e.currentTarget.id);
this.setState({info: !this.state.info, btn:!this.state.btn});
}
render() {
const hideInfo = this.state.info;
const pl = this.state.players.map((player,i) => {
return (
<div key={i} className="card--content movie" onClick={this.handleClick}>
<div className="content">
<img src={player.source} alt="" />
<div class="buttons">
<p
onClick={() => this.showInfo(player[i])} key={player[i]} className="btn effect04 movie" data-sm-link-text="INFO"><span>{this.state.btn === true ? "SHOW" : "HIDE"}</span>
</p>
{hideInfo === true ? (
<div className="opening">
<p>{player.name}</p>
<p>{player.age} </p>
<p>{player.mevki} </p>
</div>
) : (
""
)}
</div>
</div>
</div>
)})
return (
<div className="container">
<section className="card">
{pl}
</section>
</div>
)}}
Each player needs its own info property; right now info applies to all of them.
See working example:
https://codesandbox.io/s/sweet-jang-m3yfe?file=/src/App.js
{
id: 1,
name: "Altay Bayindir",
age: "21",
mevki: "Kaleci",
info: false
}
showInfo = i => {
this.setState(state => ({
...state,
players: state.players.map((player, index) =>
index === i ? { ...player, info: !player.info } : player
)
}));
};
onClick={() => this.showInfo(i)}
{player.info && (
<div className="opening">
<p>{player.name}</p>
<p>{player.age} </p>
<p>{player.mevki} </p>
</div>
)}
Here is my sample response:
var jsonData1 = [{
firstName: "Sam",
age: "10"
}, {
firstName: "John",
age: "11"
}, {
firstName: "Jack",
age: "12"
}, {
firstName: "Pam",
age: "13"
}, {
firstName: "",
age: "14"
}, {
firstName: "Mitch",
age: ""
}];
All I want is, wherever I have a blank string in any field, to show it as zero. I want to do it using plain JS, no lodash, no jQuery.
Assuming the given data structure, I'd approach it like this:
loop through the elements in the array with Array.forEach()
loop through the properties in the element with Object.keys(person).forEach()
check for emptystring and replace
Like this:
jsonData1.forEach(person => {
Object.keys(person).forEach(key => {
if (person[key] === "") person[key] = "-";
});
});
You can write this in one line of code:
jsonData1.forEach(o => Object.keys(o).forEach(key => o[key] === '' && (o[key] = '-')))
Using forEach loop
var jsonData1 = [
{
firstName: "Sam",
age: "10"
},
{
firstName: "John",
age: "11"
},
{
firstName: "Jack",
age: "12"
},
{
firstName: "Pam",
age: "13"
},
{
firstName: "",
age: "14"
},
{
firstName: "Mitch",
age: ""
}
];
jsonData1.forEach((e)=>{Object.keys(e).forEach((x)=>e[x]==""?e[x]=0:false)})
console.log(jsonData1)
That should do the trick for nested objects:
const convertObj = obj => {
Object.keys(obj).forEach(key => {
if (obj[key] === '') {
obj[key] = 0
} else if (obj[key] instanceof Object) {
convertObj(obj[key])
}
})
return obj
}
Sample test:
const jsonData1 = [
{
firstName: "Mitch",
age: "",
nested_test: [
{
foo: 'bar',
age: ''
}
],
nested_object: {
foo: 'bar',
age: ''
}
}
]
Result:
[
{
"firstName": "Mitch",
"age": 0,
"nested_array": [
{
"foo": "bar",
"age": 0
}
],
"nested_object": {
"foo": "bar",
"age": 0
}
}
]
As you do have an array, you can simply iterate over it:
for (var i=0;i<jsonData1.length;i++) {
if (jsonData1[i].age==="")
jsonData1[i].age = 0;
if (jsonData1[i].firstName==="")
jsonData1[i].firstName = "Unknown";
}
You can use for...of
The for...of statement creates a loop iterating over iterable objects, including: built-in String, Array, Array-like objects (e.g., arguments or NodeList), TypedArray, Map, Set, and user-defined iterables.
var jsonData1 = [{
firstName: "Sam",
age: "10"}, {
firstName: "John",
age: "11"},{
firstName: "Jack",
age: "12"},{
firstName: "Pam",
age: "13"},{
firstName: "",
age: "14"},{
firstName: "Mitch",
age: ""
}];
for(var p of jsonData1){
if(p.firstName.trim()=="") p.firstName="0";
if(p.age.trim()=="") p.age="0"
}
console.log(jsonData1);
Try this
let newData = jsonData1.forEach(function(data) {
for(ans in data) {
If(data[ans] === "") data[ans] = 0;
}
});
jsonData1 = jsonData1.map(item=>{
for(let key in item){
if(item[key].length === 0) item[key] = 0;
}
return item;
})
With Simple Loop
for(let i = 0; i<data.length;i++){
let keys = Object.keys(data[i]); //returns an array of keys of object
for(let key = 0;key<keys.length;key++){
let keyName = keys[key];
if(data[i][keyName].length === 0) data[i][keyName] = 0
}
}