Apparently it doesn't, but it would be pretty awesome if it did. We already listen for DOMCharacterDataModified
so I don't think it should be too terrible. Tangentially it would be great to stop using mutation events and switch over to observers (let's not do that here though unless it dovetails really nicely).
Interested @spicyj?
Maybe, I don't know anything about contenteditable.
Fair enough. Let us know if you do end up working on it.
I don't believe 'change' should fire for contentEditable fields but 'input' should be. See https://developer.mozilla.org/en-US/docs/Web/Reference/Events/input and https://developer.mozilla.org/en-US/docs/Web/Reference/Events/change
@joshduck React's onChange
intentionally deviates from the spec; see http://facebook.github.io/react/docs/forms.html.
@spicyj Sure. It might make sense to a) polyfill onInput for old browsers b) make onChange depend on onInput rather than directly on modification events. That way we get both events.
That way we get both events.
Are both really needed though? Whenever a difference _could_ exist, React's changes to change
basically match the spec's input
.
@masklinn Basically match the spec's
is a world of difference when it comes to practical usefulness though.
Basically match the spec's is a world of difference when it comes to practical usefulness though.
Yes. A positive one, as input
's behaviour (and react's onchange
) are much more useful than the DOM's change
event.
I need this for a simple editor. I have to create a ContentEditable component that basically does what <div contentEditable onChange={handler} />
should do. Target browser support is IE8.
The more we can do the normalize contentEditable, the better. It's very useful, but inaccessible due to quirks and weirdness and poor cross-browser compatibility. Full normalization would probably be too complex for React core, though.
I'd love to see this as well - for same reason as @brigand - to work on a simple rich-text editor for prose.
@edwardmsmith It may not work on older browsers, but for modern browsers you can use the onInput callback like so:
<div
contentEditable="true"
onInput={function(e) {
console.log("woohoo!");
}}
>initial content</div>
Edit: if you do that, be very sure not to use the app state for that 'initial content'. That will make it a controlled component that gets rerendered every time, and the user's cursor will jump to the beginning of the text with every keypress.
@salier did we ever make this work? I know a lot has happened in this area since this time last year.
For those requesting this, is your objective to have a controlled contentEditable component that makes use of and onChange
event? Or to use native contentEditable behavior in an uncontrolled component?
If it's the latter, is onInput
not sufficient for your use case for modern browsers? I'm inclined to agree with @masklinn , though as @joshduck notes, more work may need to be done to get better legacy browser support.
Low desire here and a way to make this work so just going to close out.
Is IE9 considered a modern browser ? I tried as @willwhitney suggested and it doesn't seem to work for IE9.
The input event in IE9 has limitations e.g. it doesn't work on backspace, delete, the cut operation, or the delete operation. Is that already resolved in react (I don't have IE9 available right now)?
If you can get the event consistently, and borrow react's internal selection utility, contentEditable is somewhat useable. Of course you still have to normalize the generated html, but that's a problem of its own begging for a third party library.
Just checking in here to say a combination of onInput
and a mutation observer covers modern browsers and IE11.
Try this
<ContentEditableDiv
contentEditable
onInput={e => props.messageOnChange(e.currentTarget.innerText)}
/>
<tbody>
{
DataPacientesAPI.map((paciente, i) =>
<tr key={i}>
<td contentEditable={iActivo === i ? true : false} suppressContentEditableWarning onBlur={e => Editando(i, "dni_cliente", e)}>{paciente.dni_cliente}</td>
<td contentEditable={iActivo === i ? true : false} suppressContentEditableWarning onBlur={e => Editando(i, "nombres_cliente", e)}>{paciente.nombres_cliente}</td>
<td contentEditable={iActivo === i ? true : false} suppressContentEditableWarning onBlur={e => Editando(i, "ap_paterno_cliente", e)}>{paciente.ap_paterno_cliente}</td>
<td contentEditable={iActivo === i ? true : false} suppressContentEditableWarning onBlur={e => Editando(i, "ap_materno_cliente", e)}>{paciente.ap_materno_cliente}</td>
<td contentEditable={iActivo === i ? true : false} suppressContentEditableWarning onBlur={e => Editando(i, "direccion_cliente", e)}>{paciente.direccion_cliente}</td>
<td contentEditable={iActivo === i ? true : false} suppressContentEditableWarning onBlur={e => Editando(i, "hcl_cliente", e)}>{paciente.hcl_cliente}</td>
<td contentEditable={iActivo === i ? true : false} suppressContentEditableWarning onBlur={e => Editando(i, "fnacimiento_cliente", e)}>{paciente.fnacimiento_cliente}</td>
<td contentEditable={iActivo === i ? true : false} suppressContentEditableWarning onBlur={e => Editando(i, "sexo_cliente", e)}>{paciente.sexo_cliente}</td>
<td>
<div className="text-info"
title="Editar datos del paciente"
style={{ cursor: "pointer" }}
onClick={() => setiActivo(i)}
>
<FaEdit size={20} />
</div>
</td>
</tr>
)
}
</tbody>
Most helpful comment
Just checking in here to say a combination of
onInput
and a mutation observer covers modern browsers and IE11.