How do I listen to change events for a contentEditable
-based control?
var Number = React.createClass({ render: function() { return <div> <span contentEditable={true} onChange={this.onChange}> {this.state.value} </span> = {this.state.value} </div>; }, onChange: function(v) { // Doesn't fire :( console.log('changed', v); }, getInitialState: function() { return {value: '123'} } }); React.renderComponent(<Number />, document.body);
Advertisement
Answer
See Sebastien Lorber’s answer which fixes a bug in my implementation.
Use the onInput event, and optionally onBlur as a fallback. You might want to save the previous contents to prevent sending extra events.
I’d personally have this as my render function.
var handleChange = function(event){ this.setState({html: event.target.value}); }.bind(this); return (<ContentEditable html={this.state.html} onChange={handleChange} />);
jsbin
Which uses this simple wrapper around contentEditable.
var ContentEditable = React.createClass({ render: function(){ return <div onInput={this.emitChange} onBlur={this.emitChange} contentEditable dangerouslySetInnerHTML={{__html: this.props.html}}></div>; }, shouldComponentUpdate: function(nextProps){ return nextProps.html !== this.getDOMNode().innerHTML; }, emitChange: function(){ var html = this.getDOMNode().innerHTML; if (this.props.onChange && html !== this.lastHtml) { this.props.onChange({ target: { value: html } }); } this.lastHtml = html; } });