React Getting Started practice todolist: adding events and Search boxes

Source: Internet
Author: User
Tags bind


In the previous article, we implemented a todolist using react to display a list of basic TODO items, and today we continue to add features such as selecting a Todoitem checkbox to change its completion status, adding a search box, You can filter multiple data by entering keywords in the search box.
We still make changes on the basis of the original, the following is the latest ToDoList module:


var todolist = React.createclass ({
  getinitialstate:function () {
    return {
      data: []
    };
  },
  Componentdidmount:function () {
    var mockdata = [
      {id:1, Name: "Report of the updates to Boss", Time: "" "},
      {i D:2, Name: "Stand-up Meeting", Time: "10:00am"},
      {id:3, Name: "Draw up a plan for next step", Time: "11:00am"}
    ];this.setstate ({
      data:mockdata
    });
  },
  render:function () {
    var todoitems = This.state.data.map (function (TODO) {
      return (
        //passing the whole Todo object as a property
        <todoitem Key={todo.id} todo={todo}/>
      )
    ;

    Return (
      <div classname= "todolist" >{todoItems}</div>
    );
  }
);


In the above code, we improved the way the Todoitem property is passed, directly providing a TODO data object as a property to Todoitem, which is more beneficial to data processing in the development process. Next, we also want to improve the Todoitem module, the code is as follows:


var TodoItem = React.createClass({
  //will be called after clicking the checkbox
  handleClick: function(event) {
    var todoData = this.props.todo;

    todoData.hasDone = !todoData.hasDone;

    //re-render the view
    this.setState({
      hasDone: todoData.hasDone
    });

    //Ajax handling maybe
    //updateTodo(this.props.todo);
  },
  getInitialState: function() {
    return {
      hasDone: false
    };
  },
  componentDidMount: function() {
    this.setState({
      hasDone: this.props.todo.hasDone
    });
  },
  render: function() {
    var classList = ['todoItem'];
    this.state.hasDone && classList.push('hasDone');  //add a 'hasDone' class after checkbox is checked
    var classNames = classList.join(' ');

    return (
      //adding 'onClick' property on checkbox to bind a click handler
      <div className={classNames}>
        <input type="checkbox" onClick={this.handleClick} checked={this.props.todo.hasDone}/>
        <div className="name">{this.props.todo.name}</div>
        <div className="time">{this.props.todo.time}</div>
      </div>
    );
  }
});


This part of the change is more, we carefully analyze each part of the function.
The first is the Getinitialstate section, we add the initial state, Hasdone indicates whether a backlog is complete, the initial value is false, and then in the Componentdidmount function, we re-set the state based on the data passed in from the upper layer. This state will eventually work in the Render method.
In the Render method we will first determine if the TODO is complete, and if it is done, add a hasdone classname to it and eventually display a different style in the page. Then we declare the checked property for the. CheckBox, which displays the selected state based on the Hasdone in the data, which means that if a todo is completed, the checkbox is selected when the page is initialized.
Finally, we bind a click event for the checkbox, and when it is clicked, the Handleclick function is triggered, in which we get the latest Hasdone value and reset the state update view. In actual development we also need to do some AJAX operations to request the server to change the values in the database.
Finally, we add a hasdone corresponding to the style:


. todoitem.hasdone > div {
    text-decoration:line-through;
}


Now let's take a look at the final page effect, as shown in the figure, when we click on the first todoitem to look like this:

We have successfully added a click event, we also need to add a filtering function for this todolist, first create a searchbox module:


var searchbox = React.createclass ({
  render:function () {
    return (
      <div classname= "SearchBox" >
        <input type= "text" placeholder= "type in keywords to search"/>
      </div>
    );
  }
);


Then declare the corresponding CSS style:


. searchbox {
    width:400px;
    height:100%;
    margin:0 auto;
}
. SearchBox input {
    width:100%;
    height:30px;
    Border:none;
    padding:5px 15px;
    border-radius:2px;
    font-size:14px;
}


Finally, you need to add the searchbox to the Render method of the ToDoList module:


Render:function () {
    var todoitems = this.state.data.map (function (TODO) {
      return (
        <todoitem key={ Todo.id} todo={todo}/>
      )
    ;

    Return (
      <div classname= "ToDoList" >
        <SearchBox/>
        {todoitems}
      </div>
    ) ;
  }


You can now preview the page effect:

The next step is to add event handling for searchbox, and we need to think about how to associate the input in the text box with the Todoitems. First, to filter the dataset, a variable representing the search keyword must be defined in the ToDoList module to manipulate the dataset, and then the keyword here is searchbox provided, Therefore, the SearchBox module in the text box data changes must inform the ToDoList module, do the next processing.
Now let's modify the code for ToDoList:


var TodoList = React.createClass({
  handleSearchTextUpdate: function(searchText) {
    this.state.searchText = searchText;
    this.setState(this.state);
  },
  getInitialState: function() {
    return {
      data: [],
      searchText: ''  //adding a searchText, it will be used in render method
    };
  },
  componentDidMount: function() {
    var mockData = [
      {id: 1, name: "report the updates to Boss", time: "9:30"},
      {id: 2, name: "Stand-up meeting", time: "10:00"},
      {id: 3, name: "Draw up a plan for next step", time: "11:00"}
    ];

    this.state.data = mockData;

    this.setState(this.state);
  },
  render: function() {
    var state = this.state;

    //filter the data first and then call map function
    var todoItems = state.data.filter(function(todo) {
      return todo.name.toLowerCase().indexOf(state.searchText.toLowerCase()) > -1;
    }).map(function(todo) {
      return (
        <TodoItem key={todo.id} todo={todo}/>
      );
    });

    return (
      //adding a 'onSearchTextUpdate' callback, it will be called when text changes in search input
      <div className="todoList">
        <SearchBox onSearchTextUpdate={this.handleSearchTextUpdate}/>
        {todoItems}
      </div>
    );
  }
});


As you can see, in the Getinitialstate method, we add a SearchText value to represent the filtered keyword, and then in the Render method, we use the filter function to filter the dataset. SearchText is the time to play its part. Then in the SearchBox declaration we added the Onsearchtextupdate property as the callback function after the search text changed, it actually executes the handlesearchtextupdate function, and then sets the new SearchText, Then reset the state to refresh the view.
So in the SearchBox module, what we need to do is listen to the input changes in the text box, and then call the above mentioned callback function, the latest input to pass up, to look at the modified code:


var searchbox = React.createclass ({
  handlechange:function (event) {
    var newinput = event.target.value;

    Call the onsearchtextupdate in props
    this.props.onSearchTextUpdate (newinput);
  },
  render:function () {
    return (
      //adding a ' onChange ' to monitor the value changes
      <div classname= "SearchBox" >
        < Input type= "text" Onchange={this.handlechange} placeholder= "type in keywords to search"/>
      </div>
    ) ;
  }
});

The

Filtering function is only the interaction between ToDoList and SearchBox, Todoitem does not need any changes, so just understand the interaction between SearchBox and ToDoList, you can quickly implement a filtering function, the following is our final page effect:

If you are a angular enthusiast, you may feel that the react use will be more around, then you need to carefully study the entire implementation process, perhaps you will be a little bit like it ~


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.