How to Select a Node Immediately After Inserting It


#1

Hello! I would like to select an inline node immediately after I have inserted it. However I do not know how to create the ResolvedPos for the NodeSelection. To do so, I would need to access the new state which is created by the transaction which inserts the node into the document.

Here is my [partially functional] code:

    insertExpression(state, dispatch) {
        const schemaType = state.schema.nodes.expression;
        let {$from} = state.selection, index = $from.index()
        if (!$from.parent.canReplaceWith(index, index, schemaType))
          return false
        if (dispatch) {
          let expressionNode = schemaType.create({value: ''});
          //resolves a position which does not yet contain the node which I will soon add to the document
          let resolvedPos = state.doc.resolve(state.selection.anchor)
          let nodeSelection = new NodeSelection(resolvedPos)
          dispatch(
            state.tr
              .replaceSelectionWith(expressionNode)
              .setSelection(nodeSelection)
          )
        }
        return true
    }

could you please suggest how to fix my code? is there a smart way to get the new state out of a transaction? Thank you!


#2

I used the selection from the transaction after replacing it with a node. Seems to work for my use case, but my inline nodes are always size 1 so I haven’t tested it with variable sized nodes.

const node = schema.nodes.myNode.create({value: ''});
const tr = state.tr;
tr.replaceSelectionWith(node);
const resolvedPos = tr.doc.resolve(
  tr.selection.anchor - tr.selection.$anchor.nodeBefore.nodeSize
);
tr.setSelection(new NodeSelection(resolvedPos));

#3

Yes, I think @mdsib diagnosed the problem correctly—you’ve already changed the document, so the selection you create should point at the new document, which you can get from the transaction.


#4

thanks @mdsib and @marijn that solution worked!