Read, With the Name of Your Lord Who Created

Cursor Positions, Selected Text, and A Simple HTML Editor

Posted by triaslama on June 6, 2008

It would be nice if we have a HTML text editor that doing a simple task of HTML editor for us. It works just like HTML view of WordPress admin page when we write a post. We select the text press specific button and then the selected text will be enclosed with appropriate format. I Test the code in Mozilla Firefox and Internet Explorer, so in both browsers this code should works fine. Here the screenshoots:

Screenshoots page.

We need to prepare the prerequisites.

As prerequisites, at least we need two things. First, we need to know how to define the cursor position inside a <textarea> element, second we need to know how to retrieve a selected text inside a <textarea> element. So, for the first step, I will talk about the both things shortly.

Every browser brings the different behaviour. The browser quirk will make our code a little bit longer because we need to specify different code for different browser. Defining cursor position (current position) is trivial in Mozilla Firefox, but we need a little trick in Internet Explorer. If we want to retrieve selected text in a <textarea> element, both (Forefox and IE) has their own way too.

Defining Cursor Position Inside a <textarea> Element
In Firefox we just need the following code to determine the current position of cursor in a <textarea> element:

var currentPosition = txtArea.selectionStart;

txtArea is a <textarea> element.
Internet Explorer (I use IE 6) doesn’t have selectionStart and selectionEnd property, so we need a little more effort to determine start and end position of the cursor (this is a tricky way).

var range = document.selection.createRange();
var drange = range.duplicate();
drange.moveToElementText(txtArea);
drange.setEndPoint("EndToEnd", range);

var currentPosition = drange.text.length - range.text.length;
var endPosition = drange.text.length - currentPosition;

Defining Selected Text Inside a <textarea> Element
In Firefox we need more effort to retrieve selected text inside a <textarea> element, we get selected text with the help of selectionStart and selectionEnd property. Then split <textarea> value using selectionStart and selectionEnd values.

var txtArea = document.getElementById("txtArea");
var text = txtArea.value;
var selectedText = text.substring(txtArea.selectionStart,txtArea.selectionEnd);

In Internet Explorer (IE) we need the following code to get the selected text:

var selectedText = document.selection.createRange().text;

Simple HTML Text Editor
Now we will combine these two things, and get ready for bigger challenge! We will create a simple HTML text editor.
It just works as is, we type something in textarea, select the text and press one of button above the textarea to insert appropriate tag. This simple HTML text editor also work fine with new line and paragraph. So if you place a new line in textarea (by press ‘Enter’ button) it would be displayed as new line too. The same thing happen for paragraph.

Here a screenshoot of my HTML text editor:

A simple HTML text editor.

Now, lets take a look at the code. I use HTML file for presentation and Javascript code for hadling what should happen under the hood.

    <html>
    <head>
    <title>HTML Editor</title>
    <script lang=”javascript” type=”text/javascript” src=”htmleditor.js”>
    </script>
    </head>
    <body>
    <input type=”button” id=”btnBold” value=”B” onclick=”insertsBoldTag()” />
    <input type=”button” id=”btnItalic” value=”I” onclick=”insertsItalicTag()” />
    <input type=”button” id=”btnUnderline” value=”U” onclick=”insertsUnderlineTag()” />
    <input type=”button” id=”btnDelete” value=”Del” onclick=”insertsDeleteTag()” />
    <br/>
    <textarea id=”area” cols=”35″ rows=”12″>
    </textarea>
    <p>
    <input type=”button” id=”btn” value=”Publish” onclick=”publish()” />
    <p>
    <div id=”showDiv”>
    </div>
    </body>
    </html>

 

I think the HTML page is quite simple, it draws four buttons (bold, italic, underline, and del button respectively), a textarea, and a publish button.

All processing handled by the following Javascript file:

var area;
var showDiv;
var formattedStr = "";
startPosition = 0;
var endPosition = 0;

window.onload = function()
{
	area = document.getElementById("area");
	showDiv = document.getElementById("showDiv");
};

function publish()
{
	formattedStr = "<pre>"+document.getElementById("area").value+"</pre>";
	showDiv.innerHTML = formattedStr;
}

function insertsBoldTag()
{
	findPositions();

	var text = area.value;
	if (startPosition!=endPosition) {
		var sbStr = text.substring(startPosition,endPosition);
		sbStr = "<b>"+sbStr+"</b>";

		fillsFormattedString(text,sbStr);
	}
}

function insertsItalicTag()
{
	findPositions();

	var text = area.value;
	if (startPosition!=endPosition) {
		var sbStr = text.substring(startPosition,endPosition);
		sbStr = "<i>"+sbStr+"</i>";

		fillsFormattedString(text,sbStr);
	}
}

function insertsUnderlineTag()
{
	findPositions();

	var text = area.value;
	if (startPosition!=endPosition) {
		var sbStr = text.substring(startPosition,endPosition);
		sbStr = "<u>"+sbStr+"</u>";

		fillsFormattedString(text,sbStr);
	}
}

function insertsDeleteTag()
{
	findPositions();

	var text = area.value;
	if (startPosition!=endPosition) {
		var sbStr = text.substring(startPosition,endPosition);
		sbStr = "<del>"+sbStr+"</del>";

		fillsFormattedString(text,sbStr);
	}
}

function findPositions()
{
	var text = area.value;

	if (document.selection) {
		// Internet Explorer
		var range = document.selection.createRange();
		var dpl = range.duplicate();
		if (range.text.length > 0) {
			dpl.moveToElementText(area);
			dpl.setEndPoint("EndToEnd", range);
			startPosition = dpl.text.length-range.text.length;
			endPosition = startPosition + range.text.length;
		}
	}
	else {
		// Mozilla Firefox
		startPosition = area.selectionStart;
		endPosition = area.selectionEnd;
	}
}

