Geekpedia Programming Tutorials






Creating a Rich Text Editor using JavaScript

This tutorial will explain how to create a rich text editor in a webpage using simply an iFrame in editable mode and its methods.

On Tuesday, February 13th 2007 at 11:05 AM
By Sorin Sodolescu (View Profile)
*****   (Rated 4.3 with 53 votes)
Contextual Ads
More JavaScript Resources
Advertisement
Rich Text Box

Sample See this code in action

First of all we have to create the HTML elements that we will use to change the content and appearance of what's inside the rich text editor:

<body onLoad="def()">
<div style="width:500px; text-align:left; margin-bottom:10px ">
<input type="button" id="bold" style="height:21px; width:21px; font-weight:bold;" value="B" />
<input type="button" id="italic" style="height:21px; width:21px; font-style:italic;" value="I" />
<input type="button" id="underline" style="height:21px; width:21px; text-decoration:underline;" value="U" /> |
<input type="button" style="height:21px; width:21px;"value="L" title="align left" />
<input type="button" style="height:21px; width:21px;"value="C" title="center" />
<input type="button" style="height:21px; width:21px;"value="R" title="align right" /> |
<select id="fonts">
<option value="Arial">Arial</option>
<option value="Comic Sans MS">Comic Sans MS</option>
<option value="Courier New">Courier New</option>
<option value="Monotype Corsiva">Monotype</option>
<option value="Tahoma">Tahoma</option>
<option value="Times">Times</option>
</select>
<select id="size">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<select id="color">
<option value="black">-</option>
<option style="color:red;" value="red">-</option>
<option style="color:blue;" value="blue">-</option>
<option style="color:green;" value="green">-</option>
<option style="color:pink;" value="pink">-</option>
</select> |
<input type="button" style="height:21px; width:21px;"value="1" title="Numbered List" />
<input type="button" style="height:21px; width:21px;"value="●" title="Bullets List" />
<input type="button" style="height:21px; width:21px;"value="←" title="Outdent" />
<input type="button" style="height:21px; width:21px;"value="→" title="Indent" />
</div>


Next we need to create an iFrame, this is where the text will be written and edited.

<iframe id="textEditor" style="width:500px; height:170px;">
</iframe>


We can now write the Javascript code.
First of all, in order to use the iFrame we have to set it to design mode. Then we have to open, write and close that iFrame.

<script type="text/javascript">
<!--
textEditor.document.designMode="on";
textEditor.document.open();
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:13px;}</style></head>');
textEditor.document.close();


You can see that the write() method has some CSS for a parameter - that is because I wanted to set the iFrame's default font and font size.
It's time to write the function that will be called by the HTML elements created earlier. This is a very simple function, we only need 2 iFrame methods: execCommand() and focus(). execCommand() will execute a command on the current document, current selection, or the given range, and focus() will give the focus back to the iFrame.

function fontEdit(x,y)
{
textEditor.document.execCommand(x,"",y);
textEditor.focus();
}


We will use this function with all the HTML elements. Let's start with the Bold button.
We just have to set the event which will call the function, and give a parameter to the function. Because it's a button, we will use the onClick event.

<input type="button" id="bold" style="height:21px; width:21px; font-weight:bold;" value="B" onClick="fontEdit('bold')" />

When called, the function will make the text bold. We do the same thing for the rest of the buttons, changing the parameter.

<input type="button" id="italic" style="height:21px; width:21px; font-style:italic;" value="I" onClick="fontEdit('italic')" />
<input type="button" id="underline" style="height:21px; width:21px; text-decoration:underline;" value="U" onClick="fontEdit('underline')" /> |
<input type="button" style="height:21px; width:21px;"value="L" onClick="fontEdit('justifyleft')" title="align left" />
<input type="button" style="height:21px; width:21px;"value="C" onClick="fontEdit('justifycenter')" title="center" />
<input type="button" style="height:21px; width:21px;"value="R" onClick="fontEdit('justifyright')" title="align right" /> |

Now it's time to take care of the dropdown Font, Size and Color lists. Because these lists have multiple values, we have pass the selected index value as the second parameter. Also, the event that will call the function will be onChange.

<select id="fonts" onChange="fontEdit('fontname',this[this.selectedIndex].value)">
   <option value="Arial">Arial</option>
   <option value="Comic Sans MS">Comic Sans MS</option>
   <option value="Courier New">Courier New</option>
   <option value="Monotype Corsiva">Monotype</option>
   <option value="Tahoma">Tahoma</option>
   <option value="Times">Times</option>
</select>
<select id="size" onChange="fontEdit('fontsize',this[this.selectedIndex].value)">
   <option value="1">1</option>
   <option value="2">2</option>
   <option value="3">3</option>
   <option value="4">4</option>
   <option value="5">5</option>
</select>
<select id="color" onChange="fontEdit('ForeColor',this[this.selectedIndex].value)">
   <option value="black">-</option>
   <option style="color:red;" value="red">-</option>
   <option style="color:blue;" value="blue">-</option>
   <option style="color:green;" value="green">-</option>
   <option style="color:pink;" value="pink">-</option>
</select> |

For example fontEdit('fontname','times') will change the font to Times. It's easy to figure out how the other dropdown lists will work.
Finally, I made a function to set the dropdown lists' default state; this will help the Font dropdown list avoid writing "Times" after refresh (when the default font is Arial), for example. The function will be called on load, by <body onLoad="def()">.
Here is the entire code for a JavaScript text editor:

<html>
<head>
</head>
<body onLoad="def()"><center>
<div style="width:500px; text-align:left; margin-bottom:10px ">
<input type="button" id="bold" style="height:21px; width:21px; font-weight:bold;" value="B" onClick="fontEdit('bold')" />
<input type="button" id="italic" style="height:21px; width:21px; font-style:italic;" value="I" onClick="fontEdit('italic')" />
<input type="button" id="underline" style="height:21px; width:21px; text-decoration:underline;" value="U" onClick="fontEdit('underline')" /> |
<input type="button" style="height:21px; width:21px;"value="L" onClick="fontEdit('justifyleft')" title="align left" />
<input type="button" style="height:21px; width:21px;"value="C" onClick="fontEdit('justifycenter')" title="center" />
<input type="button" style="height:21px; width:21px;"value="R" onClick="fontEdit('justifyright')" title="align right" /> |
<select id="fonts" onChange="fontEdit('fontname',this[this.selectedIndex].value)">
   <option value="Arial">Arial</option>
   <option value="Comic Sans MS">Comic Sans MS</option>
   <option value="Courier New">Courier New</option>
   <option value="Monotype Corsiva">Monotype</option>
   <option value="Tahoma">Tahoma</option>
   <option value="Times">Times</option>
</select>
<select id="size" onChange="fontEdit('fontsize',this[this.selectedIndex].value)">
   <option value="1">1</option>
   <option value="2">2</option>
   <option value="3">3</option>
   <option value="4">4</option>
   <option value="5">5</option>
</select>
<select id="color" onChange="fontEdit('ForeColor',this[this.selectedIndex].value)">
   <option value="black">-</option>
   <option style="color:red;" value="red">-</option>
   <option style="color:blue;" value="blue">-</option>
   <option style="color:green;" value="green">-</option>
   <option style="color:pink;" value="pink">-</option>
</select> |
<input type="button" style="height:21px; width:21px;"value="1" onClick="fontEdit('insertorderedlist')" title="Numbered List" />
<input type="button" style="height:21px; width:21px;"value="●" onClick="fontEdit('insertunorderedlist')" title="Bullets List" />
<input type="button" style="height:21px; width:21px;"value="←" onClick="fontEdit('outdent')" title="Outdent" />
<input type="button" style="height:21px; width:21px;"value="→" onClick="fontEdit('indent')" title="Indent" />
</div>
<iframe id="textEditor" style="width:500px; height:170px;">
</iframe>
</center>
<script type="text/javascript">
<!--
textEditor.document.designMode="on";
textEditor.document.open();
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:13px; }</style> </head>');
textEditor.document.close();
function def()
{
   document.getElementById("fonts").selectedIndex=0;
   document.getElementById("size").selectedIndex=1;
   document.getElementById("color").selectedIndex=0;
}
function fontEdit(x,y)
{
   textEditor.document.execCommand(x,"",y);
   textEditor.focus();
}
-->
</script>
</body>
</html>

Digg Digg It!     Del.icio.us Del.icio.us     Reddit Reddit     StumbleUpon StumbleIt     Newsvine Newsvine     Furl Furl     BlinkList BlinkList

Rate Rate this tutorial
Comment Current Comments
by Ritesh Singh on Wednesday, February 21st 2007 at 03:22 AM

Thanks for help to set iframe body text dynamically.

by Greg on Friday, February 23rd 2007 at 10:07 PM

Thanks for the code; but it doesn\'t seem to work on Firefox.

by Sorin Sodolescu on Saturday, February 24th 2007 at 07:09 AM

I know about that problem. Unfortunatelly I couldn't set the iFrame to design mode in firefox. If I will find a solution, it will be posted here.

by Greg on Sunday, February 25th 2007 at 08:48 AM

I came up with something for the Firfox issue

Replace your script with the following. Basically I changed the def() function.

Now it's a matter of creating a table and lining up the iframe with your controls.

Also the focus(); function doesn't seem to work with FireFox. So when the page loads click the iframe and type.

I have a three year old and she is climbing on me so I'll try and come up with something to resolve these issues.


<script type="text/javascript">
<!--
function def()
{
var testframe = document.createElement("iframe");
testframe.name = testframe.id = "textEditor";


if (testframe.addEventListener){
testframe.addEventListener("load",function(e){this.contentWindow.document.designMode = "on";}, false);
} else if (testframe.attachEvent){
testframe.attachEvent("load", function(e){this.contentWindow.document.designMode = "on";});
}

document.body.appendChild(testframe);

textEditor.document.designMode="on";
textEditor.document.open();
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:13px; }</style> </head>');
textEditor.document.close();
textEditor.focus();



}
function fontEdit(x,y)
{
textEditor.document.execCommand(x,"",y);
textEditor.focus();
}
-->
</script>

by Greg on Sunday, February 25th 2007 at 02:49 PM

for got to mention I also removed the <iframe> tag from the HTML

by Sorin Sodolescu on Sunday, February 25th 2007 at 04:19 PM

Hi Greg. I have to say good job on the fix, and thank you for making the script better :)

by Greg on Monday, February 26th 2007 at 05:30 PM

My pleasure. Thanks for the starting block. I'm looking to build a Webcontrol fro .NET.

I know there are controls on the market; but I like the challange.

by JPP on Wednesday, March 21st 2007 at 06:50 PM

Hi, here is a link to the official documentation of the moilla project's conversation method.

http://www.mozilla.org/editor/ie2midas.html

mfg jpp

by Sanabi on Friday, April 27th 2007 at 03:44 AM

HI. Thanks for the script. But i want to know how will you save the edited data if you want to save and preview later.

by Sorin Sodolescu on Saturday, April 28th 2007 at 12:41 PM

Hello Sanabi. Here’s what you have to do to save the content that you’ve edited: first, change this line -
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:13px; }</style> </head>');.
You need to add a div inside the iFrame, so add this: <div id="txt"></div> in that line.
Next, you need to create a form, that has a hidden element that will retain the data.
<form action="handler.php" method="post" onsubmit="setHidden()">
<input type="hidden" name="cnt" id="cnt" />
<input type="submit" value="submit" />
</form>
and you need this function inside the head tag too :
function setHidden()
{
document.getElementById('cnt').value =
textEditor.document.getElementById('txt').document.body.innerHTML;
}
When you click submit, the setHidden() function takes the data from the iFrame and stores it in the hidden element. The hidden element is submitted, and now the data is ready do be handled by some server side script that will store it in a database.
Hope you’ll find this helpful.

