Search code examples
javascriptangulartypescriptsummernote

Summernote custom button pass context and data


I am using summernote in angular I want to create a custom button.

I would like to pass the listHit in customButton as parameter like this 'testBtn': this.customButton(context, listHit) but I am not sure how to do this since the function looks like this 'testBtn': this.customButton any help would be appreciated thank you.

My custom button looks something like this.

  customButton(context) {    
    
    var listHit = ['One', 'Two', 'Tree'];
    
    const ui = ($ as any).summernote.ui;
    var i;
    var listHitHtml = "";
    for (i = 0; i < listHit.length; i++) {
      listHitHtml += "<li>" + listHit[i] + "</li>";
    }


    var button = ui.buttonGroup([
      ui.button({
        className: 'dropdown-toggle',
        contents: '<i class="fa fa-comments"/><span class="caret"></span>',
        tooltip: '@erp_colombia.Lang.Resource.conAvailableComments',
        data: {
          toggle: 'dropdown'
        }
      }),
      ui.dropdown({
        className: 'drop-default summernote-list',
        contents: "<div id=\"container-comentario\"><div id=\"dialog\" title=\"Comentarios\" ><h1 class=\"header-comentario\">" + 'Comment' + "</h1><ul id=\"liste-comentarios\"><ul>" + listHitHtml + "</ul></div></div>",
        callback: function ($dropdown) {
          $dropdown.find('li').each(function () {
            $(this).click(function () {
              context.invoke("editor.insertText", $(this).html() + "\n");
            });
          });
        }
      })
    ]);

    return button.render();   // return button as jquery object
  }

Here is my pdfmaker config

  this.config = {
    placeholder: placeholder,
    shortcuts: false,
    disableDragAndDrop: true,
    //tabsize: 2,
    hint: {
      mentions: this.quoteCommentsForSummerNote,
      match: /\b(\w{1,})$/,
      search: function (keyword, callback) {
        callback($.grep(this.mentions, function (item: any) {
          return item.indexOf(keyword) == 0;
        }));
      },
      content: function (item) {
        return item;
      }
    },
    height: 200,
    toolbar: [
      ['myotherbutton', ['testBtn']],
    ],
    buttons: {
      'testBtn': this.customButton
    }
  }

And this is my angular html

Here you can fiddle with a example I created a list that we will assume comes from a service I would like to pass this list to customButton

  listStringFromDbService = ['one', 'two', 'three'];

https://stackblitz.com/edit/angular-summernote-demo-gdvvbn?file=src%2Fapp%2Fapp.component.ts


Solution

  • I believe I figured this out.

    You can change your button declaration to a function that returns a button function. That way you can pass data to it before constructing the function that Evernote binds to testBtn.

    Change the function declaration (expression or declaration will work, like you pointed out)

    function customButtonGenerator(arr) {
      return function (context) {
        const ui = $.summernote.ui;
        const button = ui.button({
          contents: '<i class="note-icon-magic"></i> Hello',
          tooltip: 'Custom button',
          container: '.note-editor',
          className: 'note-btn',
          click: function () {
            context.invoke('editor.insertText', 'Hello from test btn!!! ' + arr);
          },
        });
        return button.render();
      };
    };
    

    then when you create the ui config you can generate the button function instead:

    buttons: {
          testBtn: customButtonGenerator(this.listStringFromDbService),
        },
    

    Here's an updated stackblitz showing a working example.