2011-10-14 50 views
7

¿Cómo actualizo dinámicamente los artículos en un menú desplegable?¿Es posible reiniciar un menú desplegable de CKEditor/menú desplegable?

Tengo un complemento personalizado para CKEditor que rellena un menú desplegable con una lista de elementos que puedo insertar en mi textarea.

Esta lista de elementos proviene de una matriz de Javascript llamada maptags, que se actualiza dinámicamente para cada página.

var maptags = [] 

Esta lista de etiquetas se agrega a la lista desplegable la primera vez que haga clic en él por la función init:. Mi problema es: ¿qué sucede si los elementos de esa matriz cambian a medida que el cliente cambia cosas en la página, cómo puedo volver a cargar esa lista en la matriz actualizada?

Aquí está mi código de CKEditor 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'); 
      } 
     }); 
    } 
}); 

Respuesta

12

Creo que acabo de resolver esto en realidad.

Cambiar la init así:

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

y definir la función buildList fuera de ese ámbito.

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

Lo inteligente acerca de la función CKEDITOR.tools.bind es que suministramos "esto" cuando nos atamos a él, así que cada vez que se activa el rebuildList, esto se refiere al propio objeto richcombo que yo no era capaz de obtener de otra manera.

Espero que esto ayude, ¡funciona bien para mí!

Elche

+0

Esta solución funciona bien con los datos estáticos pero cuando intento utilizar la solución anterior con datos obtenidos desde el servidor, se muestra en blanco. ¿Puede usted ayudar? –

+0

obtenga sus artículos del servidor, p. desde Ajax llame y póngalos en el array "yourListOfItems" –

+0

Esto es un poco desordenado, pero me puso en el camino correcto. ¡Gracias! PD. la estructura del objeto richCombo es extraña y asquerosa, y esta capacidad realmente debería ser una parte de richCombo en lugar de tener que hackearla desde el exterior. –

0

no pude encontrar ninguna documenatation útiles en torno richcombo, me echó un vistazo al código fuente y consiguió una idea de los eventos que necesitaba.

solución

@El Che me ha ayudado a conseguir a través de este tema, pero yo tenía otro enfoque del problema porque tenía una estructura más compleja cuadro combinado (búsqueda, grupos)

  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 Todo el código de seguridad está dentro de devolución de llamada addRichCombo init

  • que eliminar el contenido de cuadro combinado "panelHide" evento
  • que repoblar cuadro combinado en el evento "panelShow"

Esperanza esto ayuda