1

Here in my app upon clicking edit button a input field appears with save button. Basically its an todo app. What I'm trying to do is edit the entered value. When i click edit button the value of the corresponding todo should be stored in input field that i want to edit. I'm facing problem in storing respective value. My code goes like this:

    class App extends React.Component {

  

constructor(){
  super();
  this.state={
    todo:[],
     editing:false
  };
};

entertodo(keypress){
  var Todo=this.refs.inputodo.value;
  if( keypress.charCode == 13 )

  {
    this.setState({
      todo: this.state.todo.concat({Value:Todo, checked:false})
    });
    this.refs.inputodo.value=null;
  };
};
todo(todo,i){
  return (
    <li className={todo.checked===true? 'line':'newtodo'}>
      <div onClick={this.todoCompleted.bind(this, i)}>
        <input type="checkbox" className="option-input checkbox" checked={todo.checked} />
        <button onClick={this.edit.bind(this,i)}>edit</button>
        <div key={todo.id}  className="item">
          {todo.Value}
          <span className="destroy" onClick={this.remove.bind(this, i)}>X</span>

        </div>
      </div>
    </li>
  );
};

remove(i){
  this.state.todo.splice(i,1)
  this.setState({todo:this.state.todo})
};
todoCompleted(i){
   var todo=this.state.todo;
   todo[i].checked =todo[i].checked? false:true;
     this.setState({
       todo:this.state.todo
     });

 };
allCompleted=()=>{
  var todo = this.state.todo;
  var _this = this
  todo.forEach(function(item) {
    item.className = _this.state.finished ? "newtodo" : "line"
    item.checked = !_this.state.finished
  })
  this.setState({todo: todo, finished: !this.state.finished})
};
edit(i){
  var todo= this.state.todo
  this.setState({
    editing:true
  });
};
save(i){
  this.setState({
    editing:false
  });
};
  rendernormal() {
  return (
      <div>
        <h1 id='heading'>todos</h1>
        <div className="lines"></div>
        <div>
          <input type="text" ref= "inputodo" onKeyPress={this.entertodo.bind(this)}className="inputodo"placeholder='todos'/>
          <span onClick={this.allCompleted}id="all">^</span>

        </div>
        <div className="mainapp">
          <ul className="decor">
            {this.state.todo.map(this.todo.bind(this))}
          </ul>
        </div>
      </div>
    );
  };
  renderform(todo,i) {
  return (
    <div>
      <h1 id='heading'>todos</h1>
      <div className="lines"></div>
      <div>
        <input type="text" ref= "inputodo" value={this.props.todo} placeholder='EDIT TODO'/>
        <span onClick={this.allCompleted}id="all">^</span>
        <button onClick={this.save.bind(this)}>save</button>
      </div>
      <div className="mainapp">
        <ul className="decor">
          {this.state.todo.map(this.todo.bind(this))}
        </ul>
      </div>
    </div>
    );
  };
  render(){
    if (this.state.editing) {
      return this.renderform()
    }
    else {
    return this.rendernormal()
    }
  };
}
 

ReactDOM.render(<App/>,document.getElementById('app'));
    .line {
  text-decoration: line-through;
  color: red;
}
.newtodo{
  text-decoration: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="app"></div>

1 Answer 1

1

You can store "current value" in the component state, and pass it to form's input. When toggling edit mode, just update state's value. Try:

NOTE:

I've used a "hacky" way to clone the array of objets from the state for immutability. You'd better use more advanced tools like this.

    class App extends React.Component {

  

constructor(){
  super();
  this.state={
    todo:[],
    editing:false,
    value: '',
    current: null, 
  };
};

entertodo(keypress){
  var Todo=this.refs.inputodo.value;
  if( keypress.charCode == 13 )

  {
    this.setState({
      todo: this.state.todo.concat({Value:Todo, checked:false})
    });
    this.refs.inputodo.value=null;
  };
};
todo(todo,i){
  return (
    <li className={todo.checked===true? 'line':'newtodo'}>
      <div onClick={this.todoCompleted.bind(this, i)}>
        <input type="checkbox" className="option-input checkbox" checked={todo.checked} />
        <button onClick={this.edit.bind(this,i)}>edit</button>
        <div key={todo.id}  className="item">
          {todo.Value}
          <span className="destroy" onClick={this.remove.bind(this, i)}>X</span>

        </div>
      </div>
    </li>
  );
};

remove(i){
  this.state.todo.splice(i,1)
  this.setState({todo:this.state.todo})
};
todoCompleted(i){
   var todo=this.state.todo;
   todo[i].checked =todo[i].checked? false:true;
     this.setState({
       todo:this.state.todo
     });

 };
allCompleted=()=>{
  var todo = this.state.todo;
  var _this = this
  todo.forEach(function(item) {
    item.className = _this.state.finished ? "newtodo" : "line"
    item.checked = !_this.state.finished
  })
  this.setState({todo: todo, finished: !this.state.finished})
};
changeValue(e) {
  this.setState({
    value: this.state.value = e.target.value
  });
} 
edit(i){
  var todo= this.state.todo
  this.setState({
    editing:true,
    value: this.state.todo[i].Value,
    current: i
  });
};
save(i){
  var clonedTodo = JSON.parse(JSON.stringify(this.state.todo));
  clonedTodo[this.state.current].Value = this.state.value;
  this.setState({
    editing:false,
    todo: clonedTodo
  });
};
  rendernormal() {
  return (
      <div>
        <h1 id='heading'>todos</h1>
        <div className="lines"></div>
        <div>
          <input type="text" ref= "inputodo" onKeyPress={this.entertodo.bind(this)}className="inputodo"placeholder='todos'/>
          <span onClick={this.allCompleted}id="all">^</span>

        </div>
        <div className="mainapp">
          <ul className="decor">
            {this.state.todo.map(this.todo.bind(this))}
          </ul>
        </div>
      </div>
    );
  };
  renderform(todo,i) {
  return (
    <div>
      <h1 id='heading'>todos</h1>
      <div className="lines"></div>
      <div>
        <input type="text" onChange={this.changeValue.bind(this)} ref="inputodo" value={this.state.value} placeholder='EDIT TODO'/>
        <span onClick={this.allCompleted}id="all">^</span>
        <button onClick={this.save.bind(this)}>save</button>
      </div>
      <div className="mainapp">
        <ul className="decor">
          {this.state.todo.map(this.todo.bind(this))}
        </ul>
      </div>
    </div>
    );
  };
  render(){
    if (this.state.editing) {
      return this.renderform()
    }
    else {
    return this.rendernormal()
    }
  };
}
 

ReactDOM.render(<App/>,document.getElementById('app'));
    .line {
  text-decoration: line-through;
  color: red;
}
.newtodo{
  text-decoration: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="app"></div>

Sign up to request clarification or add additional context in comments.

2 Comments

hi alexandr, thanks for update. But why i am not able to edit the text and save it?
Ok, I thaught you had only troubles with setting the value and the rest you would like to do by your own. I've updated my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.