2011-10-14 21 views
7

Jak dynamicznie aktualizować elementy w menu rozwijanym?Czy można ponownie zainicjować menu Combobox/Drop Down CKEditor?

Mam niestandardową wtyczkę dla CKEditor, która zapełnia rozwijane menu z listą elementów, które mogę wprowadzić do mojego textarea.

Ta lista pozycji pochodzi z tablicy JavaScript o nazwie maptags, która jest dynamicznie aktualizowana dla każdej strony.

var maptags = [] 

Ta lista tagów zostanie dodany do listy rozwijanej po pierwszym kliknięciu na nim przez funkcję init:. Mój problem polega na tym, że jeśli elementy w tej tablicy zmieniają się, gdy klient zmienia rzeczy na stronie, jak mogę ponownie załadować tę listę do zaktualizowanej tablicy?

Oto moja CKEditor kod wtyczki:

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

Odpowiedz

12

Chyba tylko rozwiązać ten rzeczywiście.

Zmiana metody init tak:

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

i zdefiniować funkcję buildList spoza tego zakresu.

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

Pomysłowa rzeczą jest to, że funkcja CKEDITOR.tools.bind dostarczamy „to”, kiedy go związać, więc gdy rebuildList jest wyzwalany, to odnoszą się do samego obiektu richcombo który nie był w stanie dostać się w jakikolwiek inny sposób.

Mam nadzieję, że to pomaga, działa dobrze dla mnie!

Elche

+0

Rozwiązanie to działa dobrze z danych statycznych, ale gdy próbuję przy użyciu powyższego rozwiązania zawierających dane pobrane z serwera, pokazuje puste. Możesz pomóc? –

+0

odbieraj swoje produkty z serwera, np. z połączenia Ajax i umieść je w tablicy "yourListOfItems". –

+0

To trochę nieprzyjemne, ale doprowadziło mnie to na właściwą drogę. Dzięki! p.s. struktura obiektu richCombo jest dziwna i obłędna, a ta zdolność powinna być częścią RichCombo, zamiast zhakować ją z zewnątrz. –

0

nie mogłem znaleźć żadnej pomocne documenatation wokół richcombo, i przyjrzał do kodu źródłowego i got pomysł wydarzeń potrzebne.

rozwiązanie

@El Che pomógł mi przejść przez ten problem, ale nie miałem innego podejścia do problemu, bo miał bardziej złożoną strukturę combobox (wyszukiwanie, grupy)

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

UWAGA Wszystkie wyżej kod jest wewnątrz addRichCombo startowe zwrotnego

  • usunąć zawartość combobox na "panelHide" zdarzenie
  • I repopulate combobox na "wydarzenie" panelShow

Nadzieja to pomaga

Powiązane problemy