2016-06-07 3 views
1

В настоящее время я создаю виджет «smartobject». В диалоговом окне виджетов пользователь может выбрать «smartobject», который просто помещает, генерирует некоторый html, который должен быть добавлен в редактор. Здесь идет сложная часть: html иногда элементы div, а иногда просто элементы span. В случае варианта div виджет должен быть обернут в div 'template'. В случае варианта span виджет должен быть обернут в промежутке, а html следует добавить «inline».CKEditor: несколько шаблонов виджета

В API виджетов я вижу следующий способ определения шаблона:

editor.widgets.add('smartobject', { 
       dialog: 'smartobject', 
       pathName: lang.pathName, 
       template: '<div class="cke_smartobject"></div>', // <------ 

       upcast: function(element) { 
        return element.hasClass('smartObject'); 
       }, 

       init: function() { 
        this.setData('editorHtml', this.element.getOuterHtml()); 
       }, 

       data: function() { 
        var editorHtml = this.data.editorHtml; 

        var newElement = new CKEDITOR.dom.element.createFromHtml(editorHtml); 

        newElement.copyAttributes(this.element); 

        this.element.setText(newElement.getText()); 
       } 
      }); 

Но в моем случае, шаблон более динамична: иногда ДИВ, а иногда пролет будет делать правильные вещи ..

Как я могу исправить это, не создавая два виджета, которые будут делать то же самое, только в качестве разницы?

Я уже пытался заменить весь элемент в методе «данных», как:

newElement.replace(this.element); 
this.element = newElement; 

Но это, казалось, не поддерживаются: в результате неопределенных ошибок после вызова editor.getData().

Я использую CKEditor v4.5.9

Спасибо за вашу помощь!

+0

Можете ли вы использовать обертку div в обоих случаях и изменить поведение этого div с помощью css? – Atzmon

+0

Это хорошая идея, но я боюсь, что нет, потому что при добавлении smartobject в следующем HTML (при выборе [smartobject] текст):

этот текст содержит [smartobject]

HTML, становится недействительным

не позволил. – NickGreen

ответ

2

Кажется, я получил его работу (с обходным решением). Код:

CKEDITOR.dialog.add('smartobject', this.path + 'dialogs/smartobject.js'); 

     editor.widgets.add('smartobject', { 
      pathName: lang.pathName, 

      // This template is needed, to activate the widget logic, but does nothing. 
      // The entire widgets html is defined and created in the dialog. 
      template: '<div class="cke_smartobject"></div>', 

      init: function() { 
       var widget = this; 
       widget.on('doubleclick', function(evt) { 
        editor.execCommand('smartobject'); 
       }, null, null, 5); 
      }, 

      upcast: function(element) { 
       return element.hasClass('smartObject'); 
      } 
     }); 

     // Add a custom command, instead of using the default widget command, 
     // otherwise multiple smartobject variants (div/span/img) are not supported. 
     editor.addCommand('smartobject', new CKEDITOR.dialogCommand('smartobject')); 

     editor.ui.addButton && editor.ui.addButton('CreateSmartobject', { 
      label: lang.toolbar, 
      command: 'smartobject', 
      toolbar: 'insert,5', 
      icon: 'smartobject' 
     }); 

И в диалоговом окне, чтобы вставить код выглядит следующим образом:

return { 
    title: lang.title, 
    minWidth: 300, 
    minHeight: 80, 

    onOk: function() { 
     var element = CKEDITOR.dom.element.createFromHtml(smartobjectEditorHtml); 

     editor.insertElement(element); 

     // Trigge the setData method, so the widget html is transformed, 
     // to an actual widget! 
     editor.setData(editor.getData()); 
    }, 
...etc. 

UPDATE Я сделал метод в «OnOK» немного лучше: smartobject элемент теперь выбранных после вставки.

onOk: function() { 
     var element = CKEDITOR.dom.element.createFromHtml(smartobjectEditorHtml); 
     var elementId = "ckeditor-element-" + element.getUniqueId(); 

     element.setAttribute("id", elementId); 

     editor.insertElement(element); 

     // Trigger the setData method, so the widget html is transformed, 
     // to an actual widget! 
     editor.setData(editor.getData()); 

     // Get the element 'fresh' by it's ID, because the setData method, 
     // makes the element change into a widget, and thats the element which should be selected, 
     // after adding. 
     var refreshedElement = CKEDITOR.document.getById(elementId); 
     var widgetWrapperElement = CKEDITOR.document.getById(elementId).getParent(); 

     // Better safe then sorry: if the fresh element doesn't have a parent, simply select the element itself. 
     var elementToSelect = widgetWrapperElement != null ? widgetWrapperElement : refreshedElement; 

     // Normally the 'insertElement' makes sure the inserted element is selected, 
     // but because we call the setData method (to ensure the element is transformed to a widget) 
     // the selection is cleared and the cursor points to the start of the editor. 
     editor.getSelection().selectElement(elementToSelect); 
    }, 

Таким образом, в общем, я частично использовал виджет API для частей, которые я хотел: - Сделать HTML виджета не редактируется - Сделать это движимым

Но я создал команду диалоговой, который просто обходит вставку виджета по умолчанию, поэтому я могу полностью решить мою собственную структуру html для виджета.

Все, кажется, работает следующим образом.

Любые предложения, чтобы сделать их лучше, оценили :)!

0

Как было предложено в this форуме форума ckeditor, лучшим подходом было бы установить шаблон для включения всех возможных элементов контента. Затем в функции data удалите ненужные части в соответствии с вашей конкретной логикой.

+0

Oke, но как будет выглядеть шаблон? template: "

"? Я не понимаю, как это поможет мне с этой проблемой, потому что когда добавляется div, например, следующий html

, следующий [TAG] будет заменен

html сломается, прежде чем я получу возможность удалить элементы noecesarry ? Я думаю, что данный пример на форуме, на самом деле не такой, как мой вариант использования. Поправьте меня если я ошибаюсь! Спасибо за вашу помощь! – NickGreen

+0

Я не думаю, что html сломается, если вы делаете удаление элемента в плагине, прежде чем контент будет фактически написан в редакторе, хотя я понимаю, что у меня пока нет рабочей выборки, чтобы поддержать это. – Atzmon

+0

Я исправил его по-другому (см. Мой ответ), потому что я не получил его, чтобы работать на вашем пути :(Кажется, все работает сейчас. Большое вам спасибо за ваше время! – NickGreen

Смежные вопросы