动态更新TinyMCE 4 ListBox

时间:2013-09-14 20:19:49

标签: tinymce tinymce-4

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

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

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

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

基本上,我可以使用

访问原始渲染的ListBox(名称:“module”}

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也不包含任何项目标记。检查这些对象只是令人沮丧:有“设置”,“值”,“_值”,“项目”,所有这些都将很乐意存储我的值,但它们甚至不清楚它们将起作用。

由于它是一个ListBox而不是一个简单的SELECT菜单,我甚至无法轻易地使用DOM来操纵这些值。

有人在4.x中征服了TinyMCE ListBox吗?

4 个答案:

答案 0 :(得分:9)

我在the TinyMCE forum找到了这个,我确认它有效:

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. 使用您想要的值
  3. 更新button.settings.values和button.settings.menu
  4. 要更新现有列表,请调用button.menu.remove()和button.menu = null

答案 1 :(得分: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]
      }
  }

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

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

答案 2 :(得分: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;
            });
        }
    });

答案 3 :(得分:0)

据我所知,这些其他方法在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
  });
}