HTML5 Content Editable paragraph after list
-
09-07-2021 - |
Question
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
- Try the editor here: http://files.inlovewithcss.com/simple-edit/
- Look at the tiny source code: https://github.com/mlabod/simple-edit/blob/master/editor.jquery.js
Question
What is the correct way of prevent divs, and instead add paragraph tags after a list?
Solution
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 http://stackoverflow.com/a/3866442/1601088
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);
});
OTHER TIPS
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/
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.
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.
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:
function replaceDivWithP(el){
$(el).find('div').each(function(){
$(this).replaceWith($('<p>' + $(this).html() + '</p>'));
});
}
$(function(){
$(".text").simpleEdit();
});
$('button.list').bind('click', function(){
replaceDivWithP($('.textarea'));
});