function fillsFormattedString(text, selectedText)
{
	// split textarea value into three pieces: before startPosition, 
        // startPosition until endPosition, and after endPosition
	var str1 = text.substring(0,startPosition);
	var str2 = text.substring(startPosition,endPosition);
	var str3 = text.substring(endPosition,text.length);

	// replace str2 with formatted substring (selectedText)
	str2 = selectedText;
	// form the new string
	formattedStr = str1+str2+str3;
	area.value = formattedStr;
}

 

To apply HTML text editor, we need to know how to get cursor positions and how to retrieve selected text.
Lets take a look at Javascript code. In window.onload (happen when our page is load) I retrieve <textarea> and <div> element

window.onload = function()
{
     area = document.getElementById("area");
     showDiv = document.getElementById("showDiv");
};

When we click bold button (‘B‘) the cursor positions (startPosition and endPosition) will be filled with appropriate value depend on what we have already selected. Split the string value using startPosition and endPosition, then enclose the string with <b> tag.


findPositions();

var text = area.value;
if (startPosition!=endPosition) {
	var sbStr = text.substring(startPosition,endPosition);
	sbStr = "<b>"+sbStr+"</b>";

The next step, I split the string into three pieces: first character to startPosition, between startPosition and endPosition, endPosition until last character.

var str1 = text.substring(0,startPosition);
var str2 = text.substring(startPosition,endPosition);
var str3 = text.substring(endPosition,text.length);

Then I replace the second substring (str2) with selectedText (text that we have already inserted with the appropriate tag). So the result is new string with html tag inside it, and gives it back to textarea.

// replace str2 with formatted substring (selectedText)
str2 = selectedText;
// form the new string
formattedStr = str1+str2+str3;
area.value = formattedStr;

The same thing also valid for italic, underline, and del button but we insert <i>, <u>, <del>, for italic, underline, and del button respectively.

When we click ‘Publish’ button, we retrieve value of textarea and pass it as innerHTML of showDiv element.

formattedStr = "<pre>"+document.getElementById("area").value+"</pre>";
showDiv.innerHTML = formattedStr;

17 Responses to “Cursor Positions, Selected Text, and A Simple HTML Editor”

  1. bethseda said

    eqeqweqwewqeqwewqewew

  2. user9999 said

    nicely done. You could also use an iframe with designMode=”on” and edit html directly

  3. triaslama said

    @ Bethseda & User9999
    Thanks for your comments.

    @ User9999
    Thanks for your tips.

  4. Gilamonster said

    Wow! you rock Triaslama! This is exactly what I was looking for as I’m trying to design my own blog system. I’m very keen about this cursor positioning thing. I think I’ll try to expand it, so I might also be able to use it to add links and other (x)html codes.

    I’ll add you to my favorites … keep up the good work, You can count me in as your new fan🙂

  5. Ozgur said

    Article is so helpful for using textarea with html codes.
    Especially, cursor position is so important for selected text for replacing with tags.

    Thanks for your writing.

  6. Tim said

    Very useful article, thank you!🙂

  7. […] – range.text.length; var endPosition = drange.text.length – currentPosition; Zu finden unter: Cursor Positions, Selected Text, and A Simple HTML Editor Read, With the Name of Your Lord Who Creat… Gru […]

  8. David Whitten said

    I’mactually doing one right now using JQuery. Have you ever heard of document.selection.CreateRange()? There are a slew of commands you can use like pasteHTML, htmlText, text. Most of the javascript above would go away. Then you could use the document.execCommand(“bold”, false, null) to set your values. The “” would be the actually range you get like:

    var range = frame.document.selection.createRange();
    if (range.text != “”)
    {
    range.execCommand(“CreateLink”);
    range.execCommand(‘FontSize’, false, 20);
    range.execCommand(“ForeColor”, false, “#FF0033”);
    }

    So whatever you hightlight, link will be created, and some formatting.

    Just a thought,

  9. IP said

    Thank you very much for this code. This is just what I was looking for! Great! Thanx a lot!

  10. Stephan said

    can be usefull for editing xml too

  11. Xp_ks said

    Thank you very much for this code. This is just what I was looking for! Great! Thanx a lot!

  12. Joglekar said

    Thank you very much. This article is very nice and useful.
    I have a question here? Is there a way to replace the tags with css styles and formatting of textarea can pass upto DB for later use?

    Regards
    Joglekar

  13. get firefox…

    […]Cursor Positions, Selected Text, and A Simple HTML Editor « Read, With the Name of Your Lord Who Created[…]…

  14. Teen Vehicle GPS…

    […]Cursor Positions, Selected Text, and A Simple HTML Editor « Read, With the Name of Your Lord Who Created[…]…

  15. Hi there would you mind letting me know which webhost you’re working with? I’ve loaded your blog in 3 completely different internet browsers and I must say this blog loads a lot quicker then most.
    Can you suggest a good web hosting provider at a
    reasonable price? Cheers, I appreciate it!

  16. It is appropriate time to make sme plans forr the long run annd it’s time to be happy.

    I’ve learn this post and if I could I desire too recommend you few fascinating things or suggestions.
    Maybe you can write next articles eferring to this article.
    I wish to read even more things approximately it!

  17. Everything is very open with a very clear
    clarification of the issues. It was really informative. Your website is useful.
    Thank you for sharing!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: