ckeditor / ckeditor5-angular

Official CKEditor 5 Angular 5+ component.
https://ckeditor.com/ckeditor-5
Other
205 stars 111 forks source link

Mention plugin implementation dynamically #228

Open martin11cortes opened 4 years ago

martin11cortes commented 4 years ago

I have successfully implemented the editor and the mention plugin with the static feed array, but now I need to change the mention feed to be provided by and http request, as I followed the docs it's either static array or callback function here

As pointed here, there's a way to add new mention feed records, but its not working for me, I hope you could help me

Below I place my code with comments in the sections where I understood it should be implemented

import { Component, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import * as Editor from '../../../ckeditor5/build/ckeditor';
import { Observable } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { CKEditorComponent } from '@ckeditor/ckeditor5-angular';

@Component({
  selector: 'app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class MyComponent implements OnInit {
  public Editor = Editor;
  public editorConfig = {
    toolbar: {
      items: [
        'heading',
        '|',
        'bold',
        'italic',
        'link',
        'bulletedList',
        'numberedList',
        '|',
        'indent',
        'outdent',
        '|',
        'imageUpload',
        'blockQuote',
        'insertTable',
        'undo',
        'redo',
        '|',
        'alignment',
        'fontBackgroundColor',
        'fontColor',
        'fontSize',
        'highlight',
        'fontFamily',
        'horizontalLine'
      ]
    },
    mention: {
      feeds: [
        {
          marker: '@',
          feed: ['@Barney', '@Lily', '@Marshall', '@Robin', '@Ted'], //**these ones work just fine**
          minimumCharacters: 1
        }
      ]
    },
    language: 'es',
    image: {
      toolbar: [
        'imageTextAlternative',
        'imageStyle:full',
        'imageStyle:side'
      ]
    },
    table: {
      contentToolbar: [
        'tableColumn',
        'tableRow',
        'mergeTableCells',
        'tableCellProperties',
        'tableProperties'
      ]
    },
    licenseKey: '',
  }

  @ViewChild('editor') editorComponent: CKEditorComponent

  constructor(
    private http: HttpClient,
    private router: Router,
    private route: ActivatedRoute) {

  }

  onReady(editor): void {
    editor.ui.getEditableElement().parentElement.insertBefore(
      editor.ui.view.toolbar.element,
      editor.ui.getEditableElement()
    )
  }

  getEditor() {
    return this.editorComponent.editorInstance
  }

  ngOnInit(): void {
    this.getMyFeed().subscribe(response => {
      // response holds my custom feed records
      this.getEditor().execute( 'mention', { marker: '@', mention: '@SomeNewName' } ); // this one is not working
    })
  }

  onSubmit() {
  }

  getMyFeed(): Observable<any> {
    return this.http.get<object>(myUrl)
  }
}
ma2ciek commented 4 years ago

I guess that this can be due to the fact that the ngOnInit fires before the editor instance is created. You should put this logic to the onReady(editor) {} callback as you want to change the behavior of the editor when it's ready.

martin11cortes commented 4 years ago

I guess that this can be due to the fact that the ngOnInit fires before the editor instance is created. You should put this logic to the onReady(editor) {} callback as you want to change the behavior of the editor when it's ready.

Thanks for your reply Already tried that, but is not working either way

onReady(editor): void {
    editor.ui.getEditableElement().parentElement.insertBefore(
      editor.ui.view.toolbar.element,
      editor.ui.getEditableElement()
    )

    this.getMyFeed().subscribe(response => {
      // {response} holds my custom feed records
      // how to add {response} to the mention list?

      this.getEditor().execute( 'mention', { marker: '@', mention: '@SomeNewName' } ); // this one is not working either
    })
}
ma2ciek commented 4 years ago
 // this one is not working either

Is there an error? Or nothing happens after using this.getEditor().execute( 'mention', { marker: '@', mention: '@SomeNewName' } ); ?

There could be just editor.execute( 'mention', { marker: '@', mention: '@SomeNewName' } );

ma2ciek commented 4 years ago

Hm, I've read docs once again and I feel that you should do it as well :sweat_smile:

The 'mention' command implemented by MentionCommand.

You can insert a mention element by executing the following code:

The MentionCommand inserts the mention directly into the editor's content. It doesn't change the feed.

So the only way to feed the editor dynamically with elements should be done using the callback as described in https://ckeditor.com/docs/ckeditor5/latest/features/mentions.html#providing-the-feed

Diego-EC commented 3 years ago

Hi @martin11cortes. Did you manage to solve the problem? I have had this same problem last week, and I finally managed to solve it. In my case I got it by using a Promise() instead of an observable. I hope you find it useful.