0

In my ckeditor instance, I want to let my users insert a horizontal rule but only once. If there is an existing line, it should be replaced by the new one (same as the Read-More functionality on Wordpress). I can get it to work if I want only the last HR tag to remain, but what if a user wants to insert his HR tag higher up in the document than an existing one?

I used a variable (say, savedContent) to store the default content (without any HR) on instantiation. Following the steps in Set cursor to specific position in CKEditor , my idea was to use the savedContent variable to revert the CKEditor contents to the default HR-less content before (using the ranges or bookmarks) to insert a new HR at the cursor position.

This is the code:

CKEDITOR.on('instanceReady', function() {
    $(".cke_button__horizontalrule").attr("title","End Preview here");
    var savedContent = CKEDITOR.instances['pro_story'].getData();

    $(".cke_button__horizontalrule").on("click",function(){
        var ranges = editor.getSelection().getRanges();
        CKEDITOR.instances['pro_story'].setData(savedContent);
        editor.getSelection().selectRanges( ranges );
        editor.insertHtml("<hr />");
    });
});

Now the problem with this code is that, for some reason, it gives me the following error: The given range isn't in document.

What do I do?

S R
  • 157
  • 1
  • 2
  • 12

1 Answers1

1

Get an array of existing <hr /> tags before inserting a new one. Then, remove all these tags after inserting the new one.

let hrArray;

CKEDITOR.instances['pro_story'].on('beforeCommandExec', function(evt) {
    if (evt.data.name == 'horizontalrule') {
        hrArray = evt.editor.document.getElementsByTag('hr').toArray();
    }
});

CKEDITOR.instances['pro_story'].on('afterCommandExec', function(evt) {
    if (evt.data.name == 'horizontalrule') {
        hrArray.forEach(el => el.remove());
    }
});
Wizard
  • 2,961
  • 2
  • 13
  • 22
  • Excellent solution! Thank you. Using this instead of my own workaround, which involved inserting a custom string at the cursor position, using string-replace to remove all other HR tags and then convert the custom string into a HR tag. Not only did it mess around with the P tags on either side of the insertion point, it would also reset the cursor position to the top of the doc. This solution is so much cleaner and does not mess around with the other P tags. – S R Feb 01 '18 at 06:28