如何在Froala Editor中实现多级下拉菜单?

问题描述 投票:0回答:1

我在我的项目中使用 Froala Editor,并且我已经使用编辑器的 API 成功实现了自定义简单下拉列表。但是,我需要创建一个多级下拉菜单(手风琴样式),其中每个顶级选项都可以有自己的子选项。

这是我目前用于简单自定义下拉列表的代码:

FroalaEditor.DefineIcon('my_dropdown', { NAME: 'cog', SVG_KEY: 'cogs' });
FroalaEditor.RegisterCommand('my_dropdown', {
  title: 'Advanced options',
  type: 'dropdown',
  focus: false,
  undo: false,
  refreshAfterCallback: true,
  options: {
    'v1': 'Option 1',
    'v2': 'Option 2'
  },
  callback: function (cmd, val) {
    console.log(val);
  },
  refresh: function ($btn) {
    console.log('do refresh');
  },
  refreshOnShow: function ($btn, $dropdown) {
    console.log('do refresh when show');
  }
});

new FroalaEditor('div#froala-editor', {
  toolbarButtons: ['bold', 'italic', 'formatBlock', 'my_dropdown']
})`;

我想扩展此功能以支持多级下拉菜单。例如:

Level 1 - Option 1
Level 1 - Option 2
    Level 2 - Option 1
    Level 2 - Option 2
Level 1 - Option 3

我尝试修改refreshOnShow函数以包含多级下拉列表的嵌套HTML,并添加事件处理程序来管理子选项的显示和隐藏。这是我的尝试:

FroalaEditor.DefineIcon('my_multilevel_dropdown', { NAME: 'list', SVG_KEY: 'list' });

FroalaEditor.RegisterCommand('my_multilevel_dropdown', {
  title: 'Advanced options',
  type: 'dropdown',
  focus: false,
  undo: false,
  refreshAfterCallback: true,
  options: {
    'level1_option1': 'Level 1 - Option 1',
    'level1_option2': 'Level 1 - Option 2',
    'level1_option3': 'Level 1 - Option 3'
  },
  callback: function (cmd, val) {
    console.log('Selected:', val);
  },
  refresh: function ($btn) {
    console.log('do refresh');
  },
  refreshOnShow: function ($btn, $dropdown) {
    console.log('do refresh when show');

    // Add custom HTML for multi-level dropdown
    $dropdown.html(`
      <div class="fr-dropdown-wrapper">
        <div class="fr-command fr-dropdown-item" data-cmd="level1_option1">Level 1 - Option 1</div>
        <div class="fr-command fr-dropdown-item" data-cmd="level1_option2">Level 1 - Option 2</div>
        <div class="fr-command fr-dropdown-item" data-cmd="level1_option3">Level 1 - Option 3
          <div class="fr-submenu">
            <div class="fr-command" data-cmd="level2_option1">Level 2 - Option 1</div>
            <div class="fr-command" data-cmd="level2_option2">Level 2 - Option 2</div>
          </div>
        </div>
      </div>
    `);

    // Debug: Check if elements are found
    var $commands = $dropdown.find('.fr-command');
    console.log($commands.length + ' commands found.');

    // Add accordion behavior
    $commands.off('click').on('click', function (event) {
      var $this = $(this);
      var $submenu = $this.children('.fr-submenu');

      if ($submenu.length) {
        event.stopPropagation();
        $submenu.slideToggle();
        $this.siblings().find('.fr-submenu').slideUp();
      } else {
        var cmd = $this.data('cmd');
        $this.closest('.fr-dropdown-wrapper').trigger('click.command', [cmd]);
      }
    });
  }
});

new FroalaEditor('#froala-editor', {
  toolbarButtons: ['bold', 'italic', 'formatBlock', 'my_multilevel_dropdown']
});
froala
1个回答
0
投票

您走在正确的道路上!

您在 Froala Editor 中创建多级下拉列表所采用的方法是一种很好的方法。以下是您的代码的细分以及一些使其顺利运行的改进: 了解代码

DefineIcon:这为您的下拉按钮注册一个自定义图标。

RegisterCommand:这就是神奇发生的地方。您定义:

  • title:按钮上显示的名称。

  • type:设置为“下拉”以获取下拉菜单。

  • 选项:这些是下拉菜单的顶级选项。

  • 回调:当顶级选项被执行时,执行此函数 已选择。

  • refreshOnShow:这对于动态生成 多层次结构。

  • refreshOnShow 函数:这是您构建 HTML 的地方 多级下拉菜单。

动态子菜单生成:

与其在refreshOnShow中对子菜单结构进行硬编码,不如根据您的数据结构使其更加动态。

refreshOnShow: function ($btn, $dropdown) {
    // Assuming you have a data structure like this:
    const menuData = {
      'level1_option1': 'Level 1 - Option 1',
      'level1_option2': {
        title: 'Level 1 - Option 2',
        suboptions: {
          'level2_option1': 'Level 2 - Option 1',
          'level2_option2': 'Level 2 - Option 2'
        }
      },
      'level1_option3': 'Level 1 - Option 3'
    };
  
    // Build the dropdown HTML
    let html = '';
    for (const key in menuData) {
      const item = menuData[key];
      html += `<div class="fr-command fr-dropdown-item" data-cmd="${key}">${item.title || item}</div>`;
      if (item.suboptions) {
        html += `<div class="fr-submenu">`;
        for (const subkey in item.suboptions) {
          html += `<div class="fr-command" data-cmd="${subkey}">${item.suboptions[subkey]}</div>`;
        }
        html += `</div>`;
      }
    }
  
    $dropdown.html(html);
  
    // ... (rest of your accordion behavior code)
  }

手风琴行为: 你的手风琴逻辑很好。这是一个稍微改进的版本:

$commands.off('click').on('click', function (event) {
  var $this = $(this);
  var $submenu = $this.children('.fr-submenu');

  if ($submenu.length) {
    event.stopPropagation();
    $submenu.slideToggle();
    $this.siblings().find('.fr-submenu').slideUp();
  } else {
    // Handle top-level option selection
    var cmd = $this.data('cmd');
    $this.closest('.fr-dropdown-wrapper').trigger('click.command', [cmd]);
  }
});

造型

您可能需要添加一些 CSS 来设置多级下拉菜单的样式,以匹配您的 Froala 编辑器主题。

您可以在 Froala 文档中查看更多选项。

© www.soinside.com 2019 - 2024. All rights reserved.