Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Draft.js Wysiwyg: How to programmatically insert text at the cursor location?

I am using the React Draft Wysiwyg and I need to insert arbitrary text from one component of my application into the editor component. I am doing this via the clipboard as an intermediary for the transfer from one component to the other. But the document.execCommand('paste') fails.

Does anybody know how to do this?

My sample code is here; the third console log emits false for the paste result.

import React, { Component } from 'react';
import { EditorState, convertToRaw, Modifier } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import draftToHtml from 'draftjs-to-html';
import htmlToDraft from 'html-to-draftjs';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import styled from 'styled-components';

class EditorConvertToHTML extends Component {
  constructor(props) {
    super(props);
    this.state = {editorState: EditorState.createEmpty()};
    this.onChange = (editorState) => this.setState({editorState});
    this.setEditor = (editor) => {
      this.editor = editor;
    };
    this.focusEditor = () => {
      if (this.editor) {
        this.editor.focusEditor();
        console.log("1. Editor has the focus now");
      }
    };
  }

  componentDidMount() {
    this.focusEditor();
  }

  onEditorStateChange = (editorState) => {
    this.setState({
      editorState,
    });
  };

  sendTextToEditor = (text) => {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);

    navigator.clipboard.readText()
    .then(text => {
      this.focusEditor();
      console.log('2. Retrieved pasted text from clipboard = ', text);
      result = document.execCommand('paste');
      console.log("3. Paste command's result = ", result);
    })
    .catch(err => {
      console.error('Failed to read clipboard contents: ', err);
    });

    return result;
  }

  render() {
    const { editorState } = this.state;
    return (
      <>
        <EditorStyled>
          <Editor
            ref={this.setEditor}
            editorState={editorState}
            wrapperClassName="demo-wrapper"
            editorClassName="demo-editor"
            onEditorStateChange={this.onEditorStateChange}
          />
        </EditorStyled>
        <button type="button" onClick={this.sendTextToEditor.bind(this, 'Sample text to put in editor')}>Copy sample text to editor</button>
      </>
    );
  }
}

export default EditorConvertToHTML;

const EditorStyled = styled.div`
  width: ${() => "calc(100% - 40px)"};
  min-height: 400px;
  margin: 20px;
  border: 1px solid black;
`;

Thank you in advance for your help!

like image 550
dchosen1 Avatar asked Nov 16 '25 08:11

dchosen1


1 Answers

Thanks to Rosemarie Robertson's explanations/article @ https://dev.to/rose/draft-js-simple-content-manipulation-b7a I got the sample working. Here is the code:

import React, { Component } from 'react';
import { EditorState, Modifier } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import styled from 'styled-components';

// Following sample is based the article https://dev.to/rose/draft-js-simple-content-manipulation-b7a

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

  componentDidMount() {
    this.focusEditor();
  }

  setEditor = (editor) => {
    this.editor = editor;
  };

  focusEditor = () => {
    if (this.editor) {
      this.editor.focusEditor();
      console.log("1. Editor has the focus now");
    }
  };

  onEditorStateChange = (editorState) => {
    this.setState({
      editorState,
    });
  };

  sendTextToEditor = (text) => {
    this.setState({editorState: this.insertText(text, this.state.editorState)});
    this.focusEditor();
  }

  insertText = (text, editorState) => {
    const currentContent = editorState.getCurrentContent(),
          currentSelection = editorState.getSelection();

    const newContent = Modifier.replaceText(
      currentContent,
      currentSelection,
      text
    );

    const newEditorState = EditorState.push(editorState, newContent, 'insert-characters');
    return  EditorState.forceSelection(newEditorState, newContent.getSelectionAfter());
  }

  render() {
    const { editorState } = this.state;
    return (
      <>
        <EditorStyled>
          <Editor
            ref={this.setEditor}
            editorState={editorState}
            wrapperClassName="demo-wrapper"
            editorClassName="demo-editor"
            onEditorStateChange={this.onEditorStateChange}
          />
        </EditorStyled>
        <button type="button" onClick={this.sendTextToEditor.bind(this, 'Sample text to put in editor')}>Copy sample text to editor</button>
      </>
    );
  }
}

export default EditorConvertToHTML;

const EditorStyled = styled.div`
  width: ${() => "calc(100% - 40px)"};
  min-height: 400px;
  margin: 20px;
  border: 1px solid black;
`;

like image 170
dchosen1 Avatar answered Nov 18 '25 21:11

dchosen1



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!