Reactjs RichTextEditor Custom Toolbar in .tsx

Viewed 441

I want to add new custom HTML tag like as <h1></h1> if click the ? toolbar item in rich text editor. But, I can't get the latest value when click the custom toolbar item in onClickHelp function.

In RichTextEditor.tsx,

import '../../node_modules/@syncfusion/ej2-icons/styles/material.css';
import '../../node_modules/@syncfusion/ej2-buttons/styles/material.css';
import '../../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css';
import '../../node_modules/@syncfusion/ej2-inputs/styles/material.css';
import '../../node_modules/@syncfusion/ej2-lists/styles/material.css';
import '../../node_modules/@syncfusion/ej2-navigations/styles/material.css';
import '../../node_modules/@syncfusion/ej2-popups/styles/material.css';
import '../../node_modules/@syncfusion/ej2-richtexteditor/styles/material.css';
import {
  Count,
  HtmlEditor,
  Inject,
  Image,
  Link,
  QuickToolbar,
  RichTextEditorComponent,
  Toolbar,
  ToolbarSettingsModel,
  ToolbarType
} from '@syncfusion/ej2-react-richtexteditor';

import { FC, useRef, useState } from 'react';

interface RichTextEditorProps {
  value?: string;
  onChange?: (value: string) => void;
}

const RichTextEditor: FC<RichTextEditorProps> = ({
  value,
  onChange
}) => {
  const editorRef = useRef<RichTextEditorComponent>(null);
  const onClickHelp = () => {
    console.log(value);
  };

  const toolbarSettings: ToolbarSettingsModel = {
    type: ToolbarType.MultiRow,
    items: [{
      template:
        '<button type="button" class="e-tbar-btn e-btn" tabindex="-1" id="custom_tbar_help"  style="width:100%"><div class="e-tbar-btn-text" style="font-weight: 800;"> ?</div></button>',
      undo: true,
      click: onClickHelp,
      tooltipText: 'Help'
    }, 'Bold', 'Italic', 'Underline', 'StrikeThrough', 'FontName', 'FontSize', 'FontColor', 'BackgroundColor', 'LowerCase', 'UpperCase', '|', 'Formats', 'Alignments', 'OrderedList', 'UnorderedList', 'Outdent', 'Indent', '|', 'CreateLink', 'Image', '|', 'ClearFormat', 'SourceCode', '|', 'NumberFormatList', 'BulletFormatList', 'Undo', 'Redo'
    ],
  };

  return (
    <RichTextEditorComponent
      ref={editorRef}
      value={value}
      toolbarSettings={toolbarSettings}
      maxLength={30000}
      height={400}
      saveInterval={1}
      showCharCount
      iframeSettings={{ enable: true }}
      change={(e) => {
        onChange(e?.value);
      }}
    >
      <Inject services={[Link, Image, HtmlEditor, Toolbar, QuickToolbar, Count]} />
    </RichTextEditorComponent>
  );
};

RichTextEditor.defaultProps = {
  value: ''
};

export default RichTextEditor;

Reference from rich text editor and example

1 Answers

The problem is caused by props.onChange(e?.value); code inside changefunction. It updates value on App component and then forces RichTextEditor component to be rerendered. When props.value changes, a new instance of ToolbarSettingsModel is created and by default it is not full-screen mode.

You can move the definition of toolbarSettings outside of the RichTextEditor component and bind onClickHelp function to the click prop inside the component like toolbarSettings.items[5].click = onClickHelp;

You can take a look at this sandbox for a live working example of this usage.

Your full code will be like this:

import {
  Count,
  HtmlEditor,
  Inject,
  Link,
  QuickToolbar,
  RichTextEditorComponent,
  Toolbar,
  ToolbarSettingsModel,
  ToolbarType
} from "@syncfusion/ej2-react-richtexteditor";

import { useRef } from "react";

import "./styles.css";

const toolbarSettings: ToolbarSettingsModel = {
  type: ToolbarType.MultiRow,
  items: [
    "Undo",
    "Redo",
    "|",
    "FullScreen",
    "SourceCode",
    {
      template:
        '<button type="button" class="e-tbar-btn e-btn" tabindex="-1" id="custom_tbar_help"  style="width:100%"><div class="e-tbar-btn-text" style="font-weight: 800;"> ?</div></button>',
      undo: true,
      tooltipText: "Help"
    }
  ]
};

export default function RichTextEditor(props: {
  value: string;
  onChange: (value: string) => void;
}) {
  const editorRef = useRef<RichTextEditorComponent>(null);

  const onClickHelp = () => {
    console.log("help");
  };

  toolbarSettings.items[5]["click"] = onClickHelp;

  return (
    <RichTextEditorComponent
      ref={editorRef}
      value={props.value}
      toolbarSettings={toolbarSettings}
      maxLength={30000}
      saveInterval={1}
      showCharCount
      iframeSettings={{ enable: true }}
      change={(e) => {
        console.log("change happened", e?.value);
        props.onChange(e?.value);
      }}
    >
      <Inject services={[Link, HtmlEditor, Toolbar, QuickToolbar, Count]} />
    </RichTextEditorComponent>
  );
}

Related