What's the best way to trigger the EditorView contenteditable on and off?

From what I see in the documentation there is the EditorProp : editable https://prosemirror.net/ref.html#view.EditorProps.editable but this is not triggered immediately.

The main problem is going from non-editable to editable, it seems that it only triggers it back to being editable with a node selection, cmd-click or triple click on a text block.

I’ve tried doing a dispatch(), focus(), updateState() and none seem to trigger the attribute contenteditable of the EditorView back to true.

How are you changing the prop? Calling update with an object containing your props with editable: false should do it.

I’m using a function:

editable: (state) => this.state.isEditable

If I use editable: false it throws an error: Uncaught TypeError: value is not a function

I tried updating with a new object from the current editorView.props and it doesn’t work:

this.editorView.update(Object.assign({}, this.editorView.props))

Right, it should be a function. But where does state.isEditable come from?

It’s React’s component state. this.state.isEditable: boolean

That doesn’t sound right. The state passed to that function is an instance of ProseMirror’s EditorState class, which does not have an isEditable property.

Exactly, and I’m not using it, so instead it should be:

editable: () => this.state.isEditable

So you’re making the editable property depend on some external mutable field? Don’t do that. ProseMirror won’t be able to notice when it changes, as you found out.

What’s the best approach to changing it?

Thank you! Got it. This works and updates the contenteditable attribute immediately:

    const isEditable = this.state.isEditable
    this.editorView.update(Object.assign({}, this.editorView.props, {
      editable: () => isEditable
    }))
```

So as a rule all objects are immutable in ProseMirror?

Not all, but yes, those that don’t provide an API for changing them should be considered immutable.

There’s currently an issue with Object.assign solution – it’ll reset your state if you used updateState before. That’s a mistake in my API, and I’m going to look into it (#564)

2 Likes