我正在尝试修改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吗?
答案 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 :(得分: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加载之前从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
});
}