HTML5 Content Editable paragraph after list
Asked Answered
L

5

7

I use Google Chrome.

I need to have a very tiny HTML editor and I found Simple Edit. Very small editor, just for my needs. However... This and many other editors that are using Content Editable have one common problem.

Problem

After creating a list (hit enter twice on last list item), it creates a new div. Expected to me would be to create a new paragraph tag.

Links

Question

What is the correct way of prevent divs, and instead add paragraph tags after a list?

Lobito answered 19/10, 2012 at 5:57 Comment(1)
This will post a problem you know. If you replace your container element with paragraph tags instead of divs, successive lists will be children of paragraphs which, is invalid html.Edithe
L
5

The answer posted by Bryan Allo did not take into account that you need to place the cursor at the end of the div. Otherwise upon every replace action the user would have to hit CTRL-End.

This is the solution I propose, also to be seen in action at http://jsfiddle.net/82dS6/:

function setEndOfContenteditable(contentEditableElement){
    // Taken from https://mcmap.net/q/83309/-how-to-move-the-cursor-to-the-end-of-a-contenteditable-entity
    var range,selection;
    if(document.createRange){//Firefox, Chrome, Opera, Safari, IE 9+
        range = document.createRange();
        range.selectNodeContents(contentEditableElement);
        range.collapse(false);
        selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
    }
    else if(document.selection){//IE 8 and lower
        range = document.body.createTextRange();
        range.moveToElementText(contentEditableElement);
        range.collapse(false);
        range.select();
    }
}

function replaceDivWithP(el){

    $(el).find('div').each(function(){
        $(this).replaceWith($('<p>' + $(this).html() + '</p>'));
    });
}

$(function(){
    $(".text").simpleEdit();
});

$('.textarea').bind('keyup', function(){
    replaceDivWithP(this);
    setEndOfContenteditable(this);
});


​
Leverick answered 27/10, 2012 at 20:52 Comment(2)
This solution is the best one so far. Vote up so far. However when I click the list icon it add the list inside a paragraph.Aurignacian
It seems like there is no easy way around this because the library you're using uses ExecCommand to replace the contents which is not easy to hook into.Leverick
C
1

Instead of processing on-the-fly with every keyup event, you could consider post-processing:

$('.textarea').bind('blur', function(){
    $('.textarea div').contents().unwrap().wrap('<p/>');
});

Fiddle: http://jsfiddle.net/thNUS/4/

Counterword answered 29/10, 2012 at 19:45 Comment(0)
C
0

A quick solution is to simply replace any DIVs with Ps. Place this inside your content editable DIV.

onkeyup="this.innerHTML=this.innerHTML.replace('div','p')"

Hope it helps. Good luck.

Concentrated answered 19/10, 2012 at 19:35 Comment(1)
you can replace the actual tags if you want to be specific and avoid potential conflicts with valid content. Just don't forget to replace the closing tags as well. :-)Concentrated
D
0

The best I could come up with was to use formatblock which has compatibility issues. Basically you could add another link like so:

textcontainer.prepend("<button class='paragraph'>p</button>");

...

$(".paragraph").live("click", function(){
    document.execCommand('formatblock', false, "p");
});

This gives your users the option to insert a paragraph tag. Getting out of that tag is a bit tricky though, so it has some usability issues too. You can play with it on the provided demo:

Demo: http://jsbin.com/ovexiz/1
Source: http://jsbin.com/ovexiz/1/edit

*note that paragraphs are styled with green colored text.

Designer answered 29/10, 2012 at 20:41 Comment(0)
L
0

Previous answers proposed a keyup or blur based solution. This one uses the click event of the list button to minimize the amount of function calls:

http://jsfiddle.net/9ZAL7/:

function replaceDivWithP(el){

    $(el).find('div').each(function(){
        $(this).replaceWith($('<p>' + $(this).html() + '</p>'));
    });
}

$(function(){
    $(".text").simpleEdit();
});

$('button.list').bind('click', function(){
    replaceDivWithP($('.textarea'));
});
​
Leverick answered 29/10, 2012 at 22:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.