0

I need to apply focus to a Draft.js editor and position the cursor at the start of the first line/block. The editor contains multiple lines/blocks.

With only this.refs.editor.focus() being applied, the cursor is always positioned at the start of the second block/line within the editor.

Using this question and this issue as guides, I tried the code below without success. I suspect that passing blockMap to createFromBlockArray() is not correct:

focusTopLine() {

  this.refs.editor.focus();

  const { editorState } = this.state;
  const contentState = editorState.getCurrentContent();
  const selectionState = editorState.getSelection();
  const blockMap = contentState.getBlockMap();

  const newContentState = ContentState.createFromBlockArray(blockMap);
  const newEditorState = EditorState.createWithContent(newContentState);

  this.setState({
    editorState: EditorState.forceSelection(newEditorState, selectionState)
  });
}
Community
  • 1
  • 1
cantera
  • 24,479
  • 25
  • 95
  • 138

2 Answers2

5

You can (probably, I haven't tested this) do it similar to how EditorState.moveFocusToEnd() is implemented:

First, create a new EditorState where the first block is selected:

function moveSelectionToStart(editorState) {
  const content = editorState.getCurrentContent()
  const firstBlock = content.getFirstBlock()
  const firstKey = firstBlock.getKey()
  const length = firstBlock.getLength()

  return EditorState.acceptSelection(
    editorState,
    new SelectionState({
      anchorKey: firstKey,
      anchorOffset: length,
      focusKey: firstKey,
      focusOffset: length,
      isBackward: false,
    })
  )
}

Then use that to move the focus:

function moveFocusToStart(editorState) {
  const afterSelectionMove = EditorState.moveSelectionToStart(editorState)
  return EditorState.forceSelection(
    afterSelectionMove,
    afterSelectionMove.getSelection()
  )
}

It can now be used like this:

this.setState({ editorState: moveFocusToStart(editorState) })
tobiasandersen
  • 8,480
  • 3
  • 28
  • 39
  • Thanks - confirming that your code worked. For some reason I had to wrap the call to `setState` in a `setTimeout(..., 0)` but with that modification it appears to be working. Thanks again. – cantera Nov 08 '16 at 22:28
0

I think you can also use merge, to set the focus and anchor offset like this:

function moveFocusToStart(editorState: EditorState): EditorState {
  const selectionState = editorState.getSelection();
  return EditorState.forceSelection(
    editorState,
    selectionState.merge({
      anchorOffset: 0,
      focusOffset: 0,
    }),
  );
}
Jaqueline
  • 37
  • 5