2016-06-07 83 views
1

我正在創建一個'smartobject'部件。在小部件對話框中,用戶可以選擇一個'smartobject',簡單地說,它會生成一些html,並將其添加到編輯器中。這裏有棘手的部分:html有時是div元素,有時是簡單的span元素。在div變體的情況下,小部件應該被包裝在div'模板'中。在跨度變體的情況下,小部件應該被包裝在一個跨度中,並且應該以'內聯'的方式添加html。CKEditor:多個部件模板

在widgets 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()); 
       } 
      }); 

但在我的情況下,模板是更加動態:有時一個div有時跨度會做正確的事情..

我該如何解決這個問題,而不需要創建兩個小部件,這兩個小部件將完成相同的事情,只有環繞元素作爲區別?

我已經嘗試過更換整個部件在「數據」的方法,如:

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

但這似乎不支持:調用editor.getData後導致不確定的錯誤()。

我正在使用ckeditor v4.5.9

感謝您的幫助!

+0

你可以使用在這兩種情況下使用包裝div和更改使用CSS的該div的行爲? – Atzmon

+0

這是一個不錯的主意,但我不害怕,因爲當在下面的html中添加smartobject(當選擇[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

奧克,但模板將如何看? template:「

」?我不明白這將如何幫助我解決這個問題,因爲當div被添加到例如下面的HTML

下面的[TAG]將會被替換

在我有機會移除不相關元素?我認爲在論壇中給出的例子與我的用例並不完全相同。如我錯了請糾正我!謝謝你的幫助! – NickGreen

+0

我不認爲如果在內容實際寫入編輯器之前刪除插件中的元素,html將會中斷,但我意識到我還沒有可用的樣本來支持此操作。 – Atzmon

+0

我以另一種方式修復它(請參閱我的答案),因爲我沒有按照你的方式工作:(這一切似乎現在都起作用了,非常感謝你的時間! – NickGreen