Removing selection on blur

I want to clear the selection on blur so that:

  • No selection is shown when the text is not editable
  • When the user focuses the field again it does not retain the previous selection

I was trying to remove the selection on blur like this (this is coffeescript):

onBlur: (view) =>
    noneSelection = new TextSelection(view.state.doc.resolve(0))
    view.props.onAction(noneSelection.action())

The problem is that in selectionToDOM the selection is not redrawn if the view doesn’t have focus. So the selection is not visibly removed.

Is there a better way to clear the selection on blur?

As an aside, new TextSelection(view.state.doc.resolve(0)) is the best I could come up with the clear the selection. Is there a simpler way? It seems like utility methods for selectNone() and selectAll() would be commonly used.

Are you sure you want to reset ProseMirror’s selection, as opposed to just the DOM selection in the editor?

Yeah, that’s ugly. I’m planning to supply at least a TextSelection.create(doc, 0) variant. selectNone isn’t really a thing, since an editor always has some selection, but maybe a selectAll variant would also be convenient.

Hey, I am also interested in doing this. I am starting to understand the structure of the new PM, but I don’t quite understand why a transaction is being dispatched when the selection within the editor is changed but not when the editor itself blurs or focuses it.

Is this still the recommended way of adding such a transaction?

Connected with this: It seems that certain transactions will reset the selection and it then ends up inside the first textblock node in the document. I would like to instead have the selection in these cases to be at position 0. I also set the position to 0 on blur and this way I can make sure that the decorators for the placeholders (plural) are set correctly.

Is there a way to configure this? Or some other way to achieve the same thing?

Edit: No longer needed. I gave the decoration in the currently selected element an extra class so that it can be hidden when there is focus on the editor.

Hello, for now I’m using the logic suggested by @marijn. It works as expected:

editor.view.dispatch(editor.state.tr.setSelection(TextSelection.create(editor.state.doc, 0)));

editor.commands.blur();

If I do this, I see this warning in console TextSelection endpoint not pointing into a node with inline content (doc).

I just want to undo my NodeSelection in my node view so that the CSS class ProseMirror-selectednode is removed:

                this.view.dispatch(
                    this.view.state.tr.setSelection(
                        new NodeSelection(this.view.state.doc.resolve(getPos())),
                    ),
                );

Is there another way to remove a selection?

As the error indicates, text selections can’t exist just anywhere, but only in inline positions. You could use Selection.near to create a valid selection near a given point.