tinymce Editor Library files not load when tab is inactive in Angular 5

1k Views Asked by At

I want to use tinymce editor in Angular 5 on mat-tab. But when the tab is inactive it can't load the scripts files which will required for the tinymce editor. Here is my HTML Code

<mat-tab-group>
    <mat-tab label="Document Info">
        <p> This is document information </p>
    </mat-tab>
    <mat-tab label="Add Note">
        <div>
            <h3 for="post-body">Editor</h3>
            <text-editor [elementId]="'post-body' (onEditorKeyup)="onBody($event)">
            </text-editor>
        </div>
    </mat-tab>
</mat-tab-group>
2

There are 2 best solutions below

1
On

After spending some time testing I came up with a simple solution. Please feel free to make alterations and provide a better solution to the community as this solution is rather a quick tactical fix than solving the actual problem.

At the top of your component file, below your imports, add the following declaration:

declare var tinymce: any; 

In your class, create new properties.

tabIndex: number;
content: string = '&nbsp;'; 

Add the following function to your class. The specified tabIndex would be the tab the editor resides in. The tab indexing starts with 0 (being the first tab).

tabChanged() {
  if ( this.tabIndex == 1 ) {
    tinymce.execCommand("mceToggleEditor", false, 'content');
  } else {
    tinymce.remove();
  }
} 

Change your mat-tab-group element to the following.

<mat-tab-group [(selectedIndex)]="tabIndex" (selectedTabChange)="tabChanged()">  

If your editor renders with a textarea inside, make sure you have some default content to load e.g. &nbsp; for records that does not have a value yet.

<editor placeholder="Content" [(ngModel)]="content" name="content" id="content" #content [init]="{skin_url: '/assets/skins/lightgray', plugins: 'link,image', height: '450'}"></editor>  

That's it.

0
On

Use Multiple instances of tinymce

import 'tinymce/tinymce.min.js';
import 'tinymce/themes/modern/theme';
import '../assets/emoticons/plugin.js';
import 'tinymce/plugins/paste/plugin.js';
import 'tinymce/plugins/link/plugin.js';
import 'tinymce/plugins/autoresize/plugin.js';
import 'tinymce/plugins/image/plugin.js';
import 'tinymce/plugins/imagetools/plugin.js';
import 'tinymce/plugins/searchreplace/plugin.js';
import 'tinymce/plugins/autolink/plugin.js';
import 'tinymce/plugins/fullscreen/plugin.js';
import 'tinymce/plugins/media/plugin.js';
import 'tinymce/plugins/table/plugin.js';
import 'tinymce/plugins/hr/plugin.js';
import 'tinymce/plugins/insertdatetime/plugin.js';
import 'tinymce/plugins/advlist/plugin.js';
import 'tinymce/plugins/lists/plugin.js';
import 'tinymce/plugins/textcolor/plugin.js';
import 'tinymce/plugins/contextmenu/plugin.js';
import 'tinymce/plugins/colorpicker/plugin.js';
import 'tinymce/plugins/help/plugin.js';

declare var tinymce: any;


public notes = {
    selector: '#notes',
    height: 500,
    width: '40%',
    skin_url: 'skins/lightgray',
    plugins_url: '/test/',
    document_base_url: 'assets',
    plugins: [
      'emoticons',
      'paste',
      'link',
      'autoresize',
      'image',
      'imagetools',
      'searchreplace',
      'autolink',
      'fullscreen',
      'media',
      'table',
      'hr',
      'insertdatetime',
      'advlist',
      'lists',
      'textcolor',
      'contextmenu',
      'colorpicker',
      'help'
    ],
    toolbar1: 'newdocument fullscreen media | \
     emoticons | undo redo cut copy paste pastetext | \
     formatselect fontsizeselect subscript superscript | \
     bold italic strikethrough forecolor backcolor | link | \
     alignleft aligncenter alignright alignjustify  | \
     numlist bullist outdent indent  | removeformat | image | help',
    image_advtab: true,
    imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions',
    paste_data_images: true
  };


  public details = {
    selector: '#opportunity',
    height: 500,
    width: '40%',
    skin_url: 'skins/lightgray',
    plugins_url: '/test/',
    document_base_url: 'assets',
    plugins: [
      'emoticons',
      'paste',
      'link',
      'autoresize',
      'image',
      'imagetools',
      'searchreplace',
      'autolink',
      'fullscreen',
      'media',
      'table',
      'hr',
      'insertdatetime',
      'advlist',
      'lists',
      'textcolor',
      'contextmenu',
      'colorpicker',
      'help'
    ],
    // tslint:disable-next-line:max-line-length
    // toolbar2: 'formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify  | numlist bullist outdent indent  | removeformat',
    toolbar1: 'newdocument fullscreen media | emoticons | undo redo cut copy paste pastetext | \
    formatselect fontsizeselect subscript superscript | \
     bold italic strikethrough forecolor backcolor | link | \
     alignleft aligncenter alignright alignjustify  | \
     numlist bullist outdent indent  | removeformat | image | help',
    image_advtab: true,

    imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions',
    paste_data_images: true
  };



 public ngAfterViewInit(): void {

    tinymce.init(this.details); //to show on first tab initially

  }

In your mat-tab-group use a tab change function passing it the event

<mat-tab-group #tabGroup (selectedTabChange)="tabSwitch($event)">

**Then the function processing the event gets rid of previous instances before initializing another*

tabSwitch(tabEvent: MatTabChangeEvent) {
    switch (tabEvent.index) {

      case (0):
        tinymce.remove();
        tinymce.init(this.details);
        break;

      case (2):
        tinymce.remove();
        tinymce.init(this.notes);
        break;

      default:
        tinymce.remove();
        break;
    }
  }