spacer
home / programming / javascript / gr / column11 / 1 current pageTo page 2To page 3
[next]

Lotus Notes Developer
AMS Staffing Solutions
US-OH-Columbus

Justtechjobs.com Post A Job | Post A Resume
Developer News
Get Ready for Microsoft's 'Oslo' Modeling Tool
Latest Linux Hits Networking Flaws
Metasploit 3.2 Offers More 'Evil Deeds'

How to Create a WYSIWYG Rich Text Editor in JavaScript. Pt. 1

Since the Internet was first unleashed, people have been using it to communicate with each other. It started with newsgroups and text based e-mail and has since progressed to web forums, richly formatted e-mails and more recently, blogs. A common feature of the last three is a text-box that allows the user to enter their own entry or e-mail to be either posted on to the forum or delivered to some destination. Taking a look around at what's on offer these days I have noticed one aspect of these sites that seems a bit primitive.

While users are able to compose richly formatted text with animated emoticons and many other features, there is no way to see what the finished work will look like until it is either posted or a preview is generated.

In this article I will show how a more modern look can be achieved that will allow writers to see how their text will look as they are writing it. This concept is not a new one, as WYSIWYG editors have been around for many years. They just haven’t seemed to hit web pages yet.

Basic Concepts

A text editor is a control that accepts keyboard and mouse input and displays the resulting text in some region of the screen. Implementing one will require wiring a number of collaborating HTML elements together.

The first hurdle to cross is finding the combination of elements that will work for each browser. Unfortunately, Internet Explorer and Netscape have significant differences in the ways HTML elements interact with keyboard and mouse events. In Internet Explorer, any HTML element can receive keyboard events so long as it is visible, whereas with Netscape, keyboard events are limited to a subset of HTML elements although they do not need to be visible.

For Internet Explorer, a <div> element will be enough both to display the formatted text and handle the user's input while in Netscape, the keyboard events will be caught by a hidden text box. Later on, we'll see how these parts fit together.

A vital part of any editor is the cursor; it shows the user where the text will be inserted or deleted from. In this article I’ve used a <span> element containing a single bar character '|'. A background timer event toggles its visibility to distinguish it from the other characters.

Finally, some mechanism is needed to store the user’s text as they type in a way that will record the multiple formats and allow individual characters to be added and removed. I chose to use a <span> element to store each individual character. Insertion and deletion of characters translates to inserting and deleting the <span> elements. By modifying the style attributes of the <span> element, each character can be formatted individually.

The Code

Because of differences in the browsers, the code will sometimes need to differentiate between browsers. A Boolean variable is defined at the start to manage this task:

 

// test the browser

var bIsNetscape = (navigator.appName == "Netscape");

 

The editor is managed fully by a single JavaScript class called “RichEdit”. The constructor (below) has arguments for name, text-box style, initial character style and some initial text.

 

function RichEdit(name, editStyle, charStyle, sText)

