Search code examples
jqueryautocompletetinymcewysiwygtinymce-5

Tinymce insert link autocomplete from db


I use the tinymce editor. How can i insert a page link from my db with autocomplete..

I will type a few letters and tinymce editor will filter my database contents. I will choose one and it will automatically create the link.

https://jqueryui.com/autocomplete/

Ajax autocomple and tinymce plugins. I haven't found a solution yet.


Solution

  • The native Autocompleter feature of TinyMCE should be sufficient.

    You can put any HTML code into an autocompleter. E.g., this code can automatically add links to Amazon.com, Yahoo.com, and Google.com:

    const mySites = [
      { text: 'yahoo', name: 'Yahoo', value: '<a href = "https://yahoo.com">Yahoo!</a>' },
      { text: 'amazon', name: 'Amazon', value: '<a href = "https://amazon.com">Amazon!</a>' },
      { text: 'google', name: 'Google', value: '<a href = "https://google.com">Google!</a>' }
    ];
    tinymce.init({
      selector: 'textarea#autocompleter-cardmenuitem',
      height: 250,
      setup: (editor) => {
        const onAction = (autocompleteApi, rng, value) => {
          editor.selection.setRng(rng);
          editor.insertContent(value);
          autocompleteApi.hide();
        };
    
        const getMatchedChars = (pattern) => {
          return mySites.filter(char => char.text.indexOf(pattern) !== -1);
        };
    
        /**
         * An autocompleter that allows you to insert special characters.
         * Items are built using the CardMenuItem.
         */
        editor.ui.registry.addAutocompleter('mySites_cardmenuitems', {
          ch: ':',
          minChars: 1,
          columns: 1,
          highlightOn: ['char_name'],
          onAction: onAction,
          fetch: (pattern) => {
            return new Promise((resolve) => {
              const results = getMatchedChars(pattern).map(char => ({
                type: 'cardmenuitem',
                value: char.value,
                label: char.text,
                items: [
                  {
                    type: 'cardcontainer',
                    direction: 'vertical',
                    items: [
                      {
                        type: 'cardtext',
                        text: char.text,
                        name: 'char_name'
                      },
                      {
                        type: 'cardtext',
                        text: char.name
                      }
                    ]
                  }
                ]
              }));
              resolve(results);
            });
          }
        });
      }
    });
    <script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/6/tinymce.min.js"></script>
    
    <textarea id="autocompleter-cardmenuitem">
      <p>Type <b>-</b> below and then keep typing to reduce further matches. For example, typing <b>:goo</b> should show the "Google" item in the menu. Pressing esc should close the autocomplete menu.</p>
      <p></p>
    </textarea>

    It won't run here, but you can test it on CodePen.