AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=1092&pId=-1
Rich Text Editor- Part I
page
by Haissam Abdul Malak
Feedback
Average Rating: 
Views (Total / Last 10 Days): 54286/ 67

Introduction

My friend was working on a project (building a blog website) and faced problems concerning which text editor to use. After researching all the free editors that he found were not as he expected so I took the responsibility to create a rich text editor user control and I thought it would be a good idea to share this with you in order to accomplish our goal which consists of knowledge sharing.

The editor contains the following elements:

1.    A toolbar containing all the functionalities (listed below)

·         Alignment (left, center, right)

·          Font formatting (bold, underline, italic, font size, font name, font color)

·         Word counts, remove formatting, insert lines, undo, redo, and insert emoticons

2.    An HTML page integrated inside an Iframe and a text area element integrated inside another iframe. Note that the two iframes are placed above each others.

3.    Two icons for displaying "View as HTML" and "Design Mode," a textbox holding the value of the word count, and finally two hidden textboxes  to preserve the data entered by the user.

To keep up with this demonstration, you should have knowledge in javascript language and in HTML.

Add HTML code to the user control

In this section we will create a user control (hamHtmlEditor.ascx) and create the necessary HTML elements. Note that the user control does not contain <head>, <body> or <form> tags.

We will create 3 tables for displaying the icons for the toolbar plus 3 dropdown lists; 2 are placed at the top of the control and 1 is placed at the bottom of the control.  Three common events are being used for each icon, onmouseover, onmouseup, onclick and they are handled using javascript which are all embedded inside a javascript file. Separating the javascript code from the HTML code will let your code be well understood and debugged. Then we will create 3 div layers, the first layer contains the already created HTML page (TextArea.htm). I have used an HTML page because if the user has entered a url it will automatically render its HTML code the same for the sake of using icons inside your text. The second will contain a text area element which is used for displaying the HTML code to the user during runtime (hidden by default), and the third will contain the emoticons which will be shown when the user click on the insert emoticons image (hidden by default).

To enable the user to enter data at runtime, you have to add set the page "designMode" property on to where the control is being used.

Listing 1

 
(onload="document.frames['HamHtmlEditor1_content'].document.designMode='on'")

 Please download the project to see exactly how we created all the HTML tags.

Figure1

 

 

Javascript File

In this section we will write functions for handling the events raised by the user. First, we will define global variables. Each of these variables has its own functionality, but most are created to store a value indicating if an icon was previously clicked or no by default its value is equal to No. Only one variable has another purpose, this variable is called (sourceText) and will be equal to the text entered by the user.

Listing 2

 
var sourceText= '';
var imgStatusBold = 'No';
var imgStatusItalic = 'No';
var imgStatusUnderLine = 'No';
var imgStatusLeft = 'No';
var imgStatusCenter = 'No';
var imgStatusRight = 'No';
var imgStatusRemoveF= 'No';
var imgStatusWCount = 'No';
var imgStatusInsertL = 'No';

Based on the value of the above variables, when the user clicks on an icon, if the specific variable's value is equal to “Yes” it indicates that this icon is not as the equal to the one loaded when the user control has been loaded and then directly we change the icon to its first status and set its variable to “No.” If the value was “No” then we will change the icon and its proper variable to “Yes.”

Three common functions are called onmouseover, onmouseup, and onclick. Onmouseover, a function (ChangeImg()), is used to change the icon when the user places his mouse at a certain icon. This function takes 2 parameters (icon id and the new icon name). Note that the toolbar icons are contained in a folder called "Images" under the root element of the web application.

Listing 3

 

function ChangeImg(id, imgsrc)
{
var imgSrc = "Images/" + imgsrc;
document.getElementById(id).src = imgSrc;
}

Onmouseup function is used to return the icon to its previous state when the mouse leaves a specific icon; it takes 3 parameters (icon id, new icon name, and a variable).

Listing 4

 

function ReturnImg(id, imgsrc, ownVar)
{
if(ownVar == 'No')
{
var imgSrc = "Images/" + imgsrc;
document.getElementById(id).src = imgSrc;
}
}

The third parameter is used to indicate either this icon was selected or not. Its default value is No.

Onclick function is called to perform a specific action. A single javascript method is used for all the actions, plus for each action a specific criteria.

Listing 5

 
document.frames['HamHtmlEditor1_content'].document.execCommand('JustifyLeft',false,null);

The above method is used to align the text entered by the user to the left. ExecCommand is used to execute a command on a document. It consists of predefined functions which are used to manipulate the page layout directly into the browser. Do not use it until the page has finished loading.

Listing 6

 
function MakeBold(boldover, bold)
{
var img = document.getElementById('Bold')       
var imgBold = "Images/" + boldover
var imgNotBold = "Images/" + bold
img.src = imgBold;
                  
if(imgStatusBold == 'Yes')
{
imgStatusBold='No';
img.src = "Images/" + bold;
}
else
{
imgStatusBold= 'Yes'
}
document.frames['HamHtmlEditor1_content'].document.execCommand('bold',false,null);
document.frames['HamHtmlEditor1_content'].focus();                
}