{

  // initialize some internal values

  this.bInFocus = false;

 

The charStyle argument defines the initial style settings to use for new characters. It also defines the set of styles that the RichEdit code will process, more on this later.

 

  // save the character style for later

  this.style = charStyle;

 

The RichEdit object is designed to be instantiated inline with the HTML page load, so the first thing that must be done is to create a place to insert the RichEdit controls, this will be called the insertion point as the rest of the code will use this place to insert HTML elements onto the page.

 

  // create an insertion point.

  document.write('<div id="' + name + '"></div>');

  this.oInsertionPoint = document.getElementById(name);

 

Once the insertion point is created, standard DOM methods are used to insert further elements. The first element to go in is the ‘text’ box, which is modeled using a <div> element. The editStyle argument is applied to the <div> to give it the desired look and feel and the supplied text is inserted

 

  // the 'text' box - or where the text goes

  this.oDiv = document.createElement('div');

 

  // set the styles

  this.copyStyle(this.oDiv, editStyle);

  this.oDiv.style.overflow = "auto"; 

  this.oDiv.style.wordWrap = "break-word";

 

  // insert the text

  if ( sText ) this.setHTML(sText);

 

  // link back to this object

  this.oDiv.oRichEdit = this;

 

Now to handle user inputs. This is the point where Internet Explorer and Netscape diverge. As mentioned above, Netscape will not deliver keyboard events to <div> elements so I've used an invisible floating <input> element to capture these events. This <input> element is stored within a <span> element and inserted into the page. With this in place, event handlers can be added to the <input> element to capture the keyboard input. The RichEdit control needs to attach handlers to the onfocus and onblur events. These events signal when the user's input becomes directed to the control and when it leaves.

 

  // handle clicks

  this.oDiv.onclick = RichEdit.prototype.onDivClick;

 

  if ( bIsNetscape )

  {

     // In Netscape, <div> elements don't have keyboard events, so

     // create a small, hidden text <input> box to catch them

     var oTextSpan = document.createElement('span');

    oTextSpan.style.position = 'absolute';

    oTextSpan.style.visibility = 'hidden';

 

    this.oTextbox = document.createElement('input');

    this.oTextbox.type = 'text';

    this.oTextbox.style.width = "1px";

    oTextSpan.appendChild(this.oTextbox);

    this.oInsertionPoint.appendChild(oTextSpan);

 

     // add event handlers

    this.oTextbox.oRichEdit = this;

    this.oTextbox.onkeypress = RichEdit.prototype.onKeyPress;

    this.oTextbox.onfocus = RichEdit.prototype.onDivFocus;

    this.oTextbox.onblur = RichEdit.prototype.onDivBlur;

  }

  else

 

 

 

home / programming / javascript / gr / column11 / 1 current pageTo page 2To page 3
[next]



JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Solutions
Whitepapers and eBooks
Microsoft Article: Will Hyper-V Make VMware This Decade's Netscape?
Microsoft Article: BitLocker Encryption on Windows Server 2008
Go Parallel Article: Intel Thread Checker, Meet 20 Million LOC
IBM Whitepaper: Innovative Collaboration to Advance Your Business
Internet.com eBook: Real Life Rails
Avaya Article: Call Control XML - Powerful, Standards-Based Call Control
Tripwire Whitepaper: Seven Practical Steps to Mitigate Virtualization Security Risks
Internet.com eBook: The Pros and Cons of Outsourcing
Internet.com eBook: Best Practices for Developing a Web Site
IBM CXO Whitepaper: The 2008 Global CEO Study "The Enterprise of the Future"
Avaya Article: Call Control XML in Action - A CCXML Auto Attendant
Go Parallel Article: James Reinders on the Intel Parallel Studio Beta Program
IBM CXO Whitepaper: Unlocking the DNA of the Adaptable Workforce--The Global Human Capital Study 2008
Adobe Acrobat Connect Pro: Web Conferencing and eLearning Whitepapers
Go Parallel Article: Getting Started with TBB on Windows
HP eBook: Storage Networking , Part 1
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
Webcasts
Go Parallel Video: Intel(R) Threading Building Blocks: A New Method for Threading in C++
HP Video: Is Your Data Center Ready for a Real World Disaster?
Microsoft Partner Portal Video: Microsoft Gold Certified Partners Build Successful Practices
HP On Demand Webcast: Virtualization in Action
Go Parallel Video: Performance and Threading Tools for Game Developers
Rackspace Hosting Center: Customer Videos
Intel vPro Developer Virtual Bootcamp
HP Disaster-Proof Solutions eSeminar
HP On Demand Webcast: Discover the Benefits of Virtualization
MORE WEBCASTS, PODCASTS, AND VIDEOS
Downloads and eKits
Microsoft Download: Silverlight 2 Software Development Kit Beta 2
30-Day Trial: SPAMfighter Exchange Module
Red Gate Download: SQL Toolbelt
Iron Speed Designer Application Generator
Microsoft Download: Silverlight 2 Beta 2 Runtime
MORE DOWNLOADS, EKITS, AND FREE TRIALS
Tutorials and Demos
IBM IT Innovation Article: Green Servers Provide a Competitive Advantage
Microsoft Article: Expression Web 2 for PHP Developers--Simplify Your PHP Applications
MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES
webref The latest from WebReference.com Browse >
Anatomy of an Ajax Application · Popular JavaScript Framework Libraries: An Overview · Controllers: Programming Application Logic - Part 2
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
MS Access and MySQL · Cisco AutoQoS: VoIP QoS for Mere Mortals · While VoIP Adoption Explodes in Enterprise, Carrier Spending Lags

Created: March 27, 2003
Revised: February 2, 2005

URL: http://webreference.com/programming/javascript/gr/column11/1