Вы находитесь на странице: 1из 17

Building a WYSIWYG HTML Editor Part 1/2

Author: Mitchell Harper


Date Added: 27th Fed 2002
Type: Tutorial
Rating:

This is a printable version of "Building a WYSIWYG HTML Editor Part 1/2". For the complete
online version, please visit http://www.devarticles.com/content.php?articleId=90

Page 1: Introduction
Whether you're creating your own personal web site, a site for a medium sized business, or a
site for a company intranet, the content management system (CMS) is one of the most
important aspects of the overall design. If you're designing a web site that will constantly have
new products or company news added to it, then you can be pretty sure that the person from
the company who will be adding that content will have at best beginners knowledge of HTML.

So how do we overcome this problem? Well, we could offer to do the updates ourself, but
that's pointless really: we're web developers, not content updaters for company web sites. We
could offer some form of offline template that the company can edit and upload, but this is
neither time effective nor streamlined. One last thing we could do is provide the company with
a browser based WYSIWYG HTML editor similar to FrontPage or Dreamweaver.

If you're thinking that this is out of your league as a developer, then think again. Internet
Explorer 5 and later supports a set of commands to facilitate complete browser based content
creation. With just a couple of lines of JavaScript, we can create a truly mind-blowing
WYSIWYG content editor in a matter of minutes, and that's what I'm doing to show you how to
do today.

To test the samples in this article, you should have preferably IE5 or IE6 (patched) installed on
your PC. You don't need any fancy server side programming experience, just a bit of HTML and
JavaScript. I will teach you the commands we will be using as we progress.

Page 2: Why a WYSIWYG editor


Why not? I'm mocking up a site design for one of my clients at the moment, and I prefer to do
it quickly using FrontPage 2000. When I'm actually developing the final release of the site
however, I use Visual Interdev, but to create a quick site prototype, you can’t beat a
WYSIWYG interface.

So how does Internet Explorer fit into the picture? Well, since IE5, there's been a JavaScript
method called execCommand. ExecCommand is used to execute a command on a document.
In the sense of execCommand, a command is a pre-defined set of functions that can
manipulate the page layout, insert an image, url, list, text box, horizontal rule, etc right into a
HTML document in the browser. In fact, pretty much anything you can do with FrontPage, you
can do in IE using the execCommand JavaScript method.

The signature and parameters of the execCommand method are shown below:
bSuccess = object.execCommand(sCommand [, bUserInterface] [, vValue])

• bSuccess: The return value from a call to execCommand. Returns true if the
command executed OK, false if it failed.
• sCommand: One of the pre-defined commands that can be used to manipulate a
document, such as "bold" to make the selected text bold.
• bUserInterface: A Boolean value that indicates whether or not the command displays
a user interface (don't worry about this parameter for now).
• vValue: A variant value that can be used in combination with sCommand to pass in a
required value. For example, if I passed "FontName" as sCommand, false as
bUserInterface, and "Verdana" as vValue, then the selected text's font would be
changed to Verdana.

At this point I'm pretty sure that 99% of you will be sitting there with a puzzled look on your
face...right? Well let’s supplement all of the nitty gritty details with a simple example. Add the
code below to a new page called testbold.html. Save the file in c:\ and run it in IE5 or above:

<html> 

<head> 

<title> Using execCommand to bold text </title> 

<script language="JavaScript">

function Init() 

iView.document.designMode = 'On'; 

function boldIt() 

iView.document.execCommand('bold', false, null); 

</script>

<body onLoad="Init()"> 
<iframe id="iView" style="width: 200px; height:70px"></iframe> 

<br><br> 

<input type="button" onClick="boldIt()" value="Toggle Bold"> 

</body> 

</html>

When you click on the area inside the inline frame, you will be able to edit it. Type in some
text, highlight it, and click on the toggle bold button:

As you can see in the screen shot above, as soon as you select some text and click the toggle
bold button, IE automatically renders the selected text as bold. Let's look at the important
parts of our code before moving on:

function Init() 

iView.document.designMode = 'On'; 

}
The Init() command is called from the onLoad event handler of the <body> tag. Our inline
frame has an id of iView, so we can use the DOM to get at its properties. To make it so that we
can actually click in and edit the contents of the inline frame, its designMode attribute must be
set to "On". If you comment out this line and refresh the page, you'll notice that you can't
click into the inline frame and enter text.

