8
votes

What is the best way to programmatically insert HTML (that represents a CKEditor widget) before an existing element in CKEditor?

The content editable is not in focus and is not currently being edited.

For example, suppose the contents of the editor are:

<h1>Here's a title</h1>
<h2>Here's a subtitle</h2>
<p>Here's a paragraph</p>
<p>Here's a paragraph</p>
<p>Here's a paragraph</p>

Now, say I have a reference to the second <p> element. What is the best way to insert html before this tag? (Keeping in mind that the HTML that I want to insert will become a Ckeditor widget after inserting.)

Thank you very much for any help,

Michael

3

3 Answers

9
votes

With the current API it is not possible to insert HTML string at the specific position without involving selection (EDIT: since CKEditor 4.5.0 it is possible – read below), because the editor.insertHtml method inserts in the selection position. However, if you have a simple situation that your HTML string contains just one element (with some ancestors), then you can easily use editor.insertElement on a lower level, when you can specify range at which you want to insert element:

var range = editor.createRange(),
    element = CKEDITOR.dom.element.createFromHtml( elementHtml );

// Place range before the <p> element.
range.setStartAt( elementP, CKEDITOR.POSITION_BEFORE_START );
// Make sure it's collapsed.
range.collapse( true );

// Insert element at the range position.
editor.editable().insertElement( element, range );

As you can see this code uses editable.insertElement, which is used by editor.insertElement.

PS. Remember that insertElement will not upcast and initialize your widget. You can find more about this here - CKEditor, initialize widget added with insertElement.

Since 4.5.0

CKEditor 4.5.0 introduced editor.editable().insertHtmlIntoRange() as well as a range parameter for editor.insertHtml(). The latter method is a more high-level one, so it will take care of undo manager and setting selection in place of insertion. The former one is more a low-level method and it only inserts the data.

2
votes

If you want to insert an element between or outside of the paragraphs , the CKEDITOR.POSITION_BEFORE_START flag won't work because the element will still be placed inside the <p></p> node.

However, the CKEDITOR.dom.node.insertBeforeMe() method will place the new element before any editor node without wrapping it or confining it to a text node.

var startRange = editor.getSelection(); //Cursor position
var parent = startRange.getStartElement(); //The parent <p> or <span> of the cursor

var e1 = CKEDITOR.dom.element.createFromHtml("<h3>Subtitle before paragraphs</h3>");
parent.insertBeforeMe(e1); //Places new node before the specified node

Hope this helps!

0
votes

its smoothly simple as this

$(document).ready(function(){
    $("#add1").click(function(){
       CKEDITOR.instances.editor2.insertHtml( '<ul><li>Computers & Electronics</li></ul>' );
    });
 });