7

我正在尝试修改 TinyMCE 4“链接”插件,以允许用户从由 AJAX 请求动态更新的 ListBox 元素中选择内容。

我在 editor.windowManager.open() 之前创建了 ListBox 元素,因此它们最初被正确渲染。我有一个执行 AJAX 请求并获得 JSON 格式响应的 onselect 处理程序。

我需要对 JSON 响应做的是让它更新另一个 ListBox 元素,用新结果替换现有项目。

我很困惑,文档非常不清楚。我不知道是否应该替换整个控件,或者删除项目然后添加新项目。我不知道是否需要实例化一个新的 ListBox 控件,或者将其渲染为 HTML 等。

基本上,我可以访问原始呈现的 ListBox(名称:“模块”}

win.find('#module');

我有来自 AJAX 请求的新值:

var data = tinymce.util.JSON.parse(text).data;

我已经尝试创建一个新的 Control 配置对象,比如

newCtrlconfig = {
    type: 'listbox',
    label: 'Class',
    values: data
};

但我不知道如何渲染它,更不用说替换现有的了。

我试过了

var newList = tinymce.ui.Factory.create(newCtrlconfig);

接着

newList.renderHtml()

但即便如此,呈现的 HTML 也不包含项目的任何标记。检查这些对象只是令人沮丧:有“设置”、“值”、“_values”、“项目”,所有这些都可以愉快地存储我的值,但甚至不清楚它们中的哪一个会起作用。

因为它是一个 ListBox 而不是一个简单的 SELECT 菜单,所以我什至不能轻松地使用 DOM 来操作这些值。

有没有人在 4.x 中征服了 TinyMCE 列表框?

4

4 回答 4

9

我在TinyMCE 论坛上找到了这个,我已经确认它有效:

tinymce.PluginManager.add('myexample', function(editor, url) {
   var self = this, button;

   function getValues() {
      return editor.settings.myKeyValueList;
   }
   // Add a button that opens a window
   editor.addButton('myexample', {
      type: 'listbox',
      text: 'My Example',
      values: getValues(),
      onselect: function() {
         //insert key
         editor.insertContent(this.value());

         //reset selected value
         this.value(null);
      },
      onPostRender: function() {
         //this is a hack to get button refrence.
         //there may be a better way to do this
         button = this;
      },
   });

   self.refresh = function() {
      //remove existing menu if it is already rendered
      if(button.menu){
         button.menu.remove();
         button.menu = null;
      }

      button.settings.values = button.settings.menu = getValues();
   };
});


Call following code block from ajax success method
//Set new values to myKeyValueList 
tinyMCE.activeEditor.settings.myKeyValueList = [{text: 'newtext', value: 'newvalue'}];
//Call plugin method to reload the dropdown
tinyMCE.activeEditor.plugins.myexample.refresh();

这里的关键是您需要执行以下操作:

  1. 通过从 onPostRender 方法中的“this”获取“按钮”引用
  2. 使用您想要的值更新 button.settings.values 和 button.settings.menu
  3. 要更新现有列表,请调用 button.menu.remove() 和 button.menu = null
于 2013-11-08T09:31:10.303 回答
7

我尝试了 TinyMCE 论坛的解决方案,但发现它有问题。例如,当我多次尝试更改第一个 ListBox 时,只有第一次生效。同样在弹出对话框后立即更改该框没有任何效果。

但是对于解决方案:

不要打电话button.menu.remove();

此外,获取按钮参考的“hack”是完全没有必要的。您的工作可以简单地使用:

var button = win.find("#button")[0]; 

通过这些修改,我的 ListBox 可以正常工作。

整体对话功能:

function ShowDialog() {
  var val;
  win = editor.windowManager.open({
          title: 'title',
          body: {type: 'form', 
          items: [
          {type: 'listbox', 
          name: 'categorybox', 
          text: 'pick one', 
          value: 0,
          label: 'Section: ', 
          values: categories,
          onselect: setValuebox(this.value())        
          },
          {type: 'listbox', 
          name: 'valuebox', 
          text:'pick one', 
          value: '',
          label: 'Page: ', 
          values: pagelist[0],
            onselect: function(e) {
              val = this.value();
            }
          }
          ]
        },
                onsubmit: function(e) {
                    //do whatever
                }
            });

      var valbox = win.find("#valuebox")[0]; 

      function setValuebox(i){
      //feel free to call ajax
      valbox.value(null);              
      valbox.menu = null;
      valbox.settings.menu = pagelist[i]; 
      // you can also set a value from pagelist[i]["values"][0]
      }
  }

categories并且pagelist是在 TinyMCE 加载之前从数据库生成的 JSON。pagelist[category]= 所选类别的 ListBox 数据。category=0 表示全部。

希望我帮助了某人,因为我已经为此苦苦挣扎了好几个小时。

于 2014-08-08T17:27:56.400 回答
5

看起来 wordpress 4.3 中包含的 tinyMCE 版本改变了一些东西,并添加了一个缓存初始菜单的状态对象,因此改变菜单已经不够了。

可能还必须更新状态对象。这是使用来自 ajax 请求的数据更新菜单的示例:

editor.addButton('shortcodes', {
        icon: 'icon_shortcodes',
        tooltip: 'Your tooltip',
        type: 'menubutton',
        onPostRender: function() {
            var ctrl = this;
            $.getJSON( ajaxurl , function( menu) {
                // menu is the array containing your menu items
                ctrl.state.data.menu = ctrl.settings.menu = menu;
            });
        }
    });
于 2015-08-26T11:01:02.387 回答
3

据我所知,这些其他方法在 TinyMCE 4.9 中被破坏了。在花了一天的大部分时间修补我自己对这些方法的使用之后,这是我发现的工作功能:

function updateListbox(win, data) { // win is a tinymce.ui.Window
  listbox = win.find('#listbox'); // Substitute your listbox 'name'
  formItem = listbox.parent();

  listbox.remove();
  formItem.append({
    label: 'Dynamic Listbox',
    type: 'listbox',
    name: 'listbox',
    values: data
  });
}
于 2019-03-29T19:06:29.190 回答