function boldIt() 

iView.document.execCommand('bold', false, null); 

When we click on the toggle bold button, the boldIt() function is called. Inside of this function
we have just one line. We call the execCommand method of our inline frame, passing in "bold"
as the command. The user interface value is set to false, and no value is required, so we pass
in null.

[Note] The execCommand method cannot be called until after the page loads. As you can
see, I've used an inline frame as part of our example. Although we could use execCommand
on <div> tags and other HTML controls directly, I think using an inline frame better suits our
purposes of creating a HTML editor [End Note]

Page 3: execCommand examples


Now that we're a little bit more familiar with the execCommand method, let's look at a list of
some of the commands that we can perform with it (the complete list is available here):

• ForeColor: Get or set the foreground color of the selected region.


• BackColor: Get or set the background color of the selected region.
• Bold: Toggles between the select region being bolded.
• Italic: Toggles between the selected region being italicised.
• Underline: Toggles between the select region being underlined.
• Copy: Copies the selected region to the clipboard.
• Cut: Removes the selected region from the document.
• Paste: Adds data from clipboard to region (if applicable).
• InsertHorizontalRule: Adds a horizontal rule to the region.
• InsertImage: Displays an IE defined modal dialog that contains full image selection
features, alt tag modification, border setting, etc.
• InsertMarquee: Converts the selected text into a marque.
• InsertSelectDropDown: Adds a drop down list to the region.
• Print: Displays the windows print dialog so that the region can be printed.
• Refresh: Refreshes the region.
• CreateLink: Displays an IE defined modal dialog that lets you add a hyperlink using
either selected text or new text.
• InsertUnorderedList: Toggles between the selected text being an unordered list and
normal text.
As you can see, we can do some pretty powerful things with the execCommand method. Let's
build an advanced HTML content editor that allows us to toggle between HTML mode and
WYSIWYG mode, format text, add images, links, lists and more.

Page 4: Building our HTML editor


Over the next couple of pages we're going to create our own browser based WYSIWYG HTML
editor. I won't look at the entire source code for the editor, but I will go into detail about the
most important points. The single HTML file and required images are available as part of the
support material for this article. You should download it before continuing.

Firstly, we want to make our HTML editor boths look and feels like a "normal" HTML editor,
such as Front Page 2000. Using style sheets and events, we can create a set of "buttons" that
mimic those found in Windows applications. Our HTML editor will contain several buttons to
bold text, insert images, etc. Here's how the image that makes up the bold button looks:

<img alt="Bold" class="butClass" src="bold.gif" onMouseOver="selOn(this)" 
onMouseOut="selOff(this)" onMouseDown="selDown(this)" onMouseUp="selUp(this)" 
onClick="doBold()">

It has a class attribute of "butClass", which is defined in the <head> part of our HTML
document:

.butClass 

border: 1px solid; 

border­color: #D6D3CE; 

It also responds to five events, which will be fired by the browser: onMouseOver, onMouseOut,
onMouseDown, onMouseUp and onClick. The contents of each of these attributes points to a
JavaScript function that is defined at the top of the file. For example, when a user moves
his/her mouse over a button, the selOn function is called, passing in the image as an object
("this" represents the control for which the event has been raised):

function selOn(ctrl) 

ctrl.style.borderColor = '#000000'; 

ctrl.style.backgroundColor = '#B5BED6'; 
ctrl.style.cursor = 'hand'; 

The selOn function sets the border color of the image to black, its background color to
"FrontPage blue", and the mouse cursor to a hand.