by dan on Sunday, May 6th 2007 at 11:17 AM

great tutorial exactly what i was after

i have followed the above advice by creating the iframe on the fly, however i am having trouble positioning the iframe with the rest of my form. because it is using body onload='def();' the iframe appears at the end of the page. any ideas?

thanks

by Sorin Sodolescu on Sunday, May 6th 2007 at 11:27 AM

hi dan. you should try creating an element and appending the iframe to that element.
in his example greg appended the iframe to the body " document.body.appendChild(testframe); " but you can append it in a table, div and so on.

by dan on Sunday, May 6th 2007 at 11:57 AM

thanks for the very quick response!! will give that a go but i think thats the answer

thanks,

by mostafa on Wednesday, June 6th 2007 at 07:01 AM

is it possible to show the source of edited html in iframe on the page?

by Sorin Sodolescu on Wednesday, June 6th 2007 at 07:49 AM

Mostafa, it is possible to do that. You need to get the innerHTML of that iframe (see my response to sanabi's question) and then use some server side language function to display the html. In PHP you can use htmlspecialchars() or htmlentities() .

by Scott on Thursday, July 19th 2007 at 05:53 AM

great tutorial! thanks heaps...just wondering if anywone knows how you could enter a link into the iframe and have it displayed as a link in the output...im using php and trying to use the iframe to edit webpage content in a small CMS....but if the end user want to make a link within their input text, whats the easiest way? another button at the top???

by Sorin Sodolescu on Thursday, July 19th 2007 at 06:10 AM

Hi Scott

Here's my suggestion: you could put another button in the editor (the link button) and when the user clicks that button, you could have a popup where the user would type in the link text and the URL. And after the user clicks "done" you could have a JS function that will include the link tag in the main content.
Example: if he fills in the Link Text: geekpedia and the URL: http://www.geekpedia.com then that function would create &lt;a href='http://www.geekpedia.com'&gt;Geekpedia&lt;/a&gt; and then insert it in the iFrame.
Hope you'll find this helpful, good luck!

by Sorin Sodolescu on Thursday, July 19th 2007 at 06:11 AM

Sorry about that link tag, it was supposed to be <a href='http://www.geekpedia.com'>Geekpedia</a> .. just a regular link tag...

by Scott on Sunday, July 22nd 2007 at 11:08 PM

Thanks Sorin! I\'ll see how i go...I might do the same with an \'add image\' button too....

Also, does any one know how to remove the shadow border from the iframe? ive tried border=\"0\" in a css style but it seems thats you need to do that in the tag itself <iframe border=\"0\"> but in this code there is no <iframe> tag after the firefox fix???

by Sorin Sodolescu on Monday, July 23rd 2007 at 09:34 AM

Hi Scott

You could use the setAttribute () method with the firefox fix after creating the iFrame.
Example: textEditor.setAttribute("border","0");
That should work.

by Jash on Monday, July 30th 2007 at 01:38 AM

Hi Sorin,
great to read your article,,

but one issue I'm facing is that I'm using the 'src' attribute of the iframe to fill the contents after this I edit the contents and thus I need the Entire manipulated content in html form,, so can I grab the entire HTML content of the iframe, store it in a hidden field and then use that to save it?

Thanks in advance.

by Scott on Monday, July 30th 2007 at 02:28 AM

Hi Sorin,

I must have it in the wrong spot beacuse its saying - "object doesnt support this property or method" -

<div id="mydiv">
<script type="text/javascript">
<!--
function def()
{
var testframe = document.createElement("iframe");
testframe.name = testframe.id = "textEditor";


if (testframe.addEventListener){
testframe.addEventListener("load",function(e){this.contentWindow.document.designMode = "on";}, false);
} else if (testframe.attachEvent){
testframe.attachEvent("load", function(e){this.contentWindow.document.designMode = "on";});
}

document.getElementById("mydiv").appendChild(testframe);

textEditor.setAttribute("border", "0");
textEditor.setAttribute("frameborder", "0");

textEditor.document.designMode="on";
textEditor.document.open();

textEditor.document.write('<div id="txt"><head><style type="text/css">body{ font-family:arial; font-size:13px; }</style> </head><? echo $mydata ; ?></div>');
textEditor.document.close();
textEditor.focus();

}
function fontEdit(x,y)
{
textEditor.document.execCommand(x,"",y);
textEditor.focus();
}
-->
</script>

Thanks
Scott

by Sorin Sodolescu on Monday, July 30th 2007 at 08:18 AM

Hi Jash, I've already posted something about saving the content of the iFrame; just read the comment posted on Apr 28 2007 - 12:41. Hope you'll find it usefull.

Scott, I'm sorry I've lead you in the wrong way - it seems setAttribute doesn't work with frameBorder. So, to get rid of that border, you'll just have to add this line after you create the iFrame ( var testframe = document.createElement("iframe");
testframe.name = testframe.id = "textEditor"; ) :
testframe.frameBorder = "0";
Good luck!

by Scott on Monday, July 30th 2007 at 08:57 PM

Perfect! Thanks Sorin.

by Alina on Tuesday, July 31st 2007 at 03:11 AM

Sorin, faina treaba ;)

by mohammed on Thursday, August 16th 2007 at 08:03 AM

hello
how i can use it with php page ( insert information to databases by mysql )
thank you

by on Thursday, August 16th 2007 at 08:07 AM

Hi mohammed

I've already answered to this question. Just read the post from Apr 28 2007 - 12:41
It tells you how to use javascript to take the content of the iframe and put it into a hidden element. Hope you'll find it useful.

by chingmale on Friday, August 17th 2007 at 05:15 AM

i tried to pass the resulted variable to a php page, it works fine on explorer but not in firefox, i know very little in Javascript..
Here is the code below.

<html>
<head>
</head>
<body onLoad="def()"><center>
<div id="toolbar" style="width:80%; text-align:left; margin-bottom:10px; background-color: #808080;">
<input type="button" id="bold" style="height:25px; width:25px; font-weight:bold; border:1px,1px,1px,1px; background-color: transparent; background-image: url(images/bold.gif);
background-repeat: no-repeat;" value="" onClick="fontEdit('bold')" />
<input type="button" id="italic" style="height:25px; width:25px; font-style:italic; background-color: transparent; background-image: url(images/italic.gif);
background-repeat: no-repeat;" value="" onClick="fontEdit('italic')" />
<input type="button" id="underline" style="height:25px; width:25px; text-decoration:underline; background-color: transparent; background-image: url(images/underline.gif);
background-repeat: no-repeat;" value="" onClick="fontEdit('underline')" /> |
<input type="button" style="height:25px; width:25px; text-decoration:underline; background-color: transparent; background-image: url(images/left_just.gif);
background-repeat: no-repeat;" value="" onClick="fontEdit('justifyleft')" title="align left" />
<input type="button" style="height:25px; width:25px; text-decoration:underline; background-color: transparent; background-image: url(images/centre.gif);
background-repeat: no-repeat;"value="" onClick="fontEdit('justifycenter')" title="center" />
<input type="button" style="height:25px; width:25px; text-decoration:underline; background-color: transparent; background-image: url(images/right_just.gif);
background-repeat: no-repeat;" value="" onClick="fontEdit('justifyright')" title="align right" /> |
<select id="fonts" onChange="fontEdit('fontname',this[this.selectedIndex].value)">
<option value="">[Font]</option>
<option value="Arial">Arial</option>
<option value="Comic Sans MS">Comic Sans MS</option>
<option value="Courier New">Courier New</option>
<option value="Monotype Corsiva">Monotype</option>
<option value="Tahoma">Tahoma</option>
<option value="Times">Times</option>
</select>
<select id="size" onChange="fontEdit('fontsize',this[this.selectedIndex].value)">
<option value="">[Size]</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<select id="color" onChange="fontEdit('ForeColor',this[this.selectedIndex].value)">
<option value="">[Colour]</option>
<option value="black">-</option>
<option style="color:red;" value="red">-</option>
<option style="color:blue;" value="blue">-</option>
<option style="color:green;" value="green">-</option>
<option style="color:pink;" value="pink">-</option>
</select> |
<input type="button" style="height:25px; width:25px; text-decoration:underline; background-color: transparent; background-image: url(images/numbered_list.gif);
background-repeat: no-repeat;"value="" onClick="fontEdit('insertorderedlist')" title="Numbered List" />
<input type="button" style="height:25px; width:25px; text-decoration:underline; background-color: transparent; background-image: url(images/list.gif);
background-repeat: no-repeat;"value="" onClick="fontEdit('insertunorderedlist')" title="Bullets List" />
<input type="button" style="height:25px; width:25px; text-decoration:underline; background-color: transparent; background-image: url(images/outdent.gif);
background-repeat: no-repeat;"value="" onClick="fontEdit('outdent')" title="Outdent" />
<input type="button" style="height:25px; width:25px; text-decoration:underline; background-color: transparent; background-image: url(images/indent.gif);
background-repeat: no-repeat;"value="" onClick="fontEdit('indent')" title="Indent" />
</div>
<div id="frame">
</div>
<form action="handler.php" method="post" onsubmit="setHidden()">
<input type="hidden" name="cnt" id="cnt" />
<input type="submit" value="Submit" />



<script type="text/javascript">
<!--
function def()
{
var testframe = document.createElement("iframe");
testframe.name = testframe.id = "textEditor";
testframe.width = 500;

if (testframe.addEventListener){
testframe.addEventListener("load",function(e){this.contentWindow.document.designMode = "on";}, false);
} else if (testframe.attachEvent){
testframe.attachEvent("load", function(e){this.contentWindow.document.designMode = "on";});
}

frame.appendChild(testframe);

textEditor.document.designMode="on";
textEditor.document.open();
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:14px;}</style> </head><div id="txt"></div>');
textEditor.document.close();
textEditor.focus();



}
function fontEdit(x,y)
{
textEditor.document.execCommand(x,"",y);
textEditor.focus();
}
function setHidden()
{
document.getElementById('cnt').value = textEditor.document.getElementById('txt').document.body.innerHTML;
}
-->
</script>
</center>
</body>
</html>

by Sorin Sodolescu on Friday, August 17th 2007 at 06:17 AM

Hi, first of all sorry for posting a method that doesn't work in firefox.
Here is the fix:
- first of all, close your form, the </form> tag is missing
- secondly, remove the txt div from the def() function, because it is no longer necessary
- next, you have to change your setHidden() function:

function setHidden()
{
var frameContent=frames['textEditor'].document.body.innerHTML;
document.getElementById('cnt').value=frameContent;
}

Hope this solves your problem.

by chingmale on Friday, August 17th 2007 at 09:40 AM

Thanks for your quick reply

it does work now...

however, if i press 'ENTER', on Firefox, it passes a '<br>' tag
but in Internet Explorer, it passes '<p></p>'...

any idea which i can get out of it?!

by Sorin Sodolescu on Friday, August 17th 2007 at 09:46 AM

Hi, here's a quick solution: str_replace("<p></p>","<br />",$content). Might be what you're looking for, because you probably wont have a lot of empty paragraphs.

by Ewan Frost on Thursday, August 23rd 2007 at 09:44 AM

