Do you want to request a feature or report a bug?
Feature
What is the current behavior?
There is no way to tell definitively what caused onChange to fire
What is the expected behavior?
I need a way to tell what caused onChange to fire for an autosave feature. I don't want to autosave on events that do not meaningfully change the editor state (such as clicks). It would be nice if editorstate had some property that said what user interaction caused an onchange event to fire. There is the lastChangeType property which gets most of the way there, but it's specifically for undo/redo and doesn't incorporate click changes, or cursor state changes at all (simply ignores they happened).
Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js?
Latest, new feature.
hi @cameackeSEL , I had to solve the same problem. What I did is compare the ContentState with the previous, not the whole EditorState (which also includes SelectionState etc). If they are the same reference, then you can assume that the content of the editor has changed, not just the selection etc.
e.g.
this.state.editorState.getCurrentContent() !== newState.editorState.getCurrentContent()
Thanks for the recommendation! We'll give it a try and see how it works.
I would be interested in how well the approach @si13b recommended works for your use case, and if more is still needed what it could look like.
@flarnie , we've been using this approach and it seems to work really well!
Maybe this would be something that'd be useful to point out in the docs?
It will be useful to add in the docs, since the question comes up several times.
Link to same issue https://github.com/facebook/draft-js/issues/830
@si13b's approach works perfect for me. I will just add for the sake anyone else reading this that it is best to use the Immutable.js is function to compare equality as ContentState is an Immutable Record.
immutable.is(this.state.editorState.getCurrentContent(), newEditorState.getCurrentContent())
This works fine, but not for Entity.replaceData. I have a use-case where that should dirty my form but it doesn't because the old content still matches the new one, plus there isn't an EditorChangeType that gets triggered by it.
I think the real solution here could be to be able to say if the change that happened is _only_ a selection change, and nothing else. Without mingling with the content.
editorState.getLastChangeType() wrongly persists across selectionChange.
If I make a change in content, the first-time editorState.getLastChangeType() will have the correct type of insert-characters(or whatever). However, now if I make any selection change, e.g by moving position of the cursor, editorState.getLastChangeType on each onChange stays the same as insert-characters.
Same as the previous comment. Also, comparing results of getCurrentContent() calls doesn't seem to work if I'm changing styling (bold, italic, etc.). Only when the actual content changes.
Guys, usefull post!!
However using Entity.mergeData with forceSelection the conditional this.state.editorState.getCurrentContent() !== newState.editorState.getCurrentContent() is not true and when I use
immutable.is(this.state.editorState.getCurrentContent(), newEditorState.getCurrentContent()) always is true even when I move the cursor's position or set the focus in the editor. There is any temporary fix?
My initial issue was issue.
Thank you.
This is the code that I using.
Entity.mergeData(
blockProps.entityKey,
{
id: inputVideoKey,
src: url
}
);
const editorState = blockProps.getEditorState();
const updateSelection = new SelectionState({
anchorKey: selection.anchorKey,
anchorOffset: selection.anchorOffset,
focusKey: selection.anchorKey,
focusOffset: selection.focusOffset,
isBackward: false,
});
let newEditorState = EditorState.acceptSelection(
editorState,
updateSelection
);
newEditorState = EditorState.forceSelection(newEditorState, newEditorState.getSelection());
blockProps.setEditorState(newEditorState);
Most helpful comment
hi @cameackeSEL , I had to solve the same problem. What I did is compare the ContentState with the previous, not the whole EditorState (which also includes SelectionState etc). If they are the same reference, then you can assume that the content of the editor has changed, not just the selection etc.
e.g.