How do I listen to change events for a contentEditable
-based control?
JavaScript
x
21
21
1
var Number = React.createClass({
2
render: function() {
3
return <div>
4
<span contentEditable={true} onChange={this.onChange}>
5
{this.state.value}
6
</span>
7
=
8
{this.state.value}
9
</div>;
10
},
11
onChange: function(v) {
12
// Doesn't fire :(
13
console.log('changed', v);
14
},
15
getInitialState: function() {
16
return {value: '123'}
17
}
18
});
19
20
React.renderComponent(<Number />, document.body);
21
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.
JavaScript
1
6
1
var handleChange = function(event){
2
this.setState({html: event.target.value});
3
}.bind(this);
4
5
return (<ContentEditable html={this.state.html} onChange={handleChange} />);
6
jsbin
Which uses this simple wrapper around contentEditable.
JavaScript
1
25
25
1
var ContentEditable = React.createClass({
2
render: function(){
3
return <div
4
onInput={this.emitChange}
5
onBlur={this.emitChange}
6
contentEditable
7
dangerouslySetInnerHTML={{__html: this.props.html}}></div>;
8
},
9
shouldComponentUpdate: function(nextProps){
10
return nextProps.html !== this.getDOMNode().innerHTML;
11
},
12
emitChange: function(){
13
var html = this.getDOMNode().innerHTML;
14
if (this.props.onChange && html !== this.lastHtml) {
15
16
this.props.onChange({
17
target: {
18
value: html
19
}
20
});
21
}
22
this.lastHtml = html;
23
}
24
});
25