简体   繁体   中英

TinyMCE 5.x - Highlight an item in a custom dropdown menu

I have 3 menu items in a custom TinyMCE 5.x dropdown that controls the width of the editor. I want to indicate what the current selection is, but can't find a way to interact with the menu items after they are initialized. When the menu is closed they don't seem to be in the DOM at all.

I would be happy if my custom dropdown behaved like the font-size dropdown, which displays a check mark next to the selected size. I would also be happy with it being like the font-family dropdown where the selected font is displayed as the menu toggle (not just when you open the menu).

editor.ui.registry.addMenuButton('maxWidth', {
                        text: 'Width',
                        fetch: function( callback ){
                            var items = [
                                {
                                    type: 'menuitem',
                                    text: 'Full Width',
                                    onAction: function(){   changeSectionWidth("full");     }
                                },
                                {
                                    type: 'menuitem',
                                    text: '1600',
                                    onAction: function(){   changeSectionWidth(1600);   }
                                },
                                {
                                    type: 'menuitem',
                                    text: '1170',
                                    onAction: function(){   changeSectionWidth(1170);   }
                                },
                            ];
                            callback(items);
                        },
                    });

After looking all over and finding nothing useful, I hacked it together, which I am not happy about, but it does work:

    //LOCATE THE BUTTON GROUP (happens to be in group 12, starts on 0 though)
    let btnGroup = $(editor.editorContainer).find(".tox-toolbar__group")[11];
    if( btnGroup ){
        return false;
    }

    //GET THE SPECIFIC BUTTON IN THAT GROUP (happens to be in slot 4, starts on 0)
    let targetBTN = $(btnGroup).children()[3];

    //CLICK HANDLER FOR THE SPECIFIC MENUBUTTON
    $(targetBTN).on("click", function(){ 

        //USE A TIMER SO TinyMCE HAS TIME TO RENDER THE MENU
        window.setTimeout( function(){

            //APPLY YOUR OWN LOGIC HERE TO DETERMINE WHICH OPTION TO SELECT
            //this has to match the words in the button and is case-sensitive
            let selectedOption = "Option 2"; 

            //DESELECT OTHER OPTIONS
            //NOTE THAT I AM USING AN EXTRA CLASS "my-selected" WHICH I APPLIED TO THE UI SKIN.min.css BECAUSE HOVER DESELECTED THEIR HIGHLIGHTS AND I WANTED IT MORE PERMANENT
            $(".tox-selected-menu .tox-collection__item--active").removeClass("tox-collection__item--active tox-collection__item--enabled my-selected");

            $('.tox-collection__item[title="'+selectedOption+'"]').addClass("tox-collection__item--active tox-collection__item--enabled my-selected");

        }, 50); //WAIT 50 milliseconds so menu has time to be rendered

});

Edit: I know this is old, but might help others.

This can be done using formats and hooking into onSetup on each menu item. See below working example.

editor.ui.registry.addMenuButton('maxWidth', {
  text: 'Width',
  fetch: callback => {
    // Define out options for width.
    var widthOptions = [
      {
        title: 'Full width',
        format: 'full_width',
      },
      {
        title: 'Width 2',
        format: 'width2',
      },
      {
        title: 'Width 3',
        format: 'width3',
      },
    ];

    var items = [];

    // Add each option to menu items.
    widthOptions.forEach(option => {
      // Register a custom format for each option.
      // See https://www.tiny.cloud/docs/configure/content-formatting/#formats
      editor.formatter.register(option.format, {
        inline: 'span',
        classes: option.format,
      });

      items.push({
        type: 'togglemenuitem',
        text: option.title,
        onAction: action => {
          // We only allow one to be selected. Remove all but the one we clicked.
          widthOptions.forEach(opt => {
            if (
              option.format !=
              opt.format
            ) {
              tinymce.activeEditor.formatter.remove(
                opt.format,
              );
            }
          });

          // Now toggle the selected one.
          editor.execCommand(
            'FormatBlock',
            false,
            option.format,
          );
        },
        onSetup: function(api) {
          // When generating the item, check if this one is selected.
          if (
            editor.formatter.match(
              option.format,
            )
          ) {
            api.setActive(true);
          }

          return function() {};
        },
      });
    });

    callback(items);
  },
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM