user4991434
user4991434

Reputation:

How to edit an element's text with React.js?

i wanna edit my p element's text when i press edit button.

When i click edit button, i display a textarea and get keyed text with alert but can't put that text to my p element.

What is the simple way to do it with React.js ?

JSFIDDLE

When i press edit button, editing state changing and textarea shows up.The code below.

renderNormal: function() {
    return (
      <div>
        <p>Edit me</p>
        <button onClick={this.edit}>Edit</button>
    </div>
    )
  },
  renderForm: function() {
    return (
      <div>
         <textarea ref="newText" defaultValue="Edit me"></textarea>
        <button onClick={this.save}>Save</button>
    </div>
    )
  },
  render: function() {
    if (this.state.editing) {
      return this.renderForm()
    } else {
      return this.renderNormal()
    }
  }

Upvotes: 5

Views: 40713

Answers (3)

jdmdevdotnet
jdmdevdotnet

Reputation: 1

I actually had this same problem, here was my solution:

{editableSubTasks.filter(id => id === subTask.Id).length > 0 ? <input type="text" /> : <span>{subTask.Name}</span>}

So basically, you have an array, in my case it was editableSubTasks. Whenever I would trigger the text element to change to a textarea, I would simply add that guy to the edtiableSubTasks array. And then in my map function, if the Id of the correspnding item was in the editableSubTasks array, I would use a ternary operator to tell it to be a <input type="text">, otherwise just a span. In your case obviously you can use a textarea. This worked out wonderfully. Here was my SO with the answer that I ended up using:

How to dynamically show/hide a list of items in react

If you don't need the array, then the answer is even simpler, just have a bool and change it to true when you want it to be a text area.

Upvotes: 1

Jeff McCloud
Jeff McCloud

Reputation: 5927

You need to store and retrieve the text from a state variable. Modifying the state causes a re-render, which will then display the updated text. Copied from your JSFiddle... note where I've added a "text" property to your state

var MyCom = React.createClass({
  getInitialState: function() {
    return {
      editing: false,
      // ** Initialize "text" property with empty string here
      text: ''
    }
  },
  edit: function() {
    this.setState({
      editing: true
    })
  },
  save: function() {
    var val = this.refs.newText.value;
    alert(val)
    this.setState({
      // ** Update "text" property with new value (this fires render() again)
      text: val,
      editing: false
    })
  },
  renderNormal: function() {
    // ** Render "state.text" inside your <p> whether its empty or not...
    return (
      <div>
        <p>{this.state.text}</p>
        <button onClick={this.edit}>Edit</button>
    </div>
    )
  },
  renderForm: function() {
    return (
      <div>
         <textarea ref="newText" defaultValue="Edit me"></textarea>
        <button onClick={this.save}>Save</button>
    </div>
    )
  },
  render: function() {
    if (this.state.editing) {
      return this.renderForm()
    } else {
      return this.renderNormal()
    }
  }
})

ReactDOM.render(
  <div>
  <MyCom/>
    <MyCom/>
    </div>,
  document.querySelector(".box")
)

Upvotes: 8

Luan Nico
Luan Nico

Reputation: 5917

You have to set a value on the state on the button is clicked, and then read that on render.

Example:

handler : function () {
  this.setState({ value : 'hey' });
},

render : function () {
  return <p>{ this.state && this.state.value ? this.state.value : 'hoy' }</p>;
}

Everytime you want the render method to change according to something that can happen, the action that triggers it must trigger a state change, and change the state object, and the object will be rerendered, so the render method should check the current state.

If you want to change the value of a input (or in your case, a textarea), you can use the linkedstate pattern as a two way databinding (more here).

I particularly use this lib. There are plenty of examples there.

Upvotes: 1

Related Questions