Search code examples
javascriptreactjsreact-nativefrontenddraftjs

React Draft-js Block Insert


How it Works: When the user hits the spacebar the Draft-JS text content is queried for a specific word. All instances of that word are then wrapped in tags. After the text is wrapped the HTML is then converted back and the Draft-JS editor state is updated:

      const convertedFromHTML= convertFromHTML(newHTML);
      const editorState = this.state.editorState;

      // Set Editor and Content States
      const newContentState = ContentState.createFromBlockArray(
        convertedFromHTML.contentBlocks,
        convertedFromHTML.entityMap
      );

      const nextEditorState = EditorState.push(
        editorState,
        newContentState,
        'insert-text'
      );

      this.setState({ 
        editorState: nextEditorState
      });

Block Render Map:

const blockRenderMap = Immutable.Map({
  'Atomic': {
    element: 'Atomic' ,
    wrapper: <GoogleCustomBlock />
  }
});

const myBlockStyleFn = (contentBlock) => {
   const type = contentBlock.getType();
   switch (type) {
     case 'atomic': {
      return 'GoogleCustomBlock';
   }
}

Custom Block Component:

// React Components
import React, { Component } from 'react';

class GoogleCustomBlock extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className='GoogleCustomBlock'>
        {this.props.children}
      </div>
    );
  }
}

export default GoogleCustomBlock;

The Issue: This functionality occurs when a user hits the space bar. The text is wrapped and the correct blocks are added to the DOM. I am having two difficulties listed below:

  • I need to insert a space after the the end of the text.
  • The cursor jumps back to the start of the document, but also stays within the new block that was created via the elements. I need it to resume editing outside of the new block and at the end of the text.

I have searched online but no luck so far, any help is appreciated.

Thanks!


Solution

  • Solution: Highlighting text and inserting space on space-bar key command:

       insertInlineStyles = (editorState, indexes, googleSearchTerm) => {
          const contentState = editorState.getCurrentContent()
          const selectionState = editorState.getSelection();
    
          // Loop Through indexes //
          const newSelection = selectionState.merge({
            anchorOffset: index[i],
            focusOffset: googleSearchTerm.length
          })
    
          // Create new Editor State with Selection on Targeted Word //
          const editorStateWithNewSelection = EditorState.forceSelection(editorState, newSelection);
    
          // Toggle Inline Style //
          const editorStateWithStyles = RichUtils.toggleInlineStyle(editorStateWithNewSelection,'GoogleStyle');
    
          // Set Selection Back to Previous //
          const editorStateWithStylesAndPreviousSelection = EditorState.forceSelection(
            editorStateWithStyles,
            selectionState
          )
    
          // Return Editor //
          return editorStateWithStylesAndPreviousSelection;
       }
    
        /// INSIDE OF ANOTHER FUNCTION
    
        /// GET INDEX OF WORD TO HIGHLIGHT
        var indexes = [INDEX OF WORD];
    
        /// INSERT INLINE STYLES
        var newEditorState = this.insertInlineStyles(this.state.editorState, indexes, googleSearchTerm);
    
        /// ADD SPACE to TEXT
        let newContentState = Modifier.replaceText(
          newEditorState.getCurrentContent(), // New content
          currentState.getSelection(), // End of old content selection
          " " // Text to add
        );
        let finalEditorState = EditorState.push(
          newEditorState, 
          newContentState, 
          'insert-characters'
        );
    
        this.setState({ 
          editorState: finalEditorState 
        });