React-js-todo-list-sortable(3)

Building a Todo app with React.js (3) - Adding Filters for Search and showing complete/incompleted tasks

TodoListApp

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
TodoListApp
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

##Building a Todo app with React.js (3) - Adding Filters for Search and showing complete/incompleted tasks

##Building a Todo app with React.js (4) - Multiple Todos

##Building a Todo app with React.js (5) - Sort item