Hey
First of all, great tutorial and love the end result.
One problem though. In a project I\'m working on, I have to load the text editor into the same page more than once (AJAX). I\'m inserting the Iframe into a div created by the AJAX.

Problem is, it only works the first time, and after that none of the tools (eg Bold, Italics etc) work. I tried killing the iframe each time, but that didn\'t work.

If anyone could help, it would be hugely appreciated !

by Sorin Sodolescu on Thursday, August 23rd 2007 at 10:04 AM

Hi Ewan.

I have to admin that I don't have much experience with AJAX and I don't know how much good this post will do, but I'm just trying to be helpful.
So, I think the tools don't work because the functions are affecting the textEditor object. For example:
function fontEdit(x,y)
{
textEditor.document.execCommand(x,"",y);
textEditor.focus();
}

And one reason for your problem might be the fact that the newly created editor doensn't have it's id="textEditor".
I hope this is useful, but if it turns out this is not the problem, I wish you good luck finding a solution.

by Sorin Sodolescu on Thursday, August 23rd 2007 at 10:05 AM

Just a small correction: i meant "admit" not "admin". Sorry about that.

by Ewan Frost on Thursday, August 23rd 2007 at 11:02 AM

Thanks for the reply,

What I'm doing is removing the Iframe using removeChild called from the parent div before the AJAX is called, then calling the def() function after the AJAX request has finished loading. So the iFrame gets appended into the new form.

My understanding of DOM nodes etc isn't the healthiest so is there maybe some chance that the old iFrame (with id : textEditor ) is still alive when the new one is created and thats causing the problems?

Thanks again

by Sorin Sodolescu on Thursday, August 23rd 2007 at 11:09 AM

Hi again
According to this article http://developer.mozilla.org/en/docs/DOM:element.removeChild an element that was removed using removeChild still exists in the memory, so you might be right about this issue.
Sorry I can't be very helpful.

by Ewan Frost on Thursday, August 23rd 2007 at 11:13 AM

Seems looking at code with fresh eyes always works.

Managed to figure it out, and incase someone wants to do something similar, heres the code :

var theEditor;

function def()
{
testframe = document.createElement("iframe");
testframe.name = testframe.id = "textEditor";
testframe.frameBorder = "0";
testframe.style.border = "thin solid #CCCCCC";


if (testframe.addEventListener){
testframe.addEventListener("load",function(e){this.contentWindow.document.designMode = "on";}, false);
} else if (testframe.attachEvent){
testframe.attachEvent("load", function(e){this.contentWindow.document.designMode = "on";});
}

tester = document.getElementById('The div it will be in');
theEditor = document.getElementById("The div it will be in").appendChild(testframe);
theEditor = theEditor.contentWindow || theEditor.contentDocument

textEditor.document.designMode="on";
textEditor.document.open();
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:13px; }</style> </head>');
textEditor.document.close();
textEditor.focus();
}

function fontEdit(x,y)
{
theEditor.document.execCommand(x,"",y);
theEditor.focus();
}

function killEditor()
{
toKill = document.getElementById("textEditor");
theKilled = toKill.parentNode.removeChild(toKill);
}


The border changing is just there because I hate the standard iframe border, so feel free to get rid of that. Thanks again for the tutorial and the support.

by Ewan Frost on Thursday, August 23rd 2007 at 11:15 AM

Just noticed, the tester variable can go, it was there because I needed to check whether it was reading the new div or not.

by Kimberly on Sunday, August 26th 2007 at 08:47 PM

This is a really great tutorial! I will probably be asking questions soon, so I thought I would thank you before I start being a pest. ;)

by Sorin Sodolescu on Monday, August 27th 2007 at 06:59 AM

Hi Kimberly

I'm glad you like the tutorial. Feel free to ask any question, but I suggest you read all the comments first, as other people already found the answers they needed, and who knows... you might find your answer there.

by Christian Tvedt on Sunday, September 9th 2007 at 03:22 PM

Hey! What an elegant text editor. I just wonder...
...what exactly can you use it for? Is it possible to save the text and retrieve it \"uneditable\", e.g.?

You see, I\'m looking for a text editor (like this one!) that can save the text for example as a html-file, and that can be loaded in a non-editable state. See what I mean?

by Sorin Sodolescu on Sunday, September 9th 2007 at 03:30 PM

Hey Christian

Well, you can use the editor any way you want. This tutorial only explain how to build the editor, but in previous comments you can find out how to save the content into a database.
From that point, you can write some server side scripts to pull the content from the database and create a file with that. It is quite easy too.
But, if you don't know how to write that code, I can recommend you a great (advanced) editor that can do what you need. You can find FCKeditor here: http://www.fckeditor.net/

Good luck.

by Jeremy on Thursday, October 25th 2007 at 05:57 PM

I added a little bit to it. This modification allows you to place all the js in a separate file and add multiple instances of the textbox to the page with minimal code. The IE / FF support has also been improved some.


<html>
<head>
<script type="text/javascript">
<!--

function initTextEditor(holderName, hiddenName)
{
//Define the frame
var holder=document.getElementById(holderName);
var textEditor = document.createElement("iframe");
textEditor.name = textEditor.id = holderName + "_textEditor";

//Define the control bar
var controls='<div style="width:500px; text-align:left; margin-bottom:10px ">';
controls+='<input type="button" id="bold" style="height:21px; width:21px; font-weight:bold;" value="B" onClick="fontEdit(\'' + textEditor.id + '\', \'bold\')" />\n';
controls+='<input type="button" id="italic" style="height:21px; width:21px; font-style:italic;" value="I" onClick="fontEdit(\'' + textEditor.id + '\', \'italic\')" />\n';
controls+='<input type="button" id="underline" style="height:21px; width:21px; text-decoration:underline;" value="U" onClick="fontEdit(\'' + textEditor.id + '\', \'underline\')" /> |\n';
controls+='<select id="color" onChange="fontEdit(\'' + textEditor.id + '\', \'ForeColor\',this[this.selectedIndex].value)">'
+ ' <option value="black">-</option>'
+ ' <option style="color:red;" value="red">Red</option>'
+ ' <option style="color:blue;" value="blue">Blue</option>'
+ ' <option style="color:green;" value="green">Green</option>'
+ ' <option style="color:pink;" value="pink">Pink</option>'
+ '</select>\n';
controls+='</div>\n';

//Add the controls to the page
holder.innerHTML=controls;
holder.appendChild(textEditor);

//Init the iframe
var w3c = textEditor.contentDocument !== undefined ? true : false;
var idoc = w3c ? textEditor.contentDocument : textEditor.contentWindow.document;
idoc.open();
idoc.close();
idoc.designMode = w3c ? "on" : "On";




if (w3c)
{
textEditor.contentDocument.addEventListener("blur", function(oEvent){
document.getElementById(hiddenName).value=textEditor.contentWindow.document.body.innerHTML;
}, false);
} else {
textEditor.attachEvent("onblur", function(){
document.getElementById(hiddenName).value=textEditor.contentWindow.document.body.innerHTML;
});
}
}

function fontEdit(editorName,x,y)
{
var textEditor=document.getElementById(editorName);
textEditor.contentWindow.document.execCommand(x,"",y);
textEditor.contentWindow.focus();
}
-->
</script>

</head>
<body><center>

<input type="hidden" id="textEditorHidden" runat="server" />
<div id="textEditorHolder" style="width:500px; text-align:left; margin-bottom:10px "></div>
<script>initTextEditor('textEditorHolder', 'textEditorHidden');</script>

</center>
</body>
</html>

by naresh on Tuesday, November 13th 2007 at 01:38 AM

Hello Sorin

Can we use outer css file for styles instead of changing font-face, font-size and font-color

Thanks

by andy on Wednesday, November 14th 2007 at 10:39 PM

hello, first of all, Exceptional tutorial, really...

as almost everyone, i\\\'m trying to create an editor that will post what i type an edit with the control in html.
i don\\\'t know much oj javascript... at all i would say...
i can understand what the code means, but when it comes on where to put it i\\\'m lost.
i know it was already explained... but i can\\\'t get it to work... and reading the post again does not really help either...

so, how do i make it so that the iframe passes the data out so i can collect it in php?

the form i\\\'m trying to make is really similar to this very same type, so i added an imput box for the title,
and that passes correctly
here the code i was using

[code]
<body onLoad=\\\"def()\\\">
<center>
<div style=\\\"width:500px; text-align:left; margin-bottom:10px \\\">
<select id=\\\"fonts\\\" onChange=\\\"fontEdit(\\\'fontname\\\',this[this.selectedIndex].value)\\\">
<option value=\\\"Arial\\\">Arial</option>
<option value=\\\"Comic Sans MS\\\">Comic Sans MS</option>
<option value=\\\"Courier New\\\">Courier New</option>
<option value=\\\"Monotype Corsiva\\\">Monotype</option>
<option value=\\\"Tahoma\\\">Tahoma</option>
<option value=\\\"Times\\\">Times</option>
</select>

<select id=\\\"size\\\" onChange=\\\"fontEdit(\\\'fontsize\\\',this[this.selectedIndex].value)\\\">
<option value=\\\"1\\\">1</option>
<option value=\\\"2\\\">2</option>
<option value=\\\"3\\\">3</option>
<option value=\\\"4\\\">4</option>
<option value=\\\"5\\\">5</option>
</select>

<select src=\\\"images/color.gif\\\" id=\\\"color\\\" onChange=\\\"fontEdit(\\\'ForeColor\\\',this[this.selectedIndex].value)\\\">
<option value=\\\"black\\\">-</option>
<option style=\\\"color:red;\\\" value=\\\"red\\\">-</option>
<option style=\\\"color:blue;\\\" value=\\\"blue\\\">-</option>
<option style=\\\"color:green;\\\" value=\\\"green\\\">-</option>
<option style=\\\"color:pink;\\\" value=\\\"pink\\\">-</option>
</select>

<select id=\\\"color\\\" onChange=\\\"fontEdit(\\\'BackColor\\\',this[this.selectedIndex].value)\\\">
<option value=\\\"black\\\">||</option>
<option style=\\\"background-color:red;\\\" value=\\\"red\\\">-</option>
<option style=\\\"background-color:blue;\\\" value=\\\"blue\\\">-</option>
<option style=\\\"background-color:green;\\\" value=\\\"green\\\">-</option>
<option style=\\\"background-color:pink;\\\" value=\\\"pink\\\">-</option>
</select> |
</br>


