Building a Todo app with React.js (3) - Adding Filters for Search and showing complete/incompleted tasks
If we have a lot of todos, it becomes difficult to search through them and to find a particular todo. It also becomes easier to see all the completed and incompleted tasks at once.
- TODO APP
- TODO BANNER
- TODO FILTER
- TODO FORM
- TODO LIST
- TODO LIST ITEM #1
- TODO LIST ITEM #2
...
- TODO LIST ITEM #n
Component 1 - ToDo Filter
This component contains the filter and search bar. Following is the code for Filter Component.
var ToDoFilter = React.createClass({
isActive:function(value){
return 'btn '+((value===this.props.filter[0].Status) ?'btn-primary':'default');
},
render: function(){
var onFilter1 = this.props.onFilter;
var onSearch1 = this.props.onSearch;
return(
<div className="row">
<div className="col-xs-7">
<div id="todo-filter" className="input-group">
<span className="input-group-btn">
<button className="btn btn-default" type="button"><span className="glyphicon glyphicon-search"></span></button>
</span>
<input type="search" className="form-control" ref='filter' onChange={onSearch1} placeholder="Search" ></input>
</div>
</div>
<div className="col-xs-5">
<ul className="nav nav-pills todo-filter">
<li><a onClick={onFilter1} className={this.isActive('SHOW_ALL')} value="SHOW_ALL" href="#">All</a></li>
<li><a onClick={onFilter1} className={this.isActive('false')} value="false">Incomplete</a></li>
<li><a onClick={onFilter1} className={this.isActive('true')} value="true">Complete</a></li>
</ul>
</div>
</div>
);
}
});
Component 2 - ToDoApp
In ToDoApp, we create filterItem function and searchItem function to save input value and then add ToDoFilter into render function.
Here’s the code :
filterItem : function(e){
this.state.filter[0].Status = e.target.value;
this.setState({
filter: this.state.filter
});
},
searchItem : function(e){
this.state.filter[0].keyword = e.target.value;
this.setState({
filter: this.state.filter
});
},
render: function(){
return (
<div>
<ToDoBanner/>
<ToDoFilter onFilter = {this.filterItem} onSearch = {this.searchItem} filter={this.state.filter}/>
<ToDoForm onFormSubmit={this.updateItems} />
<ToDoList items={this.state.items} filter = {this.state.filter} onDelete={this.deleteItem} />
</div>
);
}
Component 3 - ToDoList
Filter the todo list based on user input. I use the filter Method to filter todo list.
I use the indexOf() Method to implement Searching function. The indexOf() method return -1 if the keyword to search for never occurs.
render: function() {
var createItem = function(itemText,i) {
return (
<ToDoListItem key={i} value={i} onRemove = {this.Remove}>{itemText}</ToDoListItem>
);
};
// Here is the filter function
var allitems = this.props.items;
var status = this.props.filter[0].Status;
switch (status){
case 'false':
allitems = allitems.filter(t => !t.isDone)
break;
case 'true':
allitems = allitems.filter(t => t.isDone)
};
// Here is the search function
var queryText = this.props.filter[0].keyword;
if(queryText){
var queryResult=[];
allitems.forEach(function(item){
if(item.item.toLowerCase().indexOf(queryText)!=-1)
queryResult.push(item);
});
return <ul>{queryResult.map(createItem,this)}</ul>;
}
return <ul>{allitems.map(createItem,this)}</ul>;
}
You should now have following screenshot
The complete working demo can be found here .
##Building a Todo app with React.js (1) - A simple todos list
##Building a Todo app with React.js (2) - Improve Component & Remove Component