React TinyMCE Editor with noneditable plugin
Tags: react, tutorial
Published: 2021-08-25 13:39:18

Trying to find a nice editor to integrate with in your application is not an easy task. You need a highly customizable package regarding both toolbar and main editor design.

I also had a feature to implement which needed some non editable (non deletable) text inside the editor wrapping the main content.

For this case, i decided to use TinyMCE editor which have many plugins including noneditable plugin(but still deletable). We will see the workaround for this issue in this tutorial.

TinyMCE is a free editor with some amazing opensource plugins but also contains some premium plugins that are not free.

To start with, we need to install TinyMCE react package.
`npm install --save @tinymce/tinymce-react`
You can find the Quick start guide in [here](https://www.tiny.cloud/docs/integrations/react/)

Next we will add the Editor Component with its main configurations.

The editor component looks like this
```
import React, { useRef } from "react";
import { Editor } from "@tinymce/tinymce-react";

const editorRef = useRef(null);
const handleEditorChange = (value) => {
    // value is in HTML format not text
    console.log(value);
};

<Editor
    apiKey="<API_KEY>"
    onInit={(evt, editor) => (editorRef.current = editor)}
    onEditorChange={handleEditorChange}
/>

```
You can get the api key with a free account. It is not mandatory but it will hide an annoying warning above the editor.

Let's start adding our configurations
```
<Editor
    ...
    init={{
          menubar: false, // remove menubar if not needed
          toolbar:
            "styleselect| bold italic underline | alignleft aligncenter alignright alignjustify", // add custom buttons for your toolbar
          style_formats: [
            { title: "H1", block: "h1" },
            { title: "H2", block: "h2" },
            { title: "H3", block: "h3" },
            { title: "H4", block: "h4" },
            { title: "H5", block: "h5" },
            { title: "H6", block: "h6" },
            { title: "Paragraph", block: "p" },
          ], // customize the styleselect dropdown in toolbar with only these
          branding: false, // remove tinymce branding
          resize: false, // disallow editor resize
          statusbar: false, // remove bottom status bar
          plugins: "noneditable", // add the noneditable plugin
          content_css: "material-outline",
          skin: "material-outline", // use the material ui theme
          height: 450, // Editor height
        }}
/>
```
We some what customized our editor. But we need to add the non deletable functionality for noneditable plugin.

For this we need to add initial value for the editor with our non editable content as html. The default css class for noneditable plugin is `mceNonEditable`.

So we're adding this class to our content and applying a function called on pressing backspace or delete button to check on these content and not delete them.

```
<Editor 
   ...
   initialValue=`<p 
       class="mceNonEditable">Non editable content 
      </p>
       <p>
       <br /><br /><br /></p>
     <p class="mceNonEditable">Non editable content</p>`
   init={{
     ...,
     setup: function (editor) {
            editor.on("keydown", function (event) {
              if (event.keyCode === 8 || event.keyCode === 46) {
                const currentLine = editor.selection.getNode();

                // Prevent deletion of non editable text
                if (currentLine.hasAttribute("data-mce-bogus") || currentLine.className.includes("mceNonEditable")) {
                  event.preventDefault();
                  event.stopPropagation();
                  return false;
                }
              }
            });
          },
   }}
```

The initial value attribute takes content as html string with mceNonEditable class. To add multiple non editable contents with space between them, you can use <br /> tags as shown above. The setup handler checks for backspace and delete keys and prevent default behavior if cursor is on the line of the non editable content.

That's it. Now you have an editor with non editable content. You can change styles and add other features and many more. You can find more details from the [docs](https://www.tiny.cloud/docs/)

Hope this quick tutorial is helpful for anyone stuck with an editor and wants to get going fast.