Each button in our HTML editor responds to the same five events in exactly the same way. The
only difference is that when the onClick event is fired (the user clicks on a button), then each
button will call a different JavaScript function, thus performing a different task.

Here's how the buttons will look at different stages:

Besides buttons, our HTML editor also contains an inline frame (<iframe>) and drop down lists
to set the font type and size, as well as various heading sizes (<h1>, <h2>, etc). If you've
downloaded the support material, you will see that our HTML editor looks like this in IE:
It’s amazing what you can do with a little bit of CSS and some positioning isn't it? When each
button is clicked, its onClick event is fired. Here's the code for the doBold() JavaScript
function, which is called when the bold "button" is clicked on:

function doBold() 

iView.document.execCommand('bold', false, null); 

As you can see, we've used the same execCommand that we used earlier to test bolding some
text. In fact, most of our JavaScript functions only contain one line, which is the call to the
inline frame's execCommand method.

The code for the italic and underline buttons is fairly similar to the bold buttons code, so let's
look at the code for the center align function, doCenter():

function doCenter() 

iView.document.execCommand('justifycenter', false, null); 

One again, a simple call to execCommand, passing in the command "justifycenter". To actually
test the justifycenter command, click on the inline frame, type in some text, select it, and click
the center align button, like this:
The insertorderedlist and insertunorderedlist commands can be passed to execCommand to
toggle whether or not the selected text is part of either an ordered or unordered list
respectively. When the user clicks on the bulleted (unsorted) list button, the doBulList()
JavaScript function is called. It looks like this:

function doBulList() 

iView.document.execCommand('insertunorderedlist', false, null); 

Here's a screen shot from me playing around with an unordered list. I've also changed the
colors of the foreground and background, which we will look at next:
Page 5: Building our HTML editor (contd.)
What good is a web site that has just boring old black text and a white background? Luckily
execCommand has two commands that we can use to change the color of text and the
background. These commands are forecolor and backcolor.

When the foreground color button is clicked (the one with the "A" on it), the JavaScript
function doForeCol() is called. To change the foreground color, we must first get the color to
change it to. We simply display a prompt box using JavaScript's prompt() command to get the
required color code:

This color code can either be a proper HTML color code (such as #3DA1CC), or an alias (such
as red). In another article I'm going to show you how to use JavaScript's showModalDialog
function to show a window from which the user can actually click on a color and select it, but
for now the prompt() function will do. The code for the doForeCol() function looks like this:

function doForeCol() 

var fCol = prompt('Enter foreground color', ''); 

if(fCol != null) 

iView.document.execCommand('forecolor', false, fCol); 

As you can see in the code above, the foreground color is grabbed from a call to prompt() and
passed in as the third argument to execCommand.

One of the things that amazed me when I started playing around with the execCommand
method was that when you pass the "createlink" command to it, IE displays a modal window
that looks like this:

If you have some text selected, then when you click OK that text becomes a hyperlink. If not,
the URL of the hyperlink is inserted into the document. When the hyperlink button is clicked in
our HTML editor, the doLink() JavaScript function is called. It looks like this:

function doLink() 

iView.document.execCommand('createlink'); 

Here are two different version of the link: the first one links a piece of text, and the second
one is just the URL:
But what about images? After all, images are what make a site, right? It's actually quite easy
to add an image to our document. When the image button is clicked, the doImage() JavaScript
function is called, which looks like this:

function doImage() 

var imgSrc = prompt('Enter image location', ''); 

if(imgSrc != null) 

iView.document.execCommand('insertimage', false, imgSrc); 

Nothing new here, we simply use prompt() to get the URL of the image and pass it as the
value to execCommand. The URL can be local or remote. Here's a screen shot:
See the little squares around the image? Well these can be used to dynamically resize the
image. To add a horizontal rule to our document, we use the horizontal rule button. When
clicked, it calls the doRule() JavaScript function whose code looks like this:

function doRule() 

iView.document.execCommand('inserthorizontalrule', false, null); 

