blgrnboy
blgrnboy

Reputation: 5157

Froala Angular Text Editor (v3) - Destroy and re-Initialize on input changes

I am creating a re-usable Angular component which is it charge for rendering the Froala Text Editor in an Angular application. I have everything working in terms of component first render initialization, but I am trying to account for some component inputs changing after the component has been initialized, and destroying then re-initializing the text-editor based on those inputs (which result in change of text editor options).

Here is my what I am trying, which again, works for the initial render, but does not when an input is changed at a later time (I am changing characterCountMax to a new value 5 seconds after the initial render). The documentation for this Angular integration (https://github.com/froala/angular-froala-wysiwyg#manual-initialization) of their raw javascript library is quite really bare, and doesn't cover this, so I am hoping someone else has done this.

Component Template:

<div [hidden]="!isInitialized" [froalaEditor]="editorOptions" (froalaInit)="initialize($event)" (froalaModelChange)="onContentChanged($event)"></div>

Component TS:

import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core';
import { TextEditorOptions } from './text-editor-options';
import { TextEditorToolbarButtons, defaultTextEditorToolbarButtons } from './text-editor-toolbar-buttons.enum';

@Component({
  selector: 'app-text-editor',
  templateUrl: './text-editor.component.html',
  styleUrls: ['./text-editor.component.css']
})
export class TextEditorComponent implements OnInit, OnChanges {
  @Input() placeholderText = 'Insert text here...';
  @Input() showCharacterCount = false;
  @Input() characterCountMax = 1000;
  @Input() heightMin = 300;
  @Input() toolbarButtons: Array<TextEditorToolbarButtons> = defaultTextEditorToolbarButtons;
  public editorOptions: TextEditorOptions;
  public isInitialized = true;
  private froalaControl: any;

  constructor() { }

  ngOnInit() {
    this.updateEditorOptions();
  }

  ngOnChanges(changes: SimpleChanges) {
    this.updateEditorOptions();
  }

  public initialize(initControls: any) {
    console.log('initializing');
    this.froalaControl = initControls;
    if (this.froalaControl) {
      this.froalaControl.initialize();
    }
  }

  public onContentChanged(text: string) {
    console.log(text);
  }

  private updateEditorOptions() {
    if (!this.toolbarButtons) {
      this.toolbarButtons = defaultTextEditorToolbarButtons;
    }

    this.editorOptions = {
      placeholderText: this.placeholderText,
      attribution: false,
      charCounterCount: this.showCharacterCount,
      charCounterMax: this.characterCountMax,
      heightMin: this.heightMin,
      toolbarButtons: this.toolbarButtons,
      toolbarButtonsXS: this.toolbarButtons,
      toolbarButtonsSM: this.toolbarButtons,
      toolbarButtonsMD: this.toolbarButtons
    };

    if (this.froalaControl) {
      const editor = this.froalaControl.getEditor();
      if (editor) {
        this.isInitialized = false;
        if (editor.opts) {
          editor.opts = Object.assign(editor.opts, this.editorOptions);
        }
        this.froalaControl.destroy();
        this.initialize(this.froalaControl);
        this.isInitialized = true;
      }
    }
  }
}

Upvotes: 4

Views: 2311

Answers (1)

JDay
JDay

Reputation: 31

Here is a example, where I change the language from outside the editor. I use a time out between the destoy of the editor and the initialization.

Markup

<div class="na-froala-editor" *ngIf="options && isInitialized"
  [froalaEditor]="options"
  (froalaInit)="initialize($event)"
  [froalaModel]="editorContent$ | async"
  (froalaModelChange)="froalaModelChange($event)">
</div>

Code

@Input()
public set language(language: string) {
  this.languageVal = language;

  // When the language change after the initialisation ( option is already set)
  // We need to destroy the froalaEditor and initialize it again
  if (this.options && this.froalaControl) {
    this.options.language = language;
    const editor = this.froalaControl.getEditor();
    if (editor) {
      this.isInitialized = false;
      this.froalaControl.destroy();
      // Delay is necessary to let the froala editor finish to destroy
      setTimeout(() => {
        if (editor.opts) {
          editor.opts = this.options;
        }
        this.initialize(this.froalaControl);
        this.isInitialized = true;
      }, 100);
    }
  }
}

public initialize(initControls) {
  this.froalaControl = initControls;
  if (this.froalaControl) {
    this.froalaControl.initialize();
  }
}

Upvotes: 3

Related Questions