The function above is used to format the text entered by the user as bold. When he clicks on this icon, we should change it to another one. Set the global variable for this action to “Yes” which means that it has been selected. We will use this variable each time the user clicks on it to see if it has been previously selected or no, and then we will make the transformation to the text into bold. It takes 2 parameters, the first is to store the bold-over image location (url) and the second is to store the bold image location (url). The same concept is used to make the text Italic and underlined.

To apply alignments into the text, we use the same as the MakeBold() function, but instead, the 3 alignment functionalities work in a parallel way which means that if a specific alignment is selected all others will be unselected and will retain their original status.

 

For a complete reference about the execCommand command list visit http://www.course.com/downloads/newperspectives/crweb3/documents/dhtml_t02.html.

Now we will create a function that counts how many words the user has entered. A variable is defined with default value equal to 0. Another variable is defined that holds the text entered. We will split the spaces in this variable, add the splitting results to an array and check each element length in the array. If it is equal to zero then it is a space, else add 1 to the specific variable. After this stage we will set the value of the textbox to the count variable.

Listing 7

 
var wordCount = document.frames['HamHtmlEditor1_content'].document.body.innerText;
var count = 0;
countWithSpace = wordCount.replace('\n', '');
countWithoutSpaces = countWithSpace.split(' ');
for(i=0;i<countWithoutSpaces.length;i++)
{
if(countWithoutSpaces[i].length>0)
{
count +=1;
}
window.parent.document.getElementById('HamHtmlEditor1_TxtCount').value = count;
}

When the "Remove Formatting" image is clicked, we call a javascript function which sends "RemoveFormat" to the execCommand to remove all the formats applied to the text. It is very useful if a user wants to remove all the formats that he already applied into the text.

 

Listing 8

 
function RemoveFormating()
{     
document.frames['HamHtmlEditor1_content'].document.execCommand('RemoveFormat');
document.frames['HamHtmlEditor1_content'].focus();
}

"Undo" & "Redo" are done the same as the above javascript function, but they send "undo" or "redo" to the execCommand to undo or redo the user action. It takes 1 parameter which is the execCommand function name.

Listing 9

 
function Formats (style)
{
document.frames['HamHtmlEditor1_content'].document.execCommand(style);
document.frames['HamHtmlEditor1_content'].focus();
}

When the user clicks on "Insert emoticons" icon, we will show the third div layer placed directly after this icon which contains all the emoticons images. When doing this we have to use Javascript.

Listing 10

 

function ShowDiv(images)
{
var div = document.getElementById(images);
if(div.style.display == 'block')
div.style.display = 'none';
else
div.style.display = 'block';
}

Figure2: Shows the editor when the "insert emoticons" is clicked.

 

When the user clicks on any emoticon inside the third div layer, another javascript function is called to insert that image and to place the cursor back to the editor. This method takes 3 parameters. The first parameter is passed to execCommand that inserts the image into the document (insertimage), the second is the image location (url), and the third is the id of the div layer. Note that the emoticons are placed inside a folder called "Emoticons" under the root element of the web application.

Listing 11

 
function insertImages(style,url,images)
{
document.getElementById(images).style.display = 'none'
document.frames['HamHtmlEditor1_content'].focus();
HamHtmlEditor1_content.document.execCommand(style,'',url)
document.frames['HamHtmlEditor1_content'].focus();
}

When the "View as HTML" image is clicked, the second div layer is shown and the first layer is hidden. The "readonly" property of this div layer is set to "true" which means that the user at runtime cannot edit it, then we will get the HTML code and insert it into that div layer.

Listing 12

 

function TransformtoHtml()
{
document.getElementById('HamHtmlEditor1_Div2').style.display = 'block';
document.getElementById('HamHtmlEditor1_Div2').innerText = 
document.frames['HamHtmlEditor1_content'].document.body.innerHTML;
}

When the "Design view" image is clicked, the third div layer (containing the HTML code) is just hidden.

Listing 13

 
function TransformToText()
{
document.getElementById('HamHtmlEditor1_Div2').style.display = 'none';
}

The dropdown lists are used to let the user selects the predefined data entered to manipulate the text.

The first one is used to change the font size; sizes may vary from 1 (10 pt) to 7 (22 pt). We will handle the onclick event by calling a javascript function. This function gets the user selected from the dropdown list and sends it as a third parameter to the execCommand command. The first parameter is the FontSize, in which you are telling this command to execute the FontSize function with its specific size. Note that the font sizes in the dropdown list are predefined in the user control HTML code created earlier.

Listing 14

 

function ChangeFont()
{
var fontSize = document.getElementById('FontDropDownonchange');
document.frames['HamHtmlEditor1_content'].document.execCommand(
'FontSize',0,fontSize.options[fontSize.selectedIndex].text);
document.frames['HamHtmlEditor1_content'].focus();
}

