Reputation: 335
In CKeditor is it possible to add multiple child elements to a list element?
E.g.
- Heading
Paragraph
- Heading2
Paragraph2
Backstory- I've created a style that lets the user style up an order list. Part of this style is to have a heading and a paragrpah within each list item element.
Problem- When the adding the heading element and pressing enter, to be able to add the paragraph, a new list item is added instead. If the shift+enter/shift+enter button combination is pressed, a new list is created without creating a new list item, however the cursor remains within the heading element, and so no paragraph can be added this way.
Is there a way around this?
Upvotes: 0
Views: 737
Reputation: 335
I've found a way to fix the problem by overriding the key press event in CKEditor. When a key is pressed, it checks that:
If so it
The code:
CKEDITOR.on(
'instanceReady',
function(ev) {
var editorInstance = CKEDITOR.instances[ev.editor.name];
var editorWindow = editorInstance.window.$;
var editorDocument = $editor_instance.document.$;
var editorBody = editorDocument.body;
/***
* Fix the editor not letting you add sub elements to lists
*/
editorInstance.on( 'key', function( event ) {
// Get the HTML event
var e = event.data;
// If the enter key was pressed
if(e.keyCode == 13) {
// Find which element the cursor is in
var selection = editorWindow.getSelection();
var cursorElem = $(selection.anchorNode);
// Only override the default behaviour if we're in a list element, and the user has typed something
if(cursorElem.closest('li').length && cursorElem.text().trim().length) {
// get the current cursor position
var range = editorWindow.getSelection().getRangeAt(0)
// create range to find how many characters are after the cursor
var postRange = editorDocument.createRange();
postRange.selectNodeContents(cursorElem[0]);
postRange.setStart(range.endContainer, range.endOffset);
var nextText = postRange.cloneContents();
var isAtEnd = nextText.textContent.length === 0;
// Only override if we're at the end of the list element
if(isAtEnd) {
// cancel the default event
event.cancel();
// get the element to add the new paragraph after
var after = cursorElem;
// if the cursor is in a TEXT not instead of an actual HTML node then get the parent HTML code
if(cursorElem[0].nodeType == Node.TEXT_NODE) {
after = cursorElem.parent();
}
// Add the new paragraph
after.after('<p></p>');
var newParagraph = after.next();
// set selection to the new paragraph
var range = editorDocument.createRange();
range.setStart(newParagraph[0], 0);
selection.removeAllRanges();
selection.addRange(range);
}
}
}
});
}
);
CSS needed to make the new paragraph display:
p {
min-height: 1em;
}
P.s. Thanks for this answer showing how to check if the cursor was at the end of an element Contenteditable DIV - how can I determine if the cursor is at the start or end of the content
Upvotes: 0