One good thing about our HTML editor is that once you insert a horizontal rule (or any other
control), you can change its properties very easily. For example, if I wanted to change its
color, I would click on it and then click on the foreground color button, enter "green", and the
color of the horizontal rule would change to green.

Page 6: Building our HTML editor (contd.)


Now that we've covered all of the controls, let’s look at how we can change the font and size
of the text in our document. The three dropdown lists at the bottom of our HTML editor can be
used to change the font, change the fonts size, and format text using a header style.

When the selected option of the font dropdown list is changed, the JavaScript function
doFont() is called. It looks like this:

function doFont(fName) 

if(fName != '') 

iView.document.execCommand('fontname', false, fName); 

If we have selected some text in our document, then only that text's font will change. If we
haven't selected any text, then any text that we type in after selecting the new font will
appear as the selected font.

The fName argument of the doFont() function is the value of the currently selected font, and is
retrieved in the dropdown lists onClick handler:

<select name="selFont" onChange="doFont(this.options[this.selectedIndex].value)">

The font size dropdown list works in the same way, so we will skip that. The heading dropdown
list allows us to format our code using header tags, such as <h1>, <h2>, etc. When its option
is changed, the doHead() JavaScript function is called:

<select name="selHeading" onChange="doHead(this.options[this.selectedIndex].value)">

The doHead() JavaScript function looks like this:

function doHead(hType) 

if(hType != '') 

iView.document.execCommand('formatblock', false, hType); 

doFont(selFont.options[selFont.selectedIndex].value); 


}

As you can see, we pass the "formatblock" command to execCommand, and set the value
argument to the heading type, which is the value of the currently selected option for the
heading dropdown list. After the call to execCommand, the type of font for the selected text
reverts back to the default, so we have to set it again. That's why we call doFont.

All modern HTML editors have the option to switch between WYSIWYG view and HTML code
view. Our HTML editor is no different. The blue button in the lower right hand corner can be
used to toggle between modes. It calls the doToggleView() JavaScript function, whose code
looks like this:

<script language="JavaScript">

var viewMode = 1; // WYSIWYG

// Other code exists here

function doToggleView() 

if(viewMode == 1) 

iHTML = iView.document.body.innerHTML; 

iView.document.body.innerText = iHTML; 

// Hide all controls 

tblCtrls.style.display = 'none'; 

selFont.style.display = 'none'; 

selSize.style.display = 'none'; 

selHeading.style.display = 'none'; 

iView.focus(); 
viewMode = 2; // Code 

else 

iText = iView.document.body.innerText; 

iView.document.body.innerHTML = iText; 

// Show all controls 

tblCtrls.style.display = 'inline'; 

selFont.style.display = 'inline'; 

selSize.style.display = 'inline'; 

selHeading.style.display = 'inline'; 

iView.focus(); 

viewMode = 1; // WYSIWYG 

The "viewMode" JavaScript variable is defined globally, and is set to 1 (WYSIWYG) by default.
When the toggle display button is clicked, its value is checked and changed accordingly.

To show the source code of our document, we grab the inline frame's HTML from using the
iView.document.body.innerHTML variable. We then set the innerText property of the inline
frame to this value, which in turns causes its HTML code to be displayed. We also hide our
HTML editors buttons and dropdown lists using display = 'inline'.
Our HTML editor before toggling:

Our HTML editor after toggling:


As you can see, all controls disappear until the toggle display button is clicked again. This is a
handy feature if you want to add some JavaScript or maybe an <object> tag to your
documents HTML code.

Page 7: Conclusion
Well there you have it, a fully capable, in-browser HTML editing system! In this article we've
looked at how to use the execCommand method to both build and format a HTML document
on the fly. In the next article I'm going to show you how we can save our source code, add a
color picker, add database support using ASP and SQL Server, and more. It will definitely been
an interesting read, so make sure you keep an eye out for it.

For more great programming articles, please visit http://www.devarticles.com. If you have an
opinion or question about this article, then please post it at the devArticles developer forum,
which is located at http://www.devarticles.com/forum

Вам также может понравиться