是否可以重新初始化 CKEditor 组合框/下拉菜单?

发布于 2024-12-09 22:01:21 字数 1546 浏览 0 评论 0原文

如何动态更新下拉列表中的项目?

我有一个 CKEditor 的自定义插件,它使用可以注入到我的 textarea 中的项目列表填充下拉菜单。

该项目列表来自名为 maptags 的 Javascript 数组,该数组会针对每个页面动态更新。

var maptags = []

当您首次通过 init: 函数单击此标签列表时,该标签列表将添加到下拉列表中。我的问题是,如果该数组中的项目随着客户端更改页面上的内容而发生变化,我该如何将该列表重新加载到更新后的数组中?

这是我的 CKEditor 插件代码:

CKEDITOR.plugins.add('mapitems', {
    requires: ['richcombo'], //, 'styles' ],
    init: function (editor) {
        var config = editor.config,
        lang = editor.lang.format;       

        editor.ui.addRichCombo('mapitems',
        {
            label: "Map Items",
            title: "Map Items",
            voiceLabel: "Map Items",
            className: 'cke_format',
            multiSelect: false,

            panel:
            {
                css: [config.contentsCss, CKEDITOR.getUrl(editor.skinPath + 'editor.css')],
                voiceLabel: lang.panelVoiceLabel
            },

            init: function () {
                this.startGroup("Map Items");
                //this.add('value', 'drop_text', 'drop_label');
                for (var this_tag in maptags) {
                    this.add(maptags[this_tag][0], maptags[this_tag][1], maptags[this_tag][2]);
                }
            },

            onClick: function (value) {
                editor.focus();
                editor.fire('saveSnapshot');
                editor.insertHtml(value);
                editor.fire('saveSnapshot');
            }
        });
    } 
});

How do I dynamically update the items in a drop down?

I have a custom plugin for CKEditor that populates a drop down menu with a list of items which I can inject into my textarea.

This list of items comes from a Javascript array called maptags, which is updated dynamically for each page.

var maptags = []

This list of tags gets added to the drop down when you first click on it by the init: function. My problem is what if the items in that array change as the client changes things on the page, how can I reload that list to the updated array?

Here is my CKEditor Plugin code:

