React search function
Basically what my code is doing is displaying a list of tables with a lookup table at the top that filters the list as you enter a value. At the moment, the problem with my code is adding an if statement to the DisplayTable component. I don't want it to display all saved data, but just display the ones that were entered by the user in the {queryText} search bar
Please ignore the tableData variable p>
var InstantBox = React.createClass({
doSearch:function(queryText){
console.log(queryText)
//get query result
var queryResult=[];
this.props.data.forEach(function(person){
if(person.name.toLowerCase().indexOf(queryText)!=-1)
queryResult.push(person);
});
this.setState({
query:queryText,
filteredData: queryResult
})
},
getInitialState:function(){
return{
query:'',
filteredData: this.props.data
}
},
render:function(){
return (
<div className="InstantBox">
<h2>Who is Richer?</h2>
<SearchBox query={this.state.query} doSearch={this.doSearch}/>
<DisplayTable data={this.state.filteredData}/>
</div>
);
}
});
var SearchBox = React.createClass({
doSearch:function(){
var query=this.refs.searchInput.getDOMNode().value; // this is the search text
this.props.doSearch(query);
},
render:function(){
return <input className="searchbar-edit" type="text" ref="searchInput" placeholder="Search Name" value={this.props.query} onChange={this.doSearch}/>
}
});
var DisplayTable = React.createClass({
doSearch:function(queryText){
console.log(queryText)
//get query result
var queryResult=[];
this.props.data.forEach(function(person){
if(person.name.toLowerCase().indexOf(queryText)!=-1)
queryResult.push(person);
});
this.setState({
query:queryText,
filteredData: queryResult
})
},
render:function(){
//making the rows to display
var rows=[];
this.props.data.forEach(function(person) {
rows.push(<tr><td>{person.image}</td></tr>)
rows.push(<tr><td>{person.name}</td></tr>)
});
//returning the table
return(
<table>
<tbody>{rows}</tbody>
</table>
);
}
});
var tableData=[
{
name:'Paul mak',
image: <img width="50" src="./images/profile_img.png"/>,
},
];
var dataSource=[
{
name:'Paul mak',
image: <img width="50" src="./images/profile_img.png"/>,
},
{
name:'John Doe',
image : '002'
},
{
name:'Sachin Tendulkar',
image : '003'
}];
React.render(
<InstantBox data={dataSource}/>,
document.getElementById('content1')
);
source to share
Try something like this:
var InstantBox = React.createClass({
doSearch:function(queryText){
console.log(queryText)
//get query result
var queryResult=[];
this.props.data.forEach(function(person){
if(person.name.toLowerCase().indexOf(queryText)!=-1)
queryResult.push(person);
});
this.setState({
query:queryText,
filteredData: queryResult
})
},
getInitialState:function(){
return{
query: '',
filteredData: undefined
}
},
renderResults: function() {
if (this.state.filteredData) {
return (
<DisplayTable data={this.state.filteredData}/>
);
}
},
render:function(){
return (
<div className="InstantBox">
<h2>Who is Richer?</h2>
<SearchBox query={this.state.query} doSearch={this.doSearch}/>
{this.renderResults()}
</div>
);
}
});
What I changed from your code, I changed this.state.filteredData
to undefined (in fact, you could just remove it completely, but I thought it was clearer for you right now) in your initial state. So when you first render the field, it is not there filteredData
and yours is <DisplayTable />
not rendering. Once you run the callback doSearch
with <SearchBox />
, it will populate filteredData
and display it.
To expand on this, you can also check when this.state.query
is undefined again or empty (for example with:) this.state.query.length
to remove <DisplayTable />
from the dom again if no query / no results.
Remember, functions render
are still just javascript. Anything you complete in {}
within JSX will be appreciated. We could just use this logic inside a function render
and do something like var displayTable = <DisplayTable />;
and then include {displayTable}
in the returned JSX and it would be the same. Personally, I just prefer to split the resulting logic between different functions :)
source to share