2011-10-14 10 views
7

Come aggiornare dinamicamente gli elementi in un menu a discesa?È possibile reinizializzare un CKEditor Combobox/menu a discesa?

Ho un plug-in personalizzato per CKEditor che popola un menu a discesa con un elenco di elementi che posso immettere nel mio textarea.

Questo elenco di elementi proviene da un array Javascript denominato maptags, che viene aggiornato in modo dinamico per ogni pagina.

var maptags = [] 

Questo elenco di tag viene aggiunto al menu a discesa prima volta che si fa clic su di esso con la funzione init:. Il mio problema è cosa succederebbe se gli elementi di quell'array cambiassero mentre il client cambia le cose nella pagina, come posso ricaricare quell'elenco nell'array aggiornato?

Ecco il mio CKEditor codice del plugin:

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

risposta

12

Penso che ho appena risolto questo in realtà.

Cambia la tua init in questo modo:

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

e definire la funzione buildList di fuori di tale ambito.

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

La cosa intelligente sulla funzione CKEDITOR.tools.bind è che forniamo "presente" quando ci leghiamo, quindi ogni volta che viene attivato il rebuildList, questo riferimento all'oggetto richcombo stessa che non ero in grado di ottenere qualsiasi altro modo.

Spero che questo aiuti, funziona bene per me!

Elche

+0

Questa soluzione funziona bene con dati statici, ma quando provo utilizzando la soluzione di cui sopra con i dati recuperati dal server, mostra vuota. Puoi aiutare? –

+0

preleva i tuoi articoli dal server, ad es. dalla chiamata Ajax e metterli nella matrice "yourListOfItems" –

+0

Questo è un po 'disordinato, ma mi ha fatto sulla buona strada. Grazie! post scriptum la struttura dell'oggetto richCombo è strana e schifosa, e questa capacità dovrebbe davvero essere una parte di richCombo invece di doverla hackerare dall'esterno. –

0

non ho potuto trovare qualsiasi documenatation utile intorno richcombo, ho dato un'occhiata al codice sorgente e ottenuto un'idea degli eventi che mi serviva.

soluzione

@El Che mi ha aiutato a superare questo problema, ma ho avuto un altro approccio al problema perché ho avuto una struttura più complessa combobox (di ricerca, gruppi)

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

NOTA Tutto il codice qui sopra è all'interno addRichCombo init callback

  • ho rimuovere i contenuti combobox su "panelHide" evento
  • ho ripopolare combobox sulla manifestazione "panelShow"

Spero che questo aiuti

Problemi correlati