Insert Table in EJ2 TypeScript Markdown Editor Control

22 Mar 202521 minutes to read

To enable the table insertion feature, add the CreateTable option to the toolbar items. Once added, users can click the Insert Table icon in the toolbar to insert a table into the editor.

By default, when a table is inserted, it consists of:

  • 2 rows and 2 columns
  • A table header row

This ensures that users can start formatting and adding content immediately.

import { enableRipple } from '@syncfusion/ej2-base';
enableRipple(true);

import {
  RichTextEditor,
  Link,
  Image,
  MarkdownEditor,
  Table,
  Toolbar,
} from '@syncfusion/ej2-richtexteditor';
import { createElement, KeyboardEventArgs } from '@syncfusion/ej2-base';
import Marked from 'marked';

RichTextEditor.Inject(Link, Image, MarkdownEditor, Table, Toolbar);

let textArea: HTMLTextAreaElement;
let mdsource: HTMLElement;
let htmlPreview: HTMLElement;

let editor: RichTextEditor = new RichTextEditor({
  value: `In Rich Text Editor, you click the toolbar buttons to format the words and the changes are visible immediately. Markdown is not like that. When you format the word in Markdown format, you need to add Markdown syntax to the word to indicate which words and phrases should look different from each other. Rich Text Editor supports markdown editing when the editorMode set as **markdown** and using both *keyboard interaction* and *toolbar action*, you can apply the formatting to text. You can add our own custom formation syntax for the Markdown formation, [sample link](https://ej2.syncfusion.com/home/). The third-party library <b>Marked</b> is used in this sample to convert markdown into HTML content.`,
  height: 250,
  editorMode: 'Markdown',
  toolbarSettings: {
    items: [
      'CreateTable',
      {
        tooltipText: 'Preview',
        template:
          '<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn">' +
          '<span class="e-btn-icon e-md-preview e-icons"></span></button>',
      },
    ],
  },
  created: () => {
    textArea = editor.contentModule.getEditPanel() as HTMLTextAreaElement;
    textArea.addEventListener('keyup', (e: KeyboardEventArgs) => {
      markDownConversion();
    });
    let rteObj: RichTextEditor = editor;
    mdsource = document.getElementById('preview-code');
    mdsource.addEventListener('click', (e: MouseEvent) => {
      fullPreview({ mode: true, type: 'preview' });
      if ((e.currentTarget as HTMLElement).classList.contains('e-active')) {
        editor.disableToolbarItem(['CreateTable']);
      } else {
        editor.enableToolbarItem(['CreateTable']);
      }
    });
  },
});
editor.appendTo('#editor');
function markDownConversion(): void {
  if (mdsource.classList.contains('e-active')) {
    let id: string = editor.getID() + 'html-view';
    let htmlPreview: HTMLElement = editor.element.querySelector('#' + id);
    htmlPreview.innerHTML = Marked(
      (editor.contentModule.getEditPanel() as HTMLTextAreaElement).value
    );
  }
}
function fullPreview(): void {
  let id: string = editor.getID() + 'html-preview';
  let htmlPreview: HTMLElement = editor.element.querySelector('#' + id);
  let previewTextArea: HTMLElement = editor.element.querySelector(
    '.e-rte-content'
  ) as HTMLElement;
  if (mdsource.classList.contains('e-active')) {
    mdsource.classList.remove('e-active');
    mdsource.parentElement.title = 'Preview';
    textArea.style.display = 'block';
    htmlPreview.style.display = 'none';
    previewTextArea.style.overflow = 'hidden';
  } else {
    mdsource.classList.add('e-active');
    if (!htmlPreview) {
      htmlPreview = createElement('div', {
        className: 'e-content e-pre-source',
      });
      htmlPreview.id = id;
      textArea.parentNode.appendChild(htmlPreview);
      previewTextArea.style.overflow = 'auto';
    }
    if (previewTextArea.style.overflow === 'hidden') {
      previewTextArea.style.overflow = 'auto';
    }
    textArea.style.display = 'none';
    htmlPreview.style.display = 'block';
    htmlPreview.innerHTML = Marked(
      (editor.contentModule.getEditPanel() as HTMLTextAreaElement).value
    );
    mdsource.parentElement.title = 'Code View';
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Rich Text Editor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-richtexteditor/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-popups/styles/material.css" rel="stylesheet" />
     <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
   
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='editor'></div>
    </div>
    <style>
        .e-richtexteditor textarea.e-content {
            float: left;
            border-right: 1px solid rgba(0, 0, 0, 0.12);
        }
        .e-richtexteditor .e-rte-content .e-content{
            min-height: 150px;
        }
    
        .e-richtexteditor .e-rte-content {
            overflow: hidden;
        }
    
        .e-icon-btn.e-active .e-md-preview::before {
            content: '\e350';
        }
    
        .e-icon-btn .e-md-preview::before {
            content: '\e345';
        }
    
        .e-rte-content .e-content {
            float: right;
            width: 50%;
            overflow: auto;
            height: inherit;
            padding: 8px;
            height: 100%;
        }
    
        .e-rte-content .e-content.e-pre-source {
            width: 100%;
        }
    
        .highcontrast .e-richtexteditor textarea.e-content {
            border-right: 1px solid #fff;
        }
    
        .sb-header {
            z-index: 100;
        }
    </style>
</body>

</html>

Changing default content

By default, when you insert a table, it comes with predefined column headers and structure. However, you can customize the table’s default content, including the heading and column names, to match your requirements.

The following example demonstrates how to customize the table content in the Markdown Editor:

import { enableRipple } from '@syncfusion/ej2-base';
enableRipple(true);

import {
  RichTextEditor,
  Link,
  Image,
  MarkdownEditor,
  Table,
  Toolbar,
} from '@syncfusion/ej2-richtexteditor';
import { createElement, KeyboardEventArgs } from '@syncfusion/ej2-base';
import Marked from 'marked';
import { L10n } from '@syncfusion/ej2-base';
L10n.load({
    'en-US': {
        'richtexteditor': {
            'TableHeadingText': 'Header',
            'TableColText': 'Cell'
         }
     }
});
RichTextEditor.Inject(Link, Image, MarkdownEditor, Table, Toolbar);

let textArea: HTMLTextAreaElement;
let mdsource: HTMLElement;
let htmlPreview: HTMLElement;

let editor: RichTextEditor = new RichTextEditor({
  value: `In Rich Text Editor, you click the toolbar buttons to format the words and the changes are visible immediately. Markdown is not like that. When you format the word in Markdown format, you need to add Markdown syntax to the word to indicate which words and phrases should look different from each other. Rich Text Editor supports markdown editing when the editorMode set as **markdown** and using both *keyboard interaction* and *toolbar action*, you can apply the formatting to text. You can add our own custom formation syntax for the Markdown formation, [sample link](https://ej2.syncfusion.com/home/). The third-party library <b>Marked</b> is used in this sample to convert markdown into HTML content.`,
  height: 250,
  editorMode: 'Markdown',
  toolbarSettings: {
    items: [
      'CreateTable',
      {
        tooltipText: 'Preview',
        template:
          '<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn">' +
          '<span class="e-btn-icon e-md-preview e-icons"></span></button>',
      },
    ],
  },
  created: () => {
    textArea = editor.contentModule.getEditPanel() as HTMLTextAreaElement;
    textArea.addEventListener('keyup', (e: KeyboardEventArgs) => {
      markDownConversion();
    });
    let rteObj: RichTextEditor = editor;
    mdsource = document.getElementById('preview-code');
    mdsource.addEventListener('click', (e: MouseEvent) => {
      fullPreview({ mode: true, type: 'preview' });
      if ((e.currentTarget as HTMLElement).classList.contains('e-active')) {
        editor.disableToolbarItem(['CreateTable']);
      } else {
        editor.enableToolbarItem(['CreateTable']);
      }
    });
  },
});
editor.appendTo('#editor');
function markDownConversion(): void {
  if (mdsource.classList.contains('e-active')) {
    let id: string = editor.getID() + 'html-view';
    let htmlPreview: HTMLElement = editor.element.querySelector('#' + id);
    htmlPreview.innerHTML = Marked(
      (editor.contentModule.getEditPanel() as HTMLTextAreaElement).value
    );
  }
}
function fullPreview(): void {
  let id: string = editor.getID() + 'html-preview';
  let htmlPreview: HTMLElement = editor.element.querySelector('#' + id);
  let previewTextArea: HTMLElement = editor.element.querySelector(
    '.e-rte-content'
  ) as HTMLElement;
  if (mdsource.classList.contains('e-active')) {
    mdsource.classList.remove('e-active');
    mdsource.parentElement.title = 'Preview';
    textArea.style.display = 'block';
    htmlPreview.style.display = 'none';
    previewTextArea.style.overflow = 'hidden';
  } else {
    mdsource.classList.add('e-active');
    if (!htmlPreview) {
      htmlPreview = createElement('div', {
        className: 'e-content e-pre-source',
      });
      htmlPreview.id = id;
      textArea.parentNode.appendChild(htmlPreview);
      previewTextArea.style.overflow = 'auto';
    }
    if (previewTextArea.style.overflow === 'hidden') {
      previewTextArea.style.overflow = 'auto';
    }
    textArea.style.display = 'none';
    htmlPreview.style.display = 'block';
    htmlPreview.innerHTML = Marked(
      (editor.contentModule.getEditPanel() as HTMLTextAreaElement).value
    );
    mdsource.parentElement.title = 'Code View';
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Rich Text Editor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-richtexteditor/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-popups/styles/material.css" rel="stylesheet" />
     <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
   
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
        <div id='editor'> </div>
    </div>
    <style>
        .e-richtexteditor textarea.e-content {
            float: left;
            border-right: 1px solid rgba(0, 0, 0, 0.12);
        }
        .e-richtexteditor .e-rte-content .e-content{
            min-height: 150px;
        }
    
        .e-richtexteditor .e-rte-content {
            overflow: hidden;
        }
    
        .e-icon-btn.e-active .e-md-preview::before {
            content: '\e350';
        }
    
        .e-icon-btn .e-md-preview::before {
            content: '\e345';
        }
    
        .e-rte-content .e-content {
            float: right;
            width: 50%;
            overflow: auto;
            height: inherit;
            padding: 8px;
            height: 100%;
        }
    
        .e-rte-content .e-content.e-pre-source {
            width: 100%;
        }
    
        .highcontrast .e-richtexteditor textarea.e-content {
            border-right: 1px solid #fff;
        }
    
        .sb-header {
            z-index: 100;
        }
    </style>
</body>

</html>