7
votes

I have been playing with Draft.js and I'm stuck trying to get immutable entities working properly.

I would like to insert an immutable entity when a user clicks a button. Here is the function that inserts the entity:

const text = "foo";

const editorState = this.state.value;
const selectionState = editorState.getSelection();
const contentState = editorState.getCurrentContent();
const contentStateWithEntity = contentState.createEntity("TOKEN", "IMMUTABLE", { time: new Date().getTime() });
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const modifiedContent = Modifier.insertText(contentState, selectionState, text, OrderedSet([ "INSERT" ]), entityKey);
const nextState = EditorState.push( editorState, modifiedContent, editorState.getLastChangeType() );

this.setState({value: nextState}, this.focus );

I have a working example of this here: https://codepen.io/dakridge/pen/XgLWJQ

It seems to almost work, but after inserting the immutable text, it seems to still be editable because continuing to type retains the style of the entity.

What am I doing wrong? Is there a better way of doing this? I have seen the example posted here: https://github.com/facebook/draft-js/blob/master/examples/draft-0-10-0/entity/ and they seem to use a span element. Is that a preferred method?

Thank you for all the help!

1
Seeing your example helped me figure out a different problem. I had not been adding the entityKey in the insertText. Really helpful to see your example even if not perfect.Rob Cannon

1 Answers

2
votes

A little late. One thing to note: your fiddle's Entity is "SEGMENTED" rather than "IMMUTABLE".

Take a look at this forked fiddle: https://codepen.io/anon/pen/pMEoyN

When you type this:

const modifiedContent = Modifier.insertText(contentState, 
   selectionState, 
   text, 
   OrderedSet([ "INSERT" ]), 
   entityKey);

The text that you insert has both an entity (last parameter) and an inline style (second-to-last parameter). Entities and inline styles are distinct in Draft.

If you look at the stringified raw content state at the bottom, you'll see that the ENTITY ranges stay the same when you keep typing (entity is not extended), but the inline style is extended (named "INSERT" in your example.). This is consistent with draft's behavior. You need to turn off the inline style separately.