<input type=\\\"image\\\" src=\\\"images/bold.gif\\\" id=\\\"bold\\\" style=\\\"height:auto; width:auto; font-weight:bold;\\\" value=\\\"\\\" onClick=\\\"fontEdit(\\\'bold\\\')\\\" />
<input type=\\\"image\\\" src=\\\"images/italics.gif\\\" id=\\\"italic\\\" style=\\\"height:auto; width:auto; font-style:italic;\\\" value=\\\"\\\" onClick=\\\"fontEdit(\\\'italic\\\')\\\" />
<input type=\\\"image\\\" src=\\\"images/underline.gif\\\" id=\\\"underline\\\" style=\\\"height:auto; width:auto; text-decoration:underline;\\\" value=\\\"\\\" onClick=\\\"fontEdit(\\\'underline\\\')\\\" /> |
<input type=\\\"image\\\" src=\\\"images/right.gif\\\" style=\\\"height:auto; width:auto;\\\"value=\\\"\\\" onClick=\\\"fontEdit(\\\'justifyleft\\\')\\\" title=\\\"align left\\\" />
<input type=\\\"image\\\" src=\\\"images/center.gif\\\" style=\\\"height:auto; width:auto;\\\"value=\\\"\\\" onClick=\\\"fontEdit(\\\'justifycenter\\\')\\\" title=\\\"center\\\" />
<input type=\\\"image\\\" src=\\\"images/left.gif\\\" style=\\\"height:auto; width:auto;\\\"value=\\\"\\\" onClick=\\\"fontEdit(\\\'justifyright\\\')\\\" title=\\\"align right\\\" />
<input type=\\\"image\\\" src=\\\"images/justified.gif\\\" style=\\\"height:auto; width:auto;\\\"value=\\\"\\\" onClick=\\\"fontEdit(\\\'justify\\\')\\\" title=\\\"align justify\\\" /> |
<input type=\\\"image\\\" src=\\\"images/nulist.gif\\\" style=\\\"height:auto; width:auto;\\\"value=\\\"\\\" onClick=\\\"fontEdit(\\\'insertorderedlist\\\')\\\" title=\\\"Numbered List\\\" />
<input type=\\\"image\\\" src=\\\"images/ollist.gif\\\" style=\\\"height:auto; width:auto;\\\"value=\\\"\\\" onClick=\\\"fontEdit(\\\'insertunorderedlist\\\')\\\" title=\\\"Bullets List\\\" />
<input type=\\\"image\\\" src=\\\"images/indent.gif\\\" style=\\\"height:auto; width:auto;\\\"value=\\\"\\\" onClick=\\\"fontEdit(\\\'indent\\\')\\\" title=\\\"Indent\\\" />
<input type=\\\"image\\\" src=\\\"images/outdent.gif\\\" style=\\\"height:auto; width:auto;\\\"value=\\\"\\\" onClick=\\\"fontEdit(\\\'outdent\\\')\\\" title=\\\"Outdent\\\" />
</div>

<form action=\\\"insert.php\\\" method=\\\"post\\\">
</br>
</br>
<br>Title: <input type=\\\"text\\\" name=\\\"entrytitle\\\"/>
</br>
</br>
<table></table>
</br>

<input type=\\\"submit\\\" />
</form>
</center>


