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 mon 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: /
- Look at the tiny source code: .jquery.js
Question
What is the correct way of prevent divs, and instead add paragraph tags after a list?
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 mon 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./simple-edit/
- Look at the tiny source code: https://github./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?
Share Improve this question edited Oct 19, 2012 at 17:58 Jens Törnell asked Oct 19, 2012 at 5:57 Jens TörnellJens Törnell 24.8k46 gold badges130 silver badges223 bronze badges 1- 2 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. – Edward J Beckett Commented Oct 29, 2012 at 16:50
5 Answers
Reset to default 5 +50The 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/82dS6/:
function setEndOfContenteditable(contentEditableElement){
// Taken from http://stackoverflow./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);
});
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/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 e up with was to use formatblock which has patibility 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./ovexiz/1
Source: http://jsbin./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:
http://jsfiddle/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'));
});