Можно ли повторно инициализировать комбинированный список / выпадающее меню CKEditor? - PullRequest
8 голосов
/ 14 октября 2011

Как мне динамически обновлять элементы в выпадающем меню?

У меня есть собственный плагин для CKEditor, который заполняет выпадающее меню списком элементов, которые я могу добавить в мой textarea.

Этот список элементов взят из массива Javascript с именем maptags, который динамически обновляется для каждой страницы.

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

Ответы [ 2 ]

12 голосов
/ 06 декабря 2011

Я думаю, что я только что решил это на самом деле.

Измените ваш 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», когда связываем ее, поэтому всякий раз, когда вызывается rebuildList, это относится к самому объекту richcombo, который я не смог получить другим способом.

Надеюсь, это поможет, у меня все отлично работает!

ElChe

1 голос
/ 28 апреля 2016

Я не смог найти никакой полезной документации по 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 = {};
                });

ПРИМЕЧАНИЕ Весь приведенный выше код находится внутри обратного вызова init addRichCombo

  • Я удаляю содержимое поля со списком в событии "panelHide"
  • Я снова заполняю поле со списком при событии "panelShow"

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...