<script type=\\\"text/javascript\\\">
<!--
function def()
{
var testframe = document.createElement(\\\"iframe\\\");
testframe.name = testframe.id = \\\"textEditor\\\";


if (testframe.addEventListener){
testframe.addEventListener(\\\"load\\\",function(e){this.contentWindow.document.designMode = \\\"on\\\";}, false);
} else if (testframe.attachEvent){
testframe.attachEvent(\\\"load\\\", function(e){this.contentWindow.document.designMode = \\\"on\\\";});
}

document.body.appendChild(testframe);

textEditor.document.designMode=\\\"on\\\";
textEditor.document.open();
textEditor.document.write(\\\'<head><style type=\\\"text/css\\\">body{ font-family:arial; font-size:13px; }</style> </head>\\\');
textEditor.document.close();
textEditor.focus();



}
function fontEdit(x,y)
{
textEditor.document.execCommand(x,\\\"\\\",y);
textEditor.focus();
}
-->
</script>

</body>
</html>
[/code]

i\\\'m also trying to append the box to the fake Table that\\\'s upthere, but changing from body to table like suggested does not do it?
what am i doing wrong?

can someone spend a second to help me out on the correct position of where to put the div and all the other stuff to get the invisible form to pass data out?
and i will i do that with 2 forms at once? (since one form is needed for the title i assume...)
thanks in advance, and once again, this is the best tutorial i found after 6 hours of research, so thanks for making it!

by Sorin Sodolescu on Friday, November 16th 2007 at 04:58 AM

Hello Naresh and Andy. First of all I appologize for taking so long to answer.
Naresh, the execCommand() function doesn't take "class" or "id" as parameters, so you can't use stylesheets with execCommand(). There might be a function that does that, but I'm not aware of it. You can use execCommand("styleWithCSS",,true) to use inline CSS instead of HTML formatting, but this is not supported by all browsers.
Andy, you will only need one form to pass the data to PHP (we'll get to that soon). First, let's talk about the table. To append the Iframe to a table cell you will have to give the cell an id. Also, you'll need to put the editor controls in the table too, so everything lines up. Here's an example:
<table>
<tr>
<td id="controls"> ADD HERE ALL OF THE EDITOR CONTROLS</td></tr><tr>
<td id="editorCell"></td></tr></table>

Now, in the js code you'll have to replace document.body.appendChild(testframe); with
document.getElementById('editorCell').appendChild(testframe).

Moving on to the form - you'll need 2 input fields there: a textbox for the title, and a hidden element to store the editors content.
The form might look like this:
<form action="insert.php" method="post" onsubmit="setHiddenValue()">
Title <input type="text" name="entryTitle" /><br />
<input type="hidden" name="editorContent" id="editorContent" />
<input type="submit" value="Submit" />
</form>

You can see that when the form is submitted the setHiddenValue function is called. This function will simply get the content of the Iframe and put in in your hidden element. Now all your information is passed to PHP (the Editor content will be stored in the $_POST['editorContent'] variable).
Of course, you will need the setHiddenValue function:
function setHidden()
{
document.getElementById('editorContent').value = textEditor.document.body.innerHTML;
}
(that function goes between the script tags)
That's about it. Hopefully you won't have any problems with the editor now. Good luck!
Sorin

by Ellen Bloom on Saturday, December 8th 2007 at 05:11 PM

Sorin thank you for a great tutorial, I had no idea text editors can be so easy to make. Do you know if this works across with less popular browsers like Safari and Opera?

by Sorin Sodolescu on Sunday, December 9th 2007 at 10:01 AM

Hello Ellen
I'm glad you like this tutorial. The text editor works Opera9 and Safari3 for Windows. But in Safari3 there is a small issue: you can't change the color of the text. I don't know what to tell you about older versions of those browsers.
I hope you'll find this information helpful,
Sorin

by Ben Tremblay on Tuesday, December 11th 2007 at 07:23 PM

Nice article!

Hey, did you notice that a lotta people went to a lotta trouble to implement pop-up blockers? I got pop-up ads here. So don\'t expect me to link to anything you ever right, ok?

*shrug*

by Michelle on Tuesday, January 8th 2008 at 08:28 AM

Thanks so much! Love this!

by SAndy on Tuesday, January 8th 2008 at 10:06 AM

Amazing work.... Very simple n clear explanation... Kudos!! Thanks

by Mark Pilar on Saturday, January 19th 2008 at 05:15 AM

Thank you for posting this tutorial. This will help me a lot in doing my CMS Project because i want to put a rich text editor in changing the contents of my website.

by Dina on Tuesday, February 12th 2008 at 01:08 PM

Nice work
but i have a problem the iframe in firefox dosen\\\'t work i can\\\'t write in it anything why?

by Sorin Sodolescu on Tuesday, February 12th 2008 at 01:18 PM

Hi Dina

At the time i wrote the tutorial, I wasn't able to set the iframe to design mode, but one of the visitors managed to solve that bug and even posted the fix here. So to get rid of the FF problem please check out Greg's comment on Feb 25 2007 - 08:48.

by Dina on Tuesday, February 12th 2008 at 04:09 PM

Thanx so much Sorin
i fixed the problem of FF
now i have another problem can i replace the iframe with textbox?

by Sorin Sodolescu on Tuesday, February 12th 2008 at 04:21 PM

Hello Dina

Good to hear you solved the FF issue. No, you cannot use a textbox because a textbox doesn't parse HTML, so the formatting wouldn't affect the appearence of the text.
In case you wanted to use a textbox with a form to pass the data to a server side language, I suggest you read the comment i posted on Apr 28 2007 - 12:41.

Best regards,
Sorin.

by Dina on Tuesday, February 12th 2008 at 05:23 PM

sorry i tried it but some errors appears to me
File"handler.php" not found

by Sorin Sodolescu on Tuesday, February 12th 2008 at 05:42 PM

handler.php is the php script that the data from the form gets sent to. You can change that page with any page you want, but you have to create that page too (and write the code to handle the data).

by Dina on Tuesday, February 12th 2008 at 06:12 PM

Thanx Sorin for ur fast reply
i wanna make sure of something ur first code when i put it .aspx
the iframe doesn't work it is only a shape but i can't write anything in it

by Dina on Tuesday, February 12th 2008 at 06:14 PM

Thanx Sorin for ur fast reply
i wanna make sure of something ur first code when i put it .aspx
the iframe doesn't work it is only a shape but i can't write anything in it

by Cikku Psaila on Wednesday, February 13th 2008 at 06:35 AM

First of all thanks for this tutorial.

Secondly, whenever I hit the enter key, to start a new line, the spacing is too large, as if I have hit the enter key twice. Although this may not effect the final output of the text editor when saved in a DB, it may confuse the users when using it.

Any workaround?
Thx

by Sorin Sodolescu on Wednesday, February 13th 2008 at 07:56 AM

Hi Dina

I'm sorry, unfortunatelly I can't help you with your .aspx page because I don't know .net. Good luck fixing it.

Cikku, the spacing between the lines is so large because every new line is a new paragraph, and by default the margin attribute is set to a specific value. To work around that you'll have to edit the line that sets the CSS for the iframe to this:
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:13px;} p{margin:0px;}</style> </head>');
Notice the "p{margin:0px;}" part.That should do the trick.
Best regards,
Sorin.

by adapa sailesh kumar on Friday, February 15th 2008 at 11:15 AM

This is Just Outstanding Stuff. Got A lot from This Site Thanx For One and all.

by Manoj on Thursday, February 21st 2008 at 02:48 AM

Hello Friend,

Can u tell me how to create the link(s) to the selected text.

by akmal on Thursday, February 21st 2008 at 05:55 AM

can u teach me, how to make the text editor by using the java script? i want the example of the script if u can tell me how to make it.. plez reply immediately! tq so much

by Sorin Sodolescu on Thursday, February 21st 2008 at 06:53 AM

Hi Manoj and akmal

In this post you will be able to dinamically create and iframe and how to put a link button for it.

Manoj, first of all, you will have to create a div that will contain some textbox, and use CSS to make it invisible.
<div id="linkInsert" style="background-color:white; height:160px; width:300px; border:1px solid black; position:absolute; top:50px; left:40%; padding:10px; display:none">
Link Text <input type="text" id="l1" /><br />
<select id="prot">
<option value="http://">HTTP</option>
<option value="https://">HTTPS</option>
<option value="ftp://">FTP</option>
</select>
URL <input type="text" id="l2" /><br />
<input type="button" value="Insert Link" onclick="insertLink()" />
</div>

Now you will need to create a button that will make this div visible:
<input type="button" style="height:21px; width:50px;"value="LINK" onClick="showLinkEditor()" title="Insert Link" />

This is all the HTML you will need. You can see that the link button will call the showLinkEditor() function. That function will toggle the visibility of the div. This is the function:
function showLinkEditor(){
e = document.getElementById('linkInsert');
if(e.style.display=="none") e.style.display = "block";
else e.style.display = "none";
}

After you fill in all the fields in the div, and click INSERT LINK the insertLink() function will be called. This function will take the data that you've entered and add it to the text editor.
function insertLink(){
content = textEditor.document.body.innerHTML;
linkText = document.getElementById('l1').value;
linkUrl = document.getElementById('l2').value;
protocol = document.getElementById('prot').value;
lnk = "<a href='"+protocol+linkUrl+"'>"+linkText+"</a>&nbsp;";
textEditor.document.body.innerHTML = content+lnk;
document.getElementById('l1').value="";
document.getElementById('l2').value="";
document.getElementById('linkInsert').style.display="none";
content = textEditor.document.body.innerHTML;
content = content.replace(/<br><a/,"<a");
textEditor.document.body.innerHTML=content+" ";
}
Because when inserting a link Firefox also adds a <br > tag, that function adds the link to the iframe, then removes the extra br tag and adds the text again. After inserting the link, the function will hide the link "editor". Here is the entire code:

<html>
<head>
</head>
<body onLoad="def()"><center>
<div style="width:500px; text-align:left; margin-bottom:10px ">
<input type="button" id="bold" style="height:21px; width:21px; font-weight:bold;" value="B" onClick="fontEdit('bold')" />
<input type="button" id="italic" style="height:21px; width:21px; font-style:italic;" value="I" onClick="fontEdit('italic')" />
<input type="button" id="underline" style="height:21px; width:21px; text-decoration:underline;" value="U" onClick="fontEdit('underline')" /> |
<input type="button" style="height:21px; width:21px;"value="L" onClick="fontEdit('justifyleft')" title="align left" />
<input type="button" style="height:21px; width:21px;"value="C" onClick="fontEdit('justifycenter')" title="center" />
<input type="button" style="height:21px; width:21px;"value="R" onClick="fontEdit('justifyright')" title="align right" /> |
<select id="fonts" onChange="fontEdit('fontname',this[this.selectedIndex].value)">
<option value="Arial">Arial</option>
<option value="Comic Sans MS">Comic Sans MS</option>
<option value="Courier New">Courier New</option>
<option value="Monotype Corsiva">Monotype</option>
<option value="Tahoma">Tahoma</option>
<option value="Times">Times</option>
</select>
<select id="size" onChange="fontEdit('fontsize',this[this.selectedIndex].value)">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<select id="color" onChange="fontEdit('ForeColor',this[this.selectedIndex].value)">
<option value="black">-</option>
<option style="color:red;" value="red">-</option>
<option style="color:blue;" value="blue">-</option>
<option style="color:green;" value="green">-</option>
<option style="color:pink;" value="pink">-</option>
</select> |
<input type="button" style="height:21px; width:21px;"value="1" onClick="fontEdit('insertorderedlist')" title="Numbered List" />
<input type="button" style="height:21px; width:21px;"value="&#9679;" onClick="fontEdit('insertunorderedlist')" title="Bullets List" />
<input type="button" style="height:21px; width:21px;"value="&#8592;" onClick="fontEdit('outdent')" title="Outdent" />
<input type="button" style="height:21px; width:21px;"value="&#8594;" onClick="fontEdit('indent')" title="Indent" />
<input type="button" style="height:21px; width:50px;"value="LINK" onClick="showLinkEditor()" title="Insert Link" />
</div>
</iframe>
</center>
<script type="text/javascript">
<!--
function def()
{
var testframe = document.createElement("iframe");
testframe.name = testframe.id = "textEditor";


if (testframe.addEventListener){
testframe.addEventListener("load",function(e){this.contentWindow.document.designMode = "on";}, false);
} else if (testframe.attachEvent){
testframe.attachEvent("load", function(e){this.contentWindow.document.designMode = "on";});
}

document.body.appendChild(testframe);

textEditor.document.designMode="on";
textEditor.document.open();
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:13px; }</style> </head>');
textEditor.document.close();
textEditor.focus();
}
function fontEdit(x,y)
{
textEditor.document.execCommand(x,"",y);
textEditor.focus();
}

function showLinkEditor(){
e = document.getElementById('linkInsert');
if(e.style.display=="none") e.style.display = "block";
else e.style.display = "none";
}

function insertLink(){
content = textEditor.document.body.innerHTML;
linkText = document.getElementById('l1').value;
linkUrl = document.getElementById('l2').value;
protocol = document.getElementById('prot').value;
lnk = "<a href='"+protocol+linkUrl+"'>"+linkText+"</a>&nbsp;";
textEditor.document.body.innerHTML = content+lnk;
document.getElementById('l1').value="";
document.getElementById('l2').value="";
document.getElementById('linkInsert').style.display="none";
content = textEditor.document.body.innerHTML;
content = content.replace(/<br><a/,"<a");
textEditor.document.body.innerHTML=content+" ";
}

</script>
<div id="linkInsert" style="background-color:white; height:160px; width:300px; border:1px solid black; position:absolute; top:50px; left:40%; padding:10px; display:none">
Link Text <input type="text" id="l1" /><br />
<select id="prot">
<option value="http://">HTTP</option>
<option value="https://">HTTPS</option>
<option value="ftp://">FTP</option>
</select>
URL <input type="text" id="l2" /><br />
<input type="button" value="Insert Link" onclick="insertLink()" />
</div>
</body>
</html>

by Manoj on Thursday, February 21st 2008 at 07:48 AM

Thnx u very very much

by Mukhtar on Sunday, February 24th 2008 at 02:58 AM

how to make with textarea not with iframe?

by Sebastian on Thursday, February 28th 2008 at 02:46 AM

Thx u very much.

Great work.

Works perfect in FF (2+), IE(6+), Opera(9.24) (tested it).

Greetz,
Seb

by Mathieu on Friday, February 29th 2008 at 04:50 PM

First of all, thank you very much for this tutorial. It helped me out a lot to create my own text editor.

As I understand it, execCommand() is used to add the <i> tags and such at the start and at the end of a selected text. Would it be possible to do such thing to add the option for the user to add blocks such as <h1> </h1>? Same for <hr> I can add it at the end of the text by adding it at the end of innerHTML but how could I place it at the cursor\'s position in the text?

Thank you very much.

by Mathieu on Friday, February 29th 2008 at 06:16 PM

Alright, I've searched a lot on how to do what I wanted... For FF it is no problem at all but for IE it's another story. (I only tested on FF2 and IE7) I know it's ugly but it does the job for now and might give ideas to others and do such a thing... You can modify the first IF if you want to accept more than just H1 and pass a variable instead of "H1" where it is needed.

function fontEdit(x,y)
{
if(x == "h1"){
if(document.selection){ //IE detection
sText = textEditor.document.selection.createRange();
sText.execCommand("createlink","",""); //Create a A node arround the selection
temp = sText.parentElement().innerHTML; //Get HTML inside the new node AKA selected html
newNode = textEditor.document.createElement("h1"); //Create the H1 wanted.
replacement = sText.parentElement().replaceNode(newNode); //Replace the newly created link with the H1
newNode.innerHTML = temp; //Insert the HTML of the selection
}else if(document.getSelection){ //FF detection
sText = textEditor.window.getSelection();
myTag = textEditor.document.createElement("h1");
sText.getRangeAt(0).surroundContents(myTag);
}
}else{
textEditor.document.execCommand(x,"",y);
document.getElementById("textEditor").focus();
}
}


On another note, I added a little style on the IFrame's body to show a text cursor to make sure the users don't get confused between a usual textarea and "our textarea" it needs to be placed AFTER any write() functions called on textEditor:

textEditor.document.designMode="on";
textEditor.document.open();
textEditor.document.write(\'<head><style type="text/css">body{ font-family:arial; font-size:13px; }</style> </head>\');
textEditor.document.close();
textEditor.document.body.style.margin = "0";
textEditor.document.body.style.height = "100%";
textEditor.document.body.style.cursor = "text";

Hope the text displays fine cuz the copy/paste is ugly =/

by Mathieu on Friday, February 29th 2008 at 06:20 PM

I came across a little bug with my code when trying to select the WHOLE text and put it into the H1... Simply fixed by changing one line.


sText.execCommand(\"createlink\",\"\",\"\"); //Create a A node arround the selection

Should be

textEditor.document.execCommand(\"createlink\",\"\",\"\"); //Create a A node arround the selection

by Mathieu on Friday, February 29th 2008 at 06:41 PM

I was too happy for it to work and posted way too fast... The code works just fine when used IN tags but here's the problem. I'll use an example since my English ain't that good.

We have "Some <b>text in bold</b> for a title"
User selects "bold</b> for a"
You see, a tag ends in the selection. When trying to get the parentElement() IE will not be able to define the element we want (the link created) and will, in that exemple put the whole text in the H1 tag and the link won't be replaced.

One way to fix this would be by inserting an IF statement as follow:
if (sText.parentElement().tagName == "A"){
//And do the replacement here
}

That way we can be sure that we are moddifying the right element. But the code won't do anything if the situation stated above happens.
And I do not want an alert telling the user to remove the formatting of his text before doing the h1.

Yet a quick fix... But I told you it was an ugly code =P

by Prasad on Tuesday, April 15th 2008 at 04:46 PM

A Wonderful Wonderful Article on \"Howto of Rich Text Editor\".
Awsome!!!

Thanks for making it available.
I have a question:
Some how it doesn\'t work on Linux/Konqueror....??? Just to make it more browser independent.

It has been a great learning process through the COMMENTS tooo....
thanks Soren for your effort.
Prasad.

by Phill on Friday, April 18th 2008 at 08:43 AM

Hi, first of all this is a great tutorail, im still really new to javascript and enyjoyed this alot, i have been working with PHP and mysql for a little while and in the past for submitting text i have used a texaarea on my forms. So thank you for making this available

anywho i have a small issuse with firefox, i went through the fix mentioned by Greg in an earlier post and that seemed to do the trick when working on my localhost server, however if i upload it to a remote sever i have it only passes the text to my PHP script and not the styles, where as in IE the style goes accross fine. i was just wandering if anybody had any clue to what may cause this difference between the local and remote servers? any help would be greatly appreciated.

by Sumalatha on Friday, April 25th 2008 at 01:49 AM

the iframe editor works fine but i have problem when I bind data to Iframe from database.
Thing is whatever data I edited I store in the database but when I come back to the page for editing I want the data I submitted to be displayed in my Iframe.But when I bind database column to THe Iframe editor it's design mode gets blocked and I cant type anything into it.If I replace iframe with textbox or textarea databinding is possible but I cant apply bold,italics etc

by sumalatha on Tuesday, May 6th 2008 at 03:52 AM

how to align justify.the tutorial contains only for left justify,rightjustify and center

by Gideon Farrell on Tuesday, June 10th 2008 at 12:19 PM

Thanks Sorin: great tutorial... I was a bit baffled as to how I would achieve this (and initially tried to do it via a <div> and innerHTML

by Nikolay on Saturday, June 14th 2008 at 05:42 AM

Hi thanks for the tutorial. I have one problem:
function is:

function init() {
if (isIE) {
frames['text1'].document.body.innerHTML=document.getElementById('hidden1').value;
frames['text2'].document.body.innerHTML=document.getElementById('hidden2').value;
}
else {
document.getElementById('text1').contentWindow.document.body.innerHTML=document.getElementById('hidden1').value;
document.getElementById('text2').contentWindow.document.body.innerHTML=document.getElementById('hidden2').value;
}
}


In the page i have form:

<img src="img/editor.jpg" id="img_ed1" alt="Editor" width=30 height=30 onclick="show_editor('1');">
<form>
<iframe id="text1" class="text_frame" onload="init();" > </iframe><input type="hidden" id="hidden1" name=text value="<?echo $this->text;?>">
</form>

when you click on the image editor is apearing and you can type, paste etc. When you submit form data from editor goes to "hidden1" and "text1" (only for reading) and from "hidden1" goes to database. If i paste into editor long formated text from MSWord and submit - it goes to database, but when i load form for updating this text don't loading in the frame "text1" and err is "Object required". If i refresh the page - all is fine - no err, full frame of text. If text is short - no problem too. I made function to replace '"'.

Sorry for english, if you can, shoud you give me advice what to do to have all fine on firs frame loading - problem is only in IE, Firefox works fine.

by Pete on Wednesday, June 25th 2008 at 04:44 AM

Your the man Sorin

by TobRock on Thursday, June 26th 2008 at 10:46 AM

Great job, really!

Only thing that is annoying.. is that IExplorer "generate" different tags compared to Mozilla..
For example - Mozilla uses the <span> to set the text-style and IExplorer uses the <font> tag.
And IE use the <p> instead of <br>, etc.

Any way to make them use the same tags?

by RedEye on Monday, July 7th 2008 at 01:54 PM

if I type something like www.bbc.co.uk it will automatically get marked as a link and have <a> tags appended to it. This is literally as I type it. Is it some kind of automated thing? If so, is it possible to disable it, or better still can i add code to when it automatically appends <a> tags so it will also set a target property of _blank.

by pol on Thursday, July 10th 2008 at 08:13 AM

Great job,

1.can you help me with function for clearing text format from MS Word. I wrote this function, but i want when i try to paste text copied from MS Word to have popup window or etc. where to paste the text, clear formating, close the window and the clear text to go in the same place where was marcer in the text editor befor clearing.
2. why when i write something ih the text editor, select it i can't "copy" it whith right mouse button content menu - function "copy" is missing ?

by Ganga on Thursday, July 17th 2008 at 04:56 AM

What changes needs to done to open this editor with some default text ?

Thanks,

by claudemar on Thursday, July 17th 2008 at 07:08 AM

show.

by Ganga on Friday, July 18th 2008 at 01:27 AM

I'm facing below issue with this edior.

When I have 3 lines of text in editor,like

Line1
Line2
Line3

it saved in database like
<P>Line1</P>
<P>Line2</P>
<P>Line3</P>

..which is correct. But when I come back to editor page to display this, it gives "Unterminated String Constant" javascript error. How to solve this?. I think it is due to line breaks but if you see, database text even doesn't contain \n or \r to replace with ""..so what's the solution for this?.
Note: If my database entry is single line, like
<P>Line1</P><P>Line2</P><P>Line3</P>
..then everything works fine.

Please help.
Thanks,
Ganga

by Brian on Thursday, July 24th 2008 at 11:31 AM

What is your dB table set up like and how are you inserting or updating the database?

by James on Thursday, July 24th 2008 at 11:37 AM

Hello - I've gotten everything working so far and i've read all the comments here, and i'm surprised this hasn't come up yet. I'm familiar with javascript, but i only learn it on a 'need-toknow' sort basis. In any event i was wondering if there was anyone who had created a support for this RTE yet so that when the user draws a focus (clicks on) the iFrame editor, that it can read what the styles on their cursor position are and highlight those on the toolbar. I've already created all teh code for mouseovers and toggles on bold, italic, underline (for example) but if i toggle it on, and then click on an area that isn't bold, it still is toggled - any way to update the variables taht iv'e set, based on teh cursor position?

by Brian on Thursday, July 24th 2008 at 02:00 PM

here's a cool function i wrote for adding links into your RTE:

function addLink()
{
str1=prompt("Please insert URL ","");
if(str1 != null)
{
kk = textEditor.document.selection.createRange();
tt = textEditor.document.selection.createRange().text ;
if(tt=="") {tt=prompt("Please insert LINK TEXT ",""); }

str = "<a href=' " str1 " ' target='_blank' ><U>" tt "</U></a>";
kk.pasteHTML(str);
textEditor.focus();
}
else{
alert("you didn't insert URL ");
}
}

by Brian on Thursday, July 24th 2008 at 03:07 PM

here's an update of the link insert, supported for firefox now.

function addLink()
{
str1=prompt("Please insert URL ","");
if(str1 != null)
{

//IE Support
if (document.selection

by Brian on Thursday, July 24th 2008 at 03:08 PM

sorry for the truncated crap ^^.

Here's the whole thing:
***************************************************'

function addLink()
{
str1=prompt("Please insert URL ","");
if(str1 != null)
{

//IE Support
if (document.selection

by CESAR on Thursday, September 11th 2008 at 12:45 PM

hi great tutorial but i want to save content in firefox, in IE the instruction work perfect
document.getElementById('cnt').value = this.textEditor.document.getElementById('txt').document.body.innerHTML;
but in firefox doesnt work
can somebody help me

thnaks a lot

by Catalin F on Friday, September 26th 2008 at 06:03 AM

Hi Sorin,

This is a great tutorial. I have tried to modify it a bit so that when I press an image a div apear and I can select different images from it(emoticons). I made the div disapear when I press another link/body from the document, but when I select the iframe the div does not disappear. Can you help me with this?

by jason on Wednesday, October 15th 2008 at 06:21 PM

how do you add images to this RTE?

i've tried for 3 hours with php, html, forms, and javascript and can't seem to figure it out...i have 777 access on the folder: http://herbalchem.bigskywebscapes.com/images

thanks thanks thanks in advance,

- jason

by manish on Monday, November 10th 2008 at 05:12 AM

Hi Sorin,
I really the tutorial you have provided, exactly in need to that how i can "REDO" and "UNDO" the content

by jv on Sunday, November 16th 2008 at 10:03 PM

how do you open files, add images and add a link to the image?

by Arvind Singh Pal on Friday, November 21st 2008 at 04:02 AM

Hi All,
This is a great tutorial. i have one proble same as Sumalatha. i have one html page with button and we have onClick event on button to "window,showModelDialog" which calls one other html that contains framset and 3 frame ,thired frame has src to html that generate editor and iframe. thinks is that now editor is readonly. but if i am using window.open(). then its working fine. i am giving you code-

Main.html-

<html>
<head>
</head>
<body>
<center>
<button onClick="window.showModalDialog('frameadd.html')">Click</button>
</center>
</body>
</html>


Frameadd.html-

<html>
<head>
<frameset rows="20%,20%,60%" >
<frame src="Header1.html" noresize="noresize">
<frame src="Header2.html" noresize="noresize" >
<frame src="Editor.html" noresize="noresize">
</frameset>
</head>
</html>

Edit.html-

<html>
<head>
<title>Rich Text Editor</title>
</head>
<body onLoad="def()"><center>
<div style="width:500px; text-align:left; margin-bottom:10px ">
<input type="button" id="bold" style="height:21px; width:21px; font-weight:bold;" value="B" onClick="fontEdit('bold')" title="bold" />
<input type="button" id="italic" style="height:21px; width:21px; font-style:italic;" value="I" onClick="fontEdit('italic')" title="italic" />
<input type="button" id="underline" style="height:21px; width:21px; text-decoration:underline;" value="U" onClick="fontEdit('underline')" title="underline" /> |
<input type="button" style="height:21px; width:21px;"value="L" onClick="fontEdit('justifyleft')" title="align left" />
<input type="button" style="height:21px; width:21px;"value="C" onClick="fontEdit('justifycenter')" title="center" />
<input type="button" style="height:21px; width:21px;"value="R" onClick="fontEdit('justifyright')" title="align right" /> |
<select id="fonts" onChange="fontEdit('fontname',this[this.selectedIndex].value)">
<option value="Arial">Arial</option>
<option value="Comic Sans MS">Comic Sans MS</option>
<option value="Courier New">Courier New</option>
<option value="Monotype Corsiva">Monotype</option>
<option value="Tahoma">Tahoma</option>
<option value="Times">Times</option>
</select>
<select id="size" onChange="fontEdit('fontsize',this[this.selectedIndex].value)">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<select id="color" onChange="fontEdit('ForeColor',this[this.selectedIndex].value)">
<option value="black">-</option>
<option style="color:red;" value="red">-</option>
<option style="color:blue;" value="blue">-</option>
<option style="color:green;" value="green">-</option>
<option style="color:pink;" value="pink">-</option>
</select> |
<input type="button" style="height:21px; width:21px;"value="1" onClick="fontEdit('insertorderedlist')" title="Numbered List" />
<input type="button" style="height:21px; width:21px;"value="?" onClick="fontEdit('insertunorderedlist')" title="Bullets List" />
<input type="button" style="height:21px; width:21px;"value="?" onClick="fontEdit('outdent')" title="Outdent" />
<input type="button" style="height:21px; width:21px;"value="?" onClick="fontEdit('indent')" title="Indent" />
</div>
<div>
<iframe id="textEditor" style="width:500px; height:170px;" >
</div>
</iframe>

</center>
<script type="text/javascript">
textEditor.document.designMode="on";
textEditor.document.open();
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:13px;}</style></head>');
textEditor.document.close();
function def()
{
document.getElementById("fonts").selectedIndex=0;
document.getElementById("size").selectedIndex=1;
document.getElementById("color").selectedIndex=0;
}
function fontEdit(x,y)
{
textEditor.document.execCommand(x,"",y);
textEditor.focus();
}

</script>
</body>
</html>



Please help me and reply me as soon as possible
Thanks
Arvind




by Arvind Singh Pal on Tuesday, November 25th 2008 at 02:59 AM

Hi,
i got the solution of my problem i was using document.designMode="on";which working for IE<=5.5 and for further version we need use document.body.contentEditable = "True";


function document.onreadystatechange() {

//textEditor.document.designMode="on";
textEditor.document.body.contentEditable = "True";
}

Thanks
Arvind

by Arvind Singh Pal on Tuesday, November 25th 2008 at 02:59 AM

Hi,
i got the solution of my problem i was using document.designMode="on";which working for IE<=5.5 and for further version we need use document.body.contentEditable = "True";


function document.onreadystatechange() {

//textEditor.document.designMode="on";
textEditor.document.body.contentEditable = "True";
}

Thanks
Arvind

by anurag on Wednesday, December 3rd 2008 at 12:23 AM

Hi,

Thanks for such a gr88 tutorial.

One query from my side:
How can i place a color picker image instead of that dropdown box consisting colored hyphens.
Means on click of any color from color picker image my text color should be effected.

Thanks

by manish on Saturday, December 6th 2008 at 12:17 AM

I am facing a problem in IE with this code
content = textEditor.document.body.innerHTML;

I am not able to get the values in IE, but in firefox it is working fine. Please help me

by nagendran on Saturday, December 6th 2008 at 03:14 AM

how to insert some text at cursor position in ur rich text editor

by nagendran on Saturday, December 6th 2008 at 03:15 AM

how to insert some text at cursor position in ur rich text editor

by richa on Saturday, December 6th 2008 at 10:36 AM

Hi

How to handle Key Event in Iframe ? Actually I want to create a RichTextEditor in nepali Language
So I want to Know that How can I Handle key Event (backspace , right arrow , left arrow , delete , and other keys ). I want Create RTF like (quillpad ) for nepali Language .

by richa on Saturday, December 6th 2008 at 10:37 AM

Hi

How to handle Key Event in Iframe ? Actually I want to create a RichTextEditor in nepali Language
So I want to Know that How can I Handle key Event (backspace , right arrow , left arrow , delete , and other keys ). I want Create RTF like (quillpad ) for nepali Language .

by manish on Tuesday, December 9th 2008 at 12:35 AM

Hi

I need to know how i remove html tags while paste OR uisng ctrl v in the editor

by manish on Tuesday, December 9th 2008 at 05:55 AM

Hi,
The link i insert is inserted at the end, i need it to be inserted where my cursor is
I am using
function showLinkEditor(){
e = document.getElementById('linkInsert');
if(e.style.display=="none") e.style.display = "block";
else e.style.display = "none";
}

function insertLink(){
content = textEditor.document.body.innerHTML;
linkText = document.getElementById('l1').value;
linkUrl = document.getElementById('l2').value;
protocol = document.getElementById('prot').value;
lnk = "<a href='" protocol linkUrl "'>" linkText "</a>

by manish on Thursday, December 18th 2008 at 11:22 PM

Hi, i need a help regarding few things

1) how can i show google map inside editor above
2) how can i show youtube vide inside editor above

by manish on Tuesday, December 23rd 2008 at 07:08 AM

Hi,

Please help me to put the element at the cursor position, wright now it is added at the end. This is the code i am using
frames['textEditor'].document.body.innerHTML = content lnk;
document.getElementById('l1').value="";
document.getElementById('l2').value="";
document.getElementById('linkInsert').style.display="none";
content = frames['textEditor'].document.body.innerHTML;
content = content.replace(/<br><a/,"<a");
frames['textEditor'].document.body.innerHTML=content " ";

by manish on Monday, January 19th 2009 at 04:09 AM

Hi, i need to know how can i call a JavaScript function when my cursor is inside the iframe

by Bryan Walesby on Monday, January 19th 2009 at 06:29 AM

Hello there i am using this code to send over to a database and i have it working in both firefox and ie but i am using a mac and would like it to work correctly in Safari. If anyone knows how i can change my code to get this to work in all 3 then I thank you,

Here is my code,

<html>
<head>
<script language="javascript">

function setHidden()
{
var frameContent=textEditor.document.body.innerHTML;
document.getElementById('cnt').value=frameContent;
}

</script>
</head>
<body onLoad="def()"><center>
<div style="width:500px; text-align:left; margin-bottom:10px ">
<input type="button" id="bold" style="height:21px; width:21px; font-weight:bold;" value="B" onClick="fontEdit('bold')" />
<input type="button" id="italic" style="height:21px; width:21px; font-style:italic;" value="I" onClick="fontEdit('italic')" />
<input type="button" id="underline" style="height:21px; width:21px; text-decoration:underline;" value="U" onClick="fontEdit('underline')" /> |
<input type="button" style="height:21px; width:21px;"value="L" onClick="fontEdit('justifyleft')" title="align left" />
<input type="button" style="height:21px; width:21px;"value="C" onClick="fontEdit('justifycenter')" title="center" />
<input type="button" style="height:21px; width:21px;"value="R" onClick="fontEdit('justifyright')" title="align right" /> |
<select id="fonts" onChange="fontEdit('fontname',this[this.selectedIndex].value)">
<option value="Arial">Arial</option>
<option value="Comic Sans MS">Comic Sans MS</option>
<option value="Courier New">Courier New</option>
<option value="Monotype Corsiva">Monotype</option>
<option value="Tahoma">Tahoma</option>
<option value="Times">Times</option>
</select>
<select id="size" onChange="fontEdit('fontsize',this[this.selectedIndex].value)">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<select id="color" onChange="fontEdit('ForeColor',this[this.selectedIndex].value)">
<option value="black">-</option>
<option style="color:red;" value="red">-</option>
<option style="color:blue;" value="blue">-</option>
<option style="color:green;" value="green">-</option>
<option style="color:pink;" value="pink">-</option>
</select> |
<input type="button" style="height:21px; width:21px;"value="1" onClick="fontEdit('insertorderedlist')" title="Numbered List" />
<input type="button" style="height:21px; width:21px;"value="●" onClick="fontEdit('insertunorderedlist')" title="Bullets List" />
<input type="button" style="height:21px; width:21px;"value="←" onClick="fontEdit('outdent')" title="Outdent" />
<input type="button" style="height:21px; width:21px;"value="→" onClick="fontEdit('indent')" title="Indent" />
</div>
<form action="post.php" method="post" onsubmit="setHidden()">
<input type="hidden" name="cnt" id="cnt" />
<input type="submit" value="submit" />
</form>
</center>
<script type="text/javascript">
<!--
function def()
{
var testframe = document.createElement("iframe");
testframe.name = testframe.id = "textEditor";


if (testframe.addEventListener){
testframe.addEventListener("load",function(e){this.contentWindow.document.designMode = "on";}, false);
} else if (testframe.attachEvent){
testframe.attachEvent("load", function(e){this.contentWindow.document.designMode = "on";});
}

document.body.appendChild(testframe);

textEditor.document.designMode="on";
textEditor.document.open();
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:13px; }</style> </head>');
textEditor.document.close();
textEditor.focus();



}
function fontEdit(x,y)
{
textEditor.document.execCommand(x,"",y);
textEditor.focus();
}
-->
</script>
</body>
</html>

by ayush on Wednesday, January 28th 2009 at 03:36 AM

Good

by Nazmul on Monday, February 23rd 2009 at 12:47 AM

Hi this is a great tutorial. It helped me a lot. But I'm facing the same problem as Ganga. So i'm just copying his message.

When I have 3 lines of text in editor,like

Line1
Line2
Line3

it saved in database like
<P>Line1</P>
<P>Line2</P>
<P>Line3</P>

..which is correct. But when I come back to editor page to display this, it gives "Unterminated String Constant" javascript error. How to solve this?. I think it is due to line breaks but if you see, database text even doesn't contain \n or \r to replace with ""..so what's the solution for this?.
Note: If my database entry is single line, like
<P>Line1</P><P>Line2</P><P>Line3</P>
..then everything works fine.

Please help.
Thanks,
Nazmul

by Odd One Out on Monday, February 23rd 2009 at 06:34 AM

Amazing job! You've been of great help. Thanks!

by Ganga on Monday, March 2nd 2009 at 03:01 AM

Hi Nazmul,
I do not know if it is a perfect solution but resolved the above problem by replacing chars 13 or 10 with " ". Code given below. So do this parsing before you render the content to page. I hope it helps you.

StringBuffer contentBuffer = new StringBuffer();
for(int i = 0; i < content.length(); i ){
if((int)content.charAt(i) == 13 || (int)content.charAt(i) == 10){
contentBuffer.append(" ");
}
else
contentBuffer.append(content.charAt(i));
}

by Nazmul on Monday, March 2nd 2009 at 05:27 AM

Hey Ganga,
Thanks for your reply. Thanks a lot. I did came up with a solution of the problem but forgot to inform it.

Here is the code, it works fine. Try this. I'll try your one as well.

function def(iframeID,appendCell)
{
var testframe = document.createElement("iframe");
testframe.name = testframe.id = iframeID;

testframe.frameBorder = "10";
testframe.style.border = "thin solid #FF0000";

if (testframe.addEventListener)
testframe.addEventListener("load",function(e){this.contentWindow.document.designMode = "on";}, false);
else if (testframe.attachEvent)
testframe.attachEvent("load", function(e){this.contentWindow.document.designMode = "on";});

document.getElementById(appendCell).appendChild(testframe);

document.getElementById(iframeID).contentWindow.document.designMode="on";
document.getElementById(iframeID).contentWindow.document.open();
document.getElementById(iframeID).contentWindow.document.write('<head> <style type="text/css"> body{ font-family:arial; font-size:13px; color:black; white-space:pre; } p{ margin:0px; } pre{margin:0px;} </style> </head>');
document.getElementById(iframeID).contentWindow.document.close();
document.getElementById(iframeID).contentWindow.focus();
document.getElementById(iframeID).contentWindow.document.body.innerHTML="<PRE></PRE>";
}

by Brian on Wednesday, March 11th 2009 at 08:42 AM

Hey everyone - we've done some cool things with the text-editor, so time to share!

1. Adding a link @ cursor position
***********************************

Adding a link is broken up into two fuctions - the first fuction creates a range selection so if you've highlighted text, then this will appear. You will need to make a pop-up div or form that this fuction can fill.

The second fuction is addLink - this fuction will actually place the link into the textarea. NOTE: it is very important then when creating your iframe you add an src element - eg.

var testframe = document.createElement("iframe");
testframe.src = "0.html";

This is so we have a base path to access our images from.

***************************************

var kk, tt, selection, range, check;
function getLinkinfo() {

if (document.selection

by Brian on Wednesday, March 11th 2009 at 08:46 AM

SORRY _new attetmpt

Hey everyone - we've done some cool things with the text-editor, so time to share!

1. Adding a link @ cursor position
***********************************

Adding a link is broken up into two fuctions - the first fuction creates a range selection so if you've highlighted text, then this will appear. You will need to make a pop-up div or form that this fuction can fill.

The second fuction is addLink - this fuction will actually place the link into the textarea. NOTE: it is very important then when creating your iframe you add an src element - eg.

var testframe = document.createElement("iframe");
testframe.src = "0.html";

This is so we have a base path to access our images from.

***************************************

var kk, tt, selection, range, check;
function getLinkinfo() {

if (document.selection

by Brian on Wednesday, March 11th 2009 at 08:48 AM

Hey everyone - we've done some cool things with the text-editor, so time to share!

1. Adding a link @ cursor position
***********************************

Adding a link is broken up into two fuctions - the first fuction creates a range selection so if you've highlighted text, then this will appear. You will need to make a pop-up div or form that this fuction can fill.

The second fuction is addLink - this fuction will actually place the link into the textarea. NOTE: it is very important then when creating your iframe you add an src element - eg.

var testframe = document.createElement("iframe");
testframe.src = "0.html";

This is so we have a base path to access our images from.

***************************************

var kk, tt, selection, range, check;
function getLinkinfo() {

if (document.selection

by Brian on Wednesday, March 11th 2009 at 08:49 AM

Why the hell is it truncating?

by Brian on Wednesday, March 11th 2009 at 08:49 AM

<code>
Hey everyone - we've done some cool things with the text-editor, so time to share!

1. Adding a link @ cursor position
***********************************

Adding a link is broken up into two fuctions - the first fuction creates a range selection so if you've highlighted text, then this will appear. You will need to make a pop-up div or form that this fuction can fill.

The second fuction is addLink - this fuction will actually place the link into the textarea. NOTE: it is very important then when creating your iframe you add an src element - eg.

var testframe = document.createElement("iframe");
testframe.src = "0.html";

This is so we have a base path to access our images from.

***************************************

var kk, tt, selection, range, check;
function getLinkinfo() {

if (document.selection

by Brian on Wednesday, March 11th 2009 at 08:52 AM

Hey everyone - we've done some cool things with the text-editor, so time to share!

'DOUBLE_AMPERSAND' means exactly what it says. Don't keep the quotes.

1. Adding a link @ cursor position
***********************************

Adding a link is broken up into two fuctions - the first fuction creates a range selection so if you've highlighted text, then this will appear. You will need to make a pop-up div or form that this fuction can fill.

The second fuction is addLink - this fuction will actually place the link into the textarea. NOTE: it is very important then when creating your iframe you add an src element - eg.

var testframe = document.createElement("iframe");
testframe.src = "0.html";

This is so we have a base path to access our images from.

***************************************

var kk, tt, selection, range, check;
function getLinkinfo() {

if (document.selection 'DOUBLE_AMPERSAND' document.selection.createRange) {
kk = textEditor.document.selection.createRange();
tt = textEditor.document.selection.createRange().text;
document.forms.myLink.text.value = tt;

} else if (window.getSelection) {
selection = textEditor.window.getSelection();
range = textEditor.window.getSelection().getRangeAt(0);
document.forms.myLink.text.value = range;
}
}

function addLink() {

str1 = document.forms.myLink.url.value;
tt = document.forms.myLink.text.value;

if(str1 != null) {

if (document.selection 'DOUBLE_AMPERSAND' document.selection.createRange) {
str = "<a href=' " str1 " ' target='_blank' ><U>" tt "</U></a>";
kk.pasteHTML(str);

} else if (window.getSelection) {

selection = textEditor.window.getSelection();
range = textEditor.window.getSelection().getRangeAt(0);
repl=textEditor.document.createTextNode(tt);
newP = textEditor.document.createElement("a");
newP.href=str1;

range.deleteContents(); newP.appendChild(repl); range.insertNode(newP);
}

} else {
alert("you didn't insert URL ");
}

}

*****************************************

2. Applying a style from a stylesheet

This fuction is almost identical to our link function. Highlight some text, select a style - bam! We will pass a variable "tag" from a select box or other form element that will be your styled tag (e.g. h2) - if you want you can do it all using spans - just edit the output code below and send the class then.

******************************************

function applyStyle(tag) {

if (document.selection 'DOUBLE_AMPERSAND' document.selection.createRange) {
kk = textEditor.document.selection.createRange();
tt = textEditor.document.selection.createRange().text;


} else if (window.getSelection) {
selection = textEditor.window.getSelection();
range = textEditor.window.getSelection().getRangeAt(0);
tt = range;

}


if(tt != null) {


if (document.selection 'DOUBLE_AMPERSAND' document.selection.createRange) {
tt = tt.replace(/

by Brian on Wednesday, March 11th 2009 at 10:19 AM

Sorry for all the truncated posts, guys. You can access the full script post here:

http://www.bump21.com/rte.txt

by test on Monday, March 16th 2009 at 06:28 AM

#
صور
#
فضائح
#
اصحاب
# تلفزيون
# راديو
#
جوجل عربي
#
لوحة المفاتيح القران

by test on Monday, March 16th 2009 at 06:28 AM

#
صور
#
فضائح
#
اصحاب
# تلفزيون
# راديو
#
جوجل عربي
#
لوحة المفاتيح القران

by Ganga on Friday, March 20th 2009 at 02:06 AM

Hi,
We have below issue.
When user copies Microsoft word content into our text editor, it brings all the format becuase of which we are facing some issues at later stages(like when comparing the contents). Note, during copy action we don't have any issues.

So, how to filter the content which comes from Microsoft word ?. Pls share your thoughts.

by Pete on Monday, April 27th 2009 at 02:51 AM

Hey Brian

Just started to have a play with a delete function, still got a way to go but heres a start.

<script>

var htmlString = "text{word}this is text{/ward}more";
var htmlNew = "";
var htmlDelete = "";

//starts counting at 1
var htmlLength = htmlString.length;

//var htmlMatch = htmlString.match('<');
//alert(htmlMatch " ");

//this will strart counting at 0
//var htmlFind = htmlString.indexOf('<');

for (var i=0;i<=htmlLength;i ){

var htmlSub = htmlString.substr(i,1);



var htmlLocation = htmlLength - i;

//############################# Delete Area #########################
if(htmlSub == "{"){

htmlNew = htmlSub;

for (var j=i;j<=htmlLocation;j ){

var htmlDelSub = htmlString.substr(j,1);

if(htmlDelSub == "}"){
htmlDelete = htmlDelSub;
alert(htmlDelete);

break;
}
else{

htmlDelete = htmlDelSub;
}


}
//############################# Delete Area #########################
}
else{

htmlNew = htmlSub;
}
//document.write(htmlSub ' ');
htmlFinal = htmlNew.replace(htmlDelete,' DELETED ');

}
//alert(htmlLength);
//alert(i);

document.write(htmlFinal);

//document.write("<br />");

//document.write(htmlDelete);
//alert(htmlLength);

</script>

by Pete on Monday, April 27th 2009 at 02:52 AM

Hey Brian

Just started to have a play with a delete function, still got a way to go but heres a start.

<script>

var htmlString = "text{word}this is text{/ward}more";
var htmlNew = "";
var htmlDelete = "";

//starts counting at 1
var htmlLength = htmlString.length;

//var htmlMatch = htmlString.match('<');
//alert(htmlMatch " ");

//this will strart counting at 0
//var htmlFind = htmlString.indexOf('<');

for (var i=0;i<=htmlLength;i ){

var htmlSub = htmlString.substr(i,1);



var htmlLocation = htmlLength - i;

//############################# Delete Area #########################
if(htmlSub == "{"){

htmlNew = htmlSub;

for (var j=i;j<=htmlLocation;j ){

var htmlDelSub = htmlString.substr(j,1);

if(htmlDelSub == "}"){
htmlDelete = htmlDelSub;
alert(htmlDelete);

break;
}
else{

htmlDelete = htmlDelSub;
}


}
//############################# Delete Area #########################
}
else{

htmlNew = htmlSub;
}
//document.write(htmlSub ' ');
htmlFinal = htmlNew.replace(htmlDelete,' DELETED ');

}
//alert(htmlLength);
//alert(i);

document.write(htmlFinal);

//document.write("<br />");

//document.write(htmlDelete);
//alert(htmlLength);

</script>

by Pete on Monday, April 27th 2009 at 02:52 AM

Hey Brian

Just started to have a play with a delete function, still got a way to go but heres a start.

<script>

var htmlString = "text{word}this is text{/ward}more";
var htmlNew = "";
var htmlDelete = "";

//starts counting at 1
var htmlLength = htmlString.length;

//var htmlMatch = htmlString.match('<');
//alert(htmlMatch " ");

//this will strart counting at 0
//var htmlFind = htmlString.indexOf('<');

for (var i=0;i<=htmlLength;i ){

var htmlSub = htmlString.substr(i,1);



var htmlLocation = htmlLength - i;

//############################# Delete Area #########################
if(htmlSub == "{"){

htmlNew = htmlSub;

for (var j=i;j<=htmlLocation;j ){

var htmlDelSub = htmlString.substr(j,1);

if(htmlDelSub == "}"){
htmlDelete = htmlDelSub;
alert(htmlDelete);

break;
}
else{

htmlDelete = htmlDelSub;
}


}
//############################# Delete Area #########################
}
else{

htmlNew = htmlSub;
}
//document.write(htmlSub ' ');
htmlFinal = htmlNew.replace(htmlDelete,' DELETED ');

}
//alert(htmlLength);
//alert(i);

document.write(htmlFinal);

//document.write("<br />");

//document.write(htmlDelete);
//alert(htmlLength);

</script>

by Brian on Friday, May 22nd 2009 at 09:01 AM

Pete - I like what you're working on there - it would be nice to have a button that would invoke a removeAllStyles(); function like you're writing there. Just revert it all back to plain text.

The next problem, is, as I'm sure all of you have realized, trying to get good code out of the editor, (e.g. - avoiding things like this):

<h1><p>Test Text<br></p><h2><p><br></p><br></h2></h1>

This is just an example of some stuff I got after changing the styles on the same text a few times...

I would guess that the solution would have to do something like this:

IF i have the code:
<h1>This is a test heading I want this to be a paragraph This is a test Heading</h1>

If i apply a paragraph style to the text "I want this to be a paragraph, then I will get code like this:
<h1>This is a test heading <p>I want this to be a paragraph</p> This is a test Heading</h1>

When we would want to have this:
<h1>This is a test heading</h1><p>I want this to be a paragraph</p><h1>This is a test Heading</h1>

so the different possibilites or catches for the function would be:

1) the text selection is within an already existing element (Close Element, alter selection, reopen element).

2) the text selection includes part of an element (IF a block element {h1,h2,p} begin applying stle after end of element, IF inline, close element open new tag, end new tag, remove original closing tag from principal element.

Does this make sense? Any ideas - I think pete is on the right track with the DELETE script he's writing - but we'd have to alter it to do a little more.

by Kent on Friday, May 22nd 2009 at 10:02 AM

Thank you . You saved me

by Kent on Friday, May 22nd 2009 at 10:02 AM

Thank you . You saved me

by Kent on Saturday, May 23rd 2009 at 10:55 AM

Hey I'm stuck!

I am trying to modify the text editor so that i be able to use the editor to edit already saved data . Like retrieving a draft and continue working on it then saving .

Could you kindly show clearly how i can do that ?

Thanks,

Kent

by Brian on Wednesday, May 27th 2009 at 08:29 AM

Kent,

To do this, edit this section of the code:

textEditor.document.designMode="on";
textEditor.document.open();
textEditor.document.write('<head><style type="text/css">body{ font-family:arial; font-size:13px; }</style> </head>');
textEditor.document.close();

and change it so that you can set an .src attribute to id like so:

var editor;
editor = document.createElement("iframe");
editor.src = "includes/blank.html"
editor.width = "100%";
editor.height = "350px";
editor.style.backgroundColor = "#ffffff";
editor.frameborder = "0";
editor.style.border = "1px solid #000000";
editor.name = editor.id = "textEditor";

if (editor.addEventListener){
editor.addEventListener("load",function(e){this.contentWindow.document.designMode = "on";}, false); //Attach Design Mode, Firefox
} else if (editor.attachEvent){
editor.attachEvent("load", function(e){this.contentWindow.document.designMode = "on";});
}
document.getElementById('editorDIV').appendChild(editor);
textEditor.document.designMode="on";
textEditor.focus();
}

In this example, I have set the src to 'includes/blank.html' - if you change this to a php / cfm / asp / etc script that will grab your database info and display it, you'll be golden.

You'll also notice that the editor is dynamically created to fill an empty <div> element called editorDIV.

To save your info and send your editor content as a form element, create a function like so:

function setHidden(); {
var content = textEditor.document.body.innerHTML;
document.getElementById('myHiddenFormField').value = content;
}

where 'myHiddenFormField' is exactly what it seems to be - a hidden form field with that ID. Then just call the setHidden() function on your form submit and you're golden.

by Kent on Wednesday, May 27th 2009 at 01:45 PM

Hey Brian
Thanks alot for your effort .
How i did it, i hid my php text in a hidden form variable then grabbed it via javascript and

displayed on the iframe using textEditor.document.write() .

I works fine .

by Tom on Friday, May 29th 2009 at 04:46 PM

I'm using a variation of the addLink() function that Brian submitted to add images to my editor. It works fine, except there must be a selection made first within the iFrame to add the image. If I try to add an image without making a selection, the image is added above the iFrame. Does anyone know a way to add an element to the iFrame without first highlighting a piece of text?

Here is my code:

function addImg() {

str1 = prompt("Please insert a filename ","");
if(str1 != null) {
img = textEditor.document.selection.createRange();
str = "<img src='Images/" str1 "' />";
img.pasteHTML(str);

textEditor.focus();
}
}

Thanks,

Tom

by md_ on Friday, June 5th 2009 at 07:43 PM

http://javascript.internet.com/snippets/remove-html-tags.html


Comment Comment on this tutorial
Name: Email:
Message:
Comment Related Tutorials
There are no related tutorials.

Comment Related Source Code
There is no related source code.

Jobs JavaScript Job Search
My skills include:
Enter a City:

Select a State:


Advanced Search >>
Latest Tech Bargains

Advertisement

Free Magazine Subscriptions

Today's Pictures

Today's Video

Other Resources

Latest Download

Latest Icons