LeO
LeO

Reputation: 5238

Angular mat-tab-group and tinyMCE

I want to place an instance of tinyMCE on a tab-group. On one tab I have tinyMCE on another just a regular textarea. Switching the tabs causes a failure in tinyMCE and the content is not any longer editable - if tinyMCE is displayed at all. Looking for solution I come up with the following:

  <mat-tab-group animationDuration="0ms" (selectedIndexChange)="unloadTinyMce($event)"
      (animationDone)="updateEditor()">
      <mat-tab label="HTML Cover">
        <editor id="tinyMCE" [init]="tinyMceSettings.defaultWithInlineImages" [ngModelOptions]="{standalone: true}"
          [(ngModel)]="myEntity.textHtml"></editor>
      </mat-tab>
      <mat-tab label="PDF Cover">
        <mat-form-field appearance="outline">
          <mat-label i18n>Text for PDF</mat-label>
          <textarea matInput rows="10" i18n-placeholder="Text for PDF" placeholder="Text for PDF"
            [(ngModel)]="myEntity.textText"> </textarea>
        </mat-form-field>
      </mat-tab>
    </mat-tab-group>

So basically following different hints that I should unload tinyMCE when switching the tab and loading when switching back. When animation ends the content is reloaded. I figured out that it has to set to 0ms otherwise it won't work.

  unloadTinyMce(value): void {
    this.currentTabIndex = value;
    console.log('tab sel:' + value)
  }

  updateEditor() {
    console.log('finished animation ')
    if (this.currentTabIndex == 0) {
      const settings = Object.assign({}, TinyMceSettings.defaultWithInlineImages, { selector: '#tinyMCE' });
      tinymce.init(settings)
    } else {
      tinymce.remove('tinyMCE'); //the id of your textarea
    }
  }

So, right now I have the following three major issues:

  1. The content of tinyMCE is not editable
  2. I have no clue how to bind the content to the ngModel - in specific to myEntity.textHTML
  3. Sometimes it fails to load the settings sometimes not. I guess that's some sort of timing.

Is there a working code how to use tinyMCE on a mat-tab-group?

Upvotes: 2

Views: 1834

Answers (2)

Joel Kesler
Joel Kesler

Reputation: 166

A simple solution is to lazy-load the mat-tab content.

This forces the tab content (and tinyMCE) to be rebuild when you change tabs:

<mat-tab-group #tabGroup (selectedTabChange)="handleTabChange($event)">
  <mat-tab label="First Tab">
    <ng-template matTabContent>
      <editor [apiKey]="apiKey" [(ngModel)]="firstEditorValue"></editor>
    </ng-template>
  </mat-tab>

  <mat-tab label="Second Tab">
    <ng-template matTabContent>
      <editor [apiKey]="apiKey" [(ngModel)]="secondEditorValue"></editor>
    </ng-template>
  </mat-tab>
</mat-tab-group>

Docs: https://material.angular.io/components/tabs/overview#lazy-loading

Upvotes: 4

LeO
LeO

Reputation: 5238

I followed simply the StoryBook from the Angular/tinyMCE component. The solution simply enables or disables in the mat-tab-group the component with the editor, i.e.

<mat-tab-group #tabGroup (selectedTabChange)="handleTabChange($event)">
  <mat-tab label="First Tab">
    <editor [(ngModel)]="firstEditorValue" *ngIf="activeTabIndex===0"></editor>
  </mat-tab>

  <mat-tab label="Second Tab">
    <editor [(ngModel)]="secondEditorValue" *ngIf="activeTabIndex===1"></editor>
  </mat-tab>
</mat-tab-group>

and

  @ViewChild('tabGroup', { static: false }) public tabGroup: any;
  public activeTabIndex: number | undefined = undefined;
  public firstEditorValue = '';
  public secondEditorValue = '';

  public handleTabChange(e: MatTabChangeEvent) {
    this.activeTabIndex = e.index;
  }

  public ngAfterViewInit() {
    this.activeTabIndex = this.tabGroup.selectedIndex;
  }

On stackblitz is also a working example. The summary here is just for sake of clarity if someone else don't want to look first in github and stumbles herein.

Upvotes: 6

Related Questions