The code below is used to change the font name; the first parameter of the execCommand command takes fontname as first parameter, the second is false or 0, and the third is the user’s selection.

Listing 15

 
function ChangeFontName()
{
var fontName = document.getElementById("FontFamilyName");
document.frames['HamHtmlEditor1_content'].document.execCommand(
'FontName',false, document.frames['HamHtmlEditor1_content'].focus();
}

The third is used to change the font color; the colors are predefined so if you want to add more colors you can modify the HTML code of this dropdown list.

Listing 16

 
function ChangeFontColor()
{
var fontColor = document.getElementById("Color");
document.frames['HamHtmlEditor1_content'].document.execCommand(
'ForeColor',false,fontColor.options[fontColor.selectedIndex].text);
document.frames['HamHtmlEditor1_content'].focus();
}

The final function will assign the text entered by the user to a hidden input HTML element and store its specific HTML code to another hidden HTML element. It is called when the editor loses the focus (onblur) event of the iframe containing the HTML page. In this way, we can use the two properties created as you will see in the next section to get the hidden inputs values from the code behind.

Listing 17

 
function CloneText()
{
document.getElementById('HamHtmlEditor1_ContentTxt').innerText
 = document.frames['HamHtmlEditor1_content'].document.body.innerText;
document.getElementById('HamHtmlEditor1_ContentHtml').value=
 document.frames['HamHtmlEditor1_content'].document.body.outerHTML;
}

After completing this stage, you will have the javascript file ready; all you need to do now is to link it to the page where you want to use the user control by adding the below code in the <head> tag.

<script src="HTMLEditor.js" language="javascript" type="text/javascript></script>

If you want to debug the code included in the javascript, add the word "debugger;" at the beginning of the code. In this way the compiler will start the debugging mode. Or you can go to your internet explorer options, navigate to Advanced, unselect the disable script debugging (internet explorer), unselect disable script debugging (other) and now add your breakpoints.

 

Editor Properties

If you want to save the text entered by the user to a .txt file or the HTML code to another .txt file, you can use the two properties added to this control.

First create two fields in your ascx.cs page.

Listing 18

 
protected System.Web.UI.HtmlControls.HtmlInputText ContentTxt;
protected System.Web.UI.HtmlControls.HtmlInputText ContentHtml;

Create two protected string variables which will store the above created fields' values.

Listing 19

 
protected string _text;
protected string _html;

The first property is called "ContentText" which can get the text and assign it to a string variable in your code behind.

ContentTxt is declared as HtmlInputText control in the field area. Its property value will be stored into the _text string variable.

Listing 20

 
public string ContentText
{
get 
{
return _text = ContentTxt.Value;
}
set
{
_text = value;
}
}

The second is called "ContentInnerHtml" which can get the specific HTML code for the entered text.

ContentInnerHtml is declared as HtmlInputText in the field area. Its property value will be stored into the _html string variable.

Listing 21

 
public string ContentInnerHtml
{
get
{
return _html  = ContentHtml.Value;
}
set
{
_html = value;
}
}

 

Adding a Stylesheet

In this section we will create a Stylesheet (Styles.css) to modify the toolbar and iframes UI. We will set the toolbar background color to blue and the background to repeat. Then we will give the same color to both the right and bottom borders of iframes. You are free to add whatever modification on the control user interface (UI) by modifying the below code.

Listing 22

 
.HtmlView
{
      background-color:white;
      border-bottom-width:medium;
      border-bottom-style:solid;
      border-bottom-color:cornflowerblue;
      border-right-width:medium;
      border-right-color:cornflowerblue;
      border-right-style:solid;
}
.FirstDiv
{
      background-color:white;
      border-bottom-width:medium;
      border-bottom-style:solid;
      border-bottom-color:cornflowerblue;
      border-right-width:medium;
      border-right-color:cornflowerblue;
      border-right-style:solid;
}
.toolbar
{
 background-color:cornflowerblue;
 background-repeat:repeat;
 }

Now it is time to link this Stylesheet to your webform where you dragged the user control by adding the below code inside the <head> tag.

<LINK href="Styles.css" type="text/css" rel="stylesheet">

Figure 3

Note that if you need to include more than one instance of the user control in a page, you have to create dynamical ids for all the div layers. You may have noticed the div layers’ ids are set to "userControlID_divlayer."

 

Conclusion

Creating you own rich text editor is not hard as it may seem. As you saw in this article, we explained it in detail using the javascript language and XHTML. This is the first release of this editor and we highly appreciate that you use it and provide us with your feedback. The second release will for sure have more features and if you have any new features or ideas they are most welcomed. We are currently working on the second release and it will be posted in this community and include Copy, paste, cut, bulleted list, numbered list, print and a more customizable toolbar. Hope that it was worth reading.

Download

Happy Coding!


Product Spotlight
Product Spotlight 

©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-29 9:43:06 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search