5

Code involved using DraftJS and Meteor Js application Task - Make a live preview where text from DraftJS will get saved to DB and from DB it get displayed on another component.

But problem is once data comes from DB and I try to edit DraftJS cursor moved to the beginning.

Code is

import {Editor, EditorState, ContentState} from 'draft-js';
import React, { Component } from 'react';
import { TestDB } from '../api/yaml-component.js';
import { createContainer } from 'meteor/react-meteor-data';
import PropTypes from 'prop-types';

class EditorComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
        editorState : EditorState.createEmpty(),
    };
  }

  componentWillReceiveProps(nextProps) {
    console.log('Receiving Props');
    if (!nextProps) return;
    console.log(nextProps);
    let j = nextProps.testDB[0];
    let c = ContentState.createFromText(j.text);
    this.setState({
      editorState: EditorState.createWithContent(c),
    })
  }

  insertToDB(finalComponentStructure) {
    if (!finalComponentStructure) return;
    finalComponentStructure.author = 'Sandeep3005';
    Meteor.call('testDB.insert', finalComponentStructure);
  }


  _handleChange(editorState) {
    console.log('Inside handle change');
    let contentState = editorState.getCurrentContent();
    this.insertToDB({text: contentState.getPlainText()});
    this.setState({editorState});
  }

  render() {
    return (
      <div>
        <Editor
          placeholder="Insert YAML Here"
          editorState={this.state.editorState}
          onChange={this._handleChange.bind(this)}
        />
      </div>
    );
  }
}


    EditorComponent.propTypes = {
     staff: PropTypes.array.isRequired,
    };

    export default createContainer(() => {
      return {
        staff: Staff.find({}).fetch(),
      };
    }, EditorComponent);

Any helpful comment in right direction will be useful

Vico
  • 1,696
  • 1
  • 24
  • 57
Sandeep Chikhale
  • 1,505
  • 2
  • 21
  • 36

3 Answers3

9

When you call EditorState.createWithContent(c) Draft will return a new EditorState for you, but it has no idea about your current SelectionState. Instead, it will just create a new empty selection in the first block of your new ContentState.

To overcome this, you will have to set the SelectionState yourself, using the SelectionState from your current state, e.g:

const stateWithContent = EditorState.createWithContent(c)
const currentSelection = this.state.editorState.getSelection()
const stateWithContentAndSelection = EditorState.forceSelection(stateWithContent, currentSelection)

this.setState({
  editorState: stateWithContentAndSelection
})
tobiasandersen
  • 8,480
  • 3
  • 28
  • 39
0

There is a propery to move focus to end:

const newState = EditorState.createEmpty()
this.setState({
 editorState:
  EditorState.moveFocusToEnd(newState)
 })

This works for me.

tech_amity
  • 192
  • 3
  • 4
    This solution will cause the cursor to always have focus at the end. If the user changed the cursor to the middle it would still jump to the end. – Aravind Reddy Aug 30 '21 at 10:03
0

All you need to do is to pass your given EditorState inside built in static EditorState.moveSelectionToEnd() method:

const editorState = EditorState.createEmpty();
const editorStateWithFocusOnTheEnd = EditorState.moveSelectionToEnd(editorState)
Mateusz Osuch
  • 388
  • 1
  • 4
  • 14