【问题标题】:Dynamically updating a TinyMCE 4 ListBox动态更新 TinyMCE 4 ListBox
【发布时间】:2013-09-14 20:19:48
【问题描述】:

我正在尝试修改 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 列表框吗?

【问题讨论】:

    标签: tinymce tinymce-4


    【解决方案1】:

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

    【讨论】:

    • 感谢 Moeri 我正在寻找重置选项! //重置选中的值 this.value(null);
    • 嘿,我正在尝试添加一个列表并按照您所说的做了,但是在myexample.refresh() 之后,我可以看到“我的示例”按钮,但它没有任何选项,即列表为空。我在menubar 中也看不到这个,不得不输入toolbar : 'myexample' 才能看到按钮。
    • 对于 Tinymce 4.3+,您必须使用:button.settings.values = button.state.data.menu = items;
    • 请先了解如何添加自定义插件,然后才能了解如何集成到您的代码中
    【解决方案2】:

    我尝试了 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 加载之前从数据库生成的 JSON。 pagelist[category] = 所选类别的列表框数据。 category=0 表示全部。

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

    【讨论】:

      【解决方案3】:

      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;
                  });
              }
          });
      

      【讨论】:

      • 受此影响的 tinyMCE 版本为 4.2,感谢您指出此更改。
      • 对于一个列表框按钮,这对我来说最终是 ctrl.state.data.menu = ctrl.settings.values = menu; 而不是 settings.menu。这适用于 WP 4.5.1 和 TinyMCE 4.3.10
      • 这对于 WP 4.7.2 来说仍然是准确的
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-11
        • 2011-03-24
        • 1970-01-01
        • 1970-01-01
        • 2011-10-13
        • 1970-01-01
        相关资源
        最近更新 更多