CKEDITOR.plugins.add('mapitems', {
    requires: ['richcombo'], //, 'styles' ],
    init: function (editor) {
        var config = editor.config,
        lang = editor.lang.format;       

        editor.ui.addRichCombo('mapitems',
        {
            label: "Map Items",
            title: "Map Items",
            voiceLabel: "Map Items",
            className: 'cke_format',
            multiSelect: false,

            panel:
            {
                css: [config.contentsCss, CKEDITOR.getUrl(editor.skinPath + 'editor.css')],
                voiceLabel: lang.panelVoiceLabel
            },

            init: function () {
                this.startGroup("Map Items");
                //this.add('value', 'drop_text', 'drop_label');
                for (var this_tag in maptags) {
                    this.add(maptags[this_tag][0], maptags[this_tag][1], maptags[this_tag][2]);
                }
            },

            onClick: function (value) {
                editor.focus();
                editor.fire('saveSnapshot');
                editor.insertHtml(value);
                editor.fire('saveSnapshot');
            }
        });
    } 
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

扎心 2024-12-16 22:01:21

我想我实际上刚刚解决了这个问题。

像这样更改你的 init:

init: function () {
                var rebuildList = CKEDITOR.tools.bind(buildList, this);
                rebuildList();
                $(editor).bind('rebuildList', rebuildList);
            },

并在该范围之外定义 buildList 函数。

var buildListHasRunOnce = 0;
        var buildList = function () {
            if (buildListHasRunOnce) {
                // Remove the old unordered list from the dom.
                // This is just to cleanup the old list within the iframe
                $(this._.panel._.iframe.$).contents().find("ul").remove();
                // reset list
                this._.items = {};
                this._.list._.items = {};
            }
            for (var i in yourListOfItems) {
                var item = yourListOfItems[i];
                // do your add calls
                this.add(item.id, 'something here as html', item.text);
            }
            if (buildListHasRunOnce) {
                // Force CKEditor to commit the html it generates through this.add
                this._.committed = 0; // We have to set to false in order to trigger a complete commit()
                this.commit();
            }
            buildListHasRunOnce = 1;
        };

CKEDITOR.tools.bind 函数的巧妙之处在于,我们在绑定它时提供“this”,因此每当触发重建列表时,this 都会引用 richcombo 对象本身,而我无法通过任何其他方式获得它。

希望这有帮助,对我来说效果很好!

埃尔切

I think I just solved this actually.

Change your init like this:

init: function () {
                var rebuildList = CKEDITOR.tools.bind(buildList, this);
                rebuildList();
                $(editor).bind('rebuildList', rebuildList);
            },

And define the buildList function outside that scope.

var buildListHasRunOnce = 0;
        var buildList = function () {
            if (buildListHasRunOnce) {
                // Remove the old unordered list from the dom.
                // This is just to cleanup the old list within the iframe
                $(this._.panel._.iframe.$).contents().find("ul").remove();
                // reset list
                this._.items = {};
                this._.list._.items = {};
            }
            for (var i in yourListOfItems) {
                var item = yourListOfItems[i];
                // do your add calls
                this.add(item.id, 'something here as html', item.text);
            }
            if (buildListHasRunOnce) {
                // Force CKEditor to commit the html it generates through this.add
                this._.committed = 0; // We have to set to false in order to trigger a complete commit()
                this.commit();
            }
            buildListHasRunOnce = 1;
        };

The clever thing about the CKEDITOR.tools.bind function is that we supply "this" when we bind it, so whenever the rebuildList is triggered, this refer to the richcombo object itself which I was not able to get any other way.

Hope this helps, it works fine for me!

ElChe

ゝ偶尔ゞ 2024-12-16 22:01:21

我找不到有关 richcombo 的任何有用的文档,我查看了源代码并了解了我需要的事件。

@El Che 解决方案帮助我解决了这个问题,但我有另一种方法来解决这个问题,因为我有一个更复杂的组合框结构(搜索、组)

            var _this = this;
                populateCombo.call(_this, data);

                function populateCombo(data) {
                    /* I have a search workaround added here */

                    this.startGroup('Default'); /* create default group */

                    /* add items with your logic */
                    for (var i = 0; i < data.length; i++) {
                        var dataitem = data[i];
                        this.add(dataitem.name, dataitem.description, dataitem.name);
                    }

                    /* other groups .... */
                }

                var buildListHasRunOnce = 0;
                /* triggered when combo is shown */
                editor.on("panelShow", function(){
                    if (buildListHasRunOnce) {
                        // reset list
                        populateCombo.call(_this, data);
                    }
                    buildListHasRunOnce = 1;
                });

                /* triggered when combo is hidden */
                editor.on("panelHide", function(){
                    $(_this._.list.element.$).empty();
                    _this._.items = {};
                    _this._.list._.items = {};
                });

注意
上面的所有代码都在 addRichCombo init 回调中

  • 我删除了“panelHide”事件上的组合框内容
  • 我在“panelShow”事件上重新填充了组合框

希望这有帮助

I could not find any helpful documenatation around richcombo, i took a look to the source code and got an idea of the events i needed.

@El Che solution helped me to get through this issue but i had another approach to the problem because i had a more complex combobox structure (search,groups)

            var _this = this;
                populateCombo.call(_this, data);

                function populateCombo(data) {
                    /* I have a search workaround added here */

                    this.startGroup('Default'); /* create default group */

                    /* add items with your logic */
                    for (var i = 0; i < data.length; i++) {
                        var dataitem = data[i];
                        this.add(dataitem.name, dataitem.description, dataitem.name);
                    }

                    /* other groups .... */
                }

                var buildListHasRunOnce = 0;
                /* triggered when combo is shown */
                editor.on("panelShow", function(){
                    if (buildListHasRunOnce) {
                        // reset list
                        populateCombo.call(_this, data);
                    }
                    buildListHasRunOnce = 1;
                });

                /* triggered when combo is hidden */
                editor.on("panelHide", function(){
                    $(_this._.list.element.$).empty();
                    _this._.items = {};
                    _this._.list._.items = {};
                });

NOTE
All above code is inside addRichCombo init callback

  • I remove combobox content on "panelHide" event
  • I repopulate combobox on "panelShow" event

Hope this helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文