Login Register

Editor

Dijit's Rich Text editor, Dijit.Editor, is a text box on steroids. Designed to look and work like a word processor. The editor features a toolbar, HTML output, and a plugin architecture that supports new commands, new buttons and other new features.

Note: Editor is currently in development. Since we had problems getting an example to work over CDN, this example requires locally-installed Dojo. See Quick Installation for details. These problems should be worked out in the 1.0 time frame. (We use /dojoroot here, but you can substitute your own Dojo root directory with no problems.)

Examples

The default configuration of Dijit.Editor has a toolbar along the top with icons for Copy, Cut, Paste, Bold, Italic, Underline, Numbered and Bulleted Lists, and Indent Left and Right.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Editor Demo</title>
    <style type="text/css">
        @import "http://o.aolcdn.com/dojo/1.0/dijit/themes/tundra/tundra.css";
        @import "http://o.aolcdn.com/dojo/1.0/dojo/resources/dojo.css"
    </style>
    <script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0/dojo/dojo.xd.js"
        djConfig="parseOnLoad: true">
</script>
        <script type="text/javascript">
       dojo.require("dojo.parser");
       dojo.require("dijit.Editor");
     </script>
</head>
<body class="tundra">
<form method="post">
<textarea name="field" width="200px" dojoType="dijit.Editor">
        It was a dark and stormy night.  Your story belongs here!
</textarea>
<input type="submit" value="Save" />
</form>
</body>
</html>

Toolbar Customization

You may limit the commands people can perform, such as removing the Indent Left button. Each button corresponds to a plugin, hence you specify toolbar buttons with the plugins attribute. For example, the following toolbar includes copy, cut, paste and bold:

<textarea dojoType="dijit.Editor" height="200"
    plugins="['copy','cut','paste','|','bold']">
</textarea>

The plugins attribute is specified in JavaScript array literal format. Here is a list of built-in plugins that you can reference: (names are case sensitive and those in italics are not yet implemented)

  • Character Formatting: bold, italic, underline, strikethrough, subscript, superscript, removeFormat, forecolor, hilitecolor
  • Paragraph Formatting:: indent, outdent,justifyCenter, justifyFull, justifyLeft, justifyRight, delete, selectall
  • Inserting Objects:insertOrderedList, insertUnorderedList, createlink (use LinkDialog plugin), inserthtml
  • Misc.: undo, redo, cut, copy, paste
dijit.Editor (Rich Text Editor)
Attributes
captureEvents String[]
[]
Events that should be connected to the underlying editing area, events in this array will be addListener with capture=true
customUndo Boolean
true for IE
Whether to use custom undo/redo support instead of the native browser support. By default, only enable customUndo for IE is available, as it has broken native undo/redo support. Note: the implementation does support other browsers which have W3C DOM2 Range API.
editActionInterval Integer
3
When using customUndo, not every keystroke is saved as a step. Instead typing (including delete) will be grouped together: after a user stop typing for editActionInterval seconds, a step will be saved; if a user resume typing within editActionInterval seconds, the timeout will be restarted. By default, editActionInterval is 3 seconds.
events String[]
["onKeyPress", "onKeyDown", "onKeyUp", "onClick"]
Events that should be connected to the underlying editing area
focusOnLoad Boolean
false
Whether focusing into this instance of rich text when page onload
height String
300px
Set height to fix the editor at a specific height, with scrolling. By default, this is 300px. If you want to have the editor always resize to accommodate the content, use AlwaysShowToolbar plugin and set height=""
inheritWidth Boolean
false
Whether to inherit the parent's width or (if false) simply use 100%.
isClosed Boolean
true
isLoaded Boolean
false
minHeight String
1em
The minimum height that the editor requires
name String If a save name is specified, the content is saved and restored when the user leaves the page and returns, or if the editor is not properly closed after editing has started.
onLoadDeferred dojo.Deferred Deferred can be used to connect to the onLoad function. This will only be set if dojo.Deferred is required
plugins See plugin section
styleSheets String Semicolon (";") separated list of .css files for the editing area.
toolbar dijit.Toolbar DOM Node To use your own custom toolbar
updateInterval Number
200
Number of ms between display changes for onNormalizedDisplayChanged
Methods
addKeyHandler(/*String*/key, /*Int*/modifiers, /*Function*/handler) Add a handler for a keyboard shortcut
addPlugin(/*String||Object*/plugin, /*Integer?*/index) Takes a plugin name as a string or a plugin instance and adds it to the toolbar and associates it with this editor instance. The resulting plugin is added to the Editor's plugins array. If index is passed, it's placed in the plugins array at that index. No big magic, but a nice helper for passing in plugin names via markup.
addStyleSheet(/*dojo._Url*/uri) Add an external stylesheet for the editing area
beginEditing(/* String */cmd) Set mark for capturing undo steps
close(/*Boolean*/save, /*Boolean*/force) Ends the editor and optionally writes back the modified contents to the element from which it originated.
endEditing(/* Boolean */ignore_caret) Clear the undo buffer, as in after a save
exec(/* String */cmd) Execute given command
String escapeXml(/*String*/str, /*Boolean*/noSingleQuotes) Adds escape sequences for special characters in XML: &<>"' Optionally skips escapes for single quotes
open(/*DomNode?*/element) Transforms the node referenced in this.domNode into a rich text editing node. This results in the creation and replacement with an iframe if designMode(FF)/contentEditable(IE) is used.
placeCursorAtEnd() Place the cursor at the end of the editing area
placeCursorAtStart() Place the cursor at the start of the editing area
Boolean queryCommandAvailable(/*Boolean*/ disabled) Tests whether a command is supported by the host. Clients should check whether a command is supported before attempting to use it, behaviour for unsupported commands is undefined.
Boolean queryCommandEnabled(/* String */cmd) Checks whether a command is enabled or not
Boolean queryCommandState(/*Boolean*/ disabled) Checks the state of a given command
String queryCommandValue(/* String */cmd) Checks the value of a given command
redo() Redoes last un-done command
removeStyleSheet(/*dojo._Url*/uri) Remove an external stylesheet for the editing area
replaceValue/*String*/html This function sets the content while trying to maintain the undo stack (currently, this only works okay with Moz, this is identical to setValue in all other browsers)
undo() Undo last command
Extension Points
onChange This is initiated if the editor loses focus and the content is changed
onDisplayChanged This event is initiated each time the display context changes and the result needs to be reflected in the UI. If you do not want to have the update too often, use onNormalizedDisplayChanged instead
onNormalizedDisplayChanged This event is initiated on each updateInterval ms or more
setupDefaultShortcuts() Override to setup your own handlers. The default implementation does not use Editor commands, but directly runs the builtin commands within the underlying browser support.

Accessibility (Applies to 1.0 version of editor)

Keyboard for Editor

ActionKey
Move focus to the next widget in the tab order.Tab (must press tab twice in some situations - see Known Issues below)
Move focus to the prior widget in the tab order (the editor toolbar)Shift+Tab (must press shift-tab twice in some situations - see Known Issues below)

Keyboard for Editor Toolbar

ActionKey
Move focus to the next enabled button in the toolbar.arrow right in left to right locales, arrow left in right to left locales
Move focus to the previous widget in the toolbararrow left in left to right locales; arrow right in right to left locales.

The arrow keys will not work within any optional drop down lists such as ComboBox or FilteringSelect in the editor toolbar until the drop down list of choices has been activated. Use the backspace or escape key to clear the current selection in the textbox associated with the drop down. When the list of choices is not activated, the arrow keys will move between toolbar buttons rather than within the combobox or select.

Known Issues

  • On Firefox 2, the user must press the Tab key twice before keyboard focus moves to the next widget. This is a permanent restriction on Firefox 2. The reason for this is because Firefox implements usage of the tab key within the editor to indent text and shift-tab to outdent text. There is no keyboard mechanism in Firefox to move focus out of the editor. So, the dijit editor traps the tab key in the editor and sets focus to the editor iframe. From there pressing tab again will move to the next focusable item after the editor. When shift-tab is pressed within the editor, focus is set to the toolbar associated with the editor (currently there is always a toolbar defined for a dijit editor). Some people are unhappy with the loss of the tab key functionality within the editor so future versions may have an option to allow the use of tab and shift-tab within the editor to indent and outdent text.
  • In IE6 or 7 when the editor has been created from a textarea the user must press tab twice to set focus into the editor to begin inserting or editing text. Likewise, with focus within editor text the user must press shift-tab twice to set focus back to the toolbar.

Can anybody tell me, how do

Can anybody tell me, how do retrieve value of Rich text editor

getValue()

... as in dijit.byId("myEditor").getValue(false). Use "false" to leave the editor text intact, or "true" to erase it from the box itself. getValue returns the same value either way.

I am in the process of updating the docs for 1.0...

Loading plugins

Under the list of plugins available it says that createlink is an available type, and that I should use the LinkDialog plugin, but adding LinkDialog or createlink to the plugins attribute of the editor tag does nothing.
Is there another way to go about this? Am I missing something?

Update

I have been playing around with the addPlugin function (I don't know why adding it to the attribute list in the tag doesn't work) and am still having problems.

I do a dojo.addOnLoad to call my addPlugin function and it tells me the editor does not exist. Then I changed my addOnLoad to addOnLoad( setTimeout("initEditor()", 1000) ) which works. Now, no matter what information I pass the addPlugin function, I get a javascript error mll[x] is not a function on dojo.js line 20.

addPlugin

I think the addPlugin function needs to be run after the editor is created (takes some time)
Have you tried running addPlugin() in the editor's onLoadDeferred function??

I got it to work

Thanks for the tip playwithdojo, it got me headed the right direction.

For anyone else who runs into this trouble, here is the final code I ended up with:

dojo.require("dojo.parser");
dojo.require("dijit.Editor");   
dojo.require("dijit._editor.plugins.LinkDialog");       

dojo.addOnLoad( setTimeout("initEditor()", 1500) );

function initEditor(){
     dijit.byId("editor").onLoadDeferred.addCallback = addEditorPlugins();      
}

function addEditorPlugins(){
     p = new dijit._editor.plugins.LinkDialog({});           
     dijit.byId("editor").addPlugin(p);
     return;
}

Here is a list of things that I couldn't get to work:

  • Calling addPlugin(string), only initializing it myself worked
  • Calling initEditor without the setTimeout, for some reason the editor doesn't exist about 50% of time when the addOnLoad functions get called
  • Get the 'mll[x] is not a function' error to go away. Even with the code above it still shows up even though everything seems to be working

After you dojo.require

After you dojo.require LinkDialog, then you can easily put it in the html element with plugins="['createLink']".

I would like to use the innerHtml plugin as well, but it doesn't seem to be listed in the plugins directory...

Rich Text Editor value workaround

This works for me.

In my html:

Sample text
		
    

    Save
        
            saveRichText('richText', dijit.byId('tresc').getValue());
            dojo.xhrPost({
		url: 'lib/saveIt.php',
                load: function(data){
                    alert(data);
		},
                error: Error,
                form: 'myForm'
            });
        
    

The saveRichText() function in my header:

function saveRichText(id, str){
    document.myForm[id].value = str;
}

The saveIt.php file:

<?php

    if(isset($_POST['richText'])){
        $richText = $_POST['richText'];
    } else {
        $richText = 'error';
    }
    print $richText;
?>

I've slimmed down the example, but that's basically it. I use this method to save rich text in mySQL database.

document.myForm and XHTML

I using XHTML strict and i get an error the docuemt.myForm has no properties. Has anyone an idea?

I also have this problem

Same for me, document has no properties ... :(, anyone knows why ?

Find the problem

The form beyond the texterea must have the same name. For example: you use document.myForm[id] = str; myForm is the same name as the name of the form. I actualy don't know if the html 4.0.1 can work with ids but xhtml 1.0 needs also the name with the same name.

Dumb question, what's the opposite of getValue??

I put in a test for FF. If FF, I successfully do:
dijit.byId('editor1').replaceValue(myrawhtml)

However, if NOT FF, I try:
dijit.byId('editor1').setValue(myrawhtml)

but it doesn't work. I tried just jamming it into the inner html of my textarea, but that object seems to go away in favor of some kind of iframe. I tried dinking around with that but could only get non-editable text to display.

What's the solution? I love this thing, but it's kinda useless if I can't load up and edit a pre-existing html block.

P.S. Not wanting to mess with servers and db's, I'm using the clipboard rather successfully to move stuff back and forth to notepad. Also, I'd like to try letting the user switch back and forth between the tagged "raw" window and the rich window. I think I need to be able to stuff the content back and forth (and a keyup event), no?

PLEASE HELP: how can I dynamically put content into the editor?

My customer really likes this. The only thing that stops him from using it is that he's on IE and I can't figure out how to dynamically put raw HTML into the edit iframe from within javascript.

Is there a work-around for the lack of replaceValue in IE?

There is no file out there to load into the iframe's src tag; the raw html is being created on the client in js based on conditions.

I did try replacing my original container div's innerHTML with a brand-new textarea html string with the dojoType="dijit.Editor" attribute (and with my new raw html content imbedded within the textarea), but I couldn't figure out how to trick dojo/dijit into re-scanning it to find the dojoType and replace the textarea with the iframe and re-load the plugins, etc..

Solution: Dynamically putting content into editor window

I'm sure what I did isn't elegant, but it kind of works. The magic incantation for IE is:

var ewin = document.getElementById("editorwindow")
var ifr = ewin.getElementsByTagName("iframe")
ifr[0].contentWindow.document.body.innerHTML = stx

(assuming you have a containing div with id="editorwindow")

I have a demo of an editor that allows you to toggle between tabs for Rich Text and Raw HTML. It also copies a starting point HTML source off the clipboard if you want and will post the resulting HTML to the clipboard (FF users will have to enable that behavior, instructions provided if it fails).

http://wellhost.com/dojoedit.html

I'm sure I missed something and this whole thing won't work somehow...

For one thing, I notice that leading comments inserted in the Raw tab get dropped for some reason when I switch back and forth. Sigh. That makes me wonder if a lot of other things will break -- probably that flakey innerHTML call. Suggestions welcome.

Raw tags? BR tag?

Of course, if you enter leftbracket + br + space + solidus + rightbracket, it's going to get saved with all the ampersand + gt + semicolon indirection.

This is a good thing.

But: is there a way to allow the user to enter a raw html tag and actually have it do something?

One pet peeve I have is the inability to insert br linebreak tags when using HTML editors. I'd actually prefer to change the Enter key behavior to do that instead of p tags and let user hit enter a couple of them if s/he really wants all that space.

I know that br tags probably aren't kosher xhtml or whatever, but sometimes a guy just wants a simple linefeed!

Is there any way for getting the HTML tags for a selected text ?

Hi,

Is there any way for retrieving the HTML tags that are applied for a selected portion of a text in the Editor widget ?

For example, I am having a line of text in bold and a second line in italics entered in the editor widget. If I am selecting the first line, I need a way for getting the HTML tags that are applied to the first line (selected portion).

Thanks in advance,

Binu Paul < binu@amtindia.co.in>

----------------------------------------------------------------------------------------------------------------
Code snippet:

var docObj = dijit.byId('txtarea').window.document ;
var selText = docObj.getSelection();
var nodeCount = dijit.byId('txtarea').window.frameElement.contentDocument.childNodes[0].childNodes[1].childNodes.length;
var win = dijit.byId('txtarea').window;
var doc = dijit.byId('txtarea').window.document;
var gs = 'getSelection';
var sel = w[gs] ? w[gs]() : d[gs] ? d[gs]() : d.selection.createRange().text;

if ((selText.length > 0)) {
console.info("Selected text = " + selText);
console.info(sel.anchorNode);
console.info(sel.focusNode);
}

for( i=0; i< nodeCount; i++) {
console.info(dijit.byId('txtarea').getNodeHtml(dijit.byId('txtarea'). window.frameElement.contentDocument.childNodes[0].childNodes[1].childNodes[i]));
}

Sharing a toolbar across multiple text areas

Does the RichTextEditor support a shared toolbar? I want to have multiple content areas on a page that are all managed with the same toolbar. I believe this was possible with the old Editor2, right?

I've tried creating a Toolbar and passing that in as a reference to each instance of the Editor that I create, but this results in the Editor plugins being added to the toolbar multiple times, once for each text area I want to edit. Any ideas as to how to work around this?

known issue

Hi,
I wanted to know, how do we enable focus to this text area using a single tab instead of using 2 tabs currently. Please help.

The known issue states that to set focus into a rich text field from any other field, we must press tab twice. How to overcome this issue.

Regards,
Naren.

tab to toolbar

I think it's currently designed such that one tab takes you to the toolbar and then another tab takes you to the editor, which was done to be consistent with usability and a11y guidelines. Once inside the toolbar or the editor, you can navigate within those widgets using the keyboard, and screen readers use the focus as context to relay state to the user.

How to make the dijit.editor support spell check

Hi,
Maybe this question is silly, but I am wondering whether some one can give me some helpful advise.
I downloaded the dojo 1.0 build in my PC and installed it to my apache server. I can see that dijit.editor widget in the mail demo supports the spell check feature very well. However I can not make the spell check work in my own widget with the dijit.editor widget.
And also, the online editor widget dose not support this feature both in FF2 and IE7.
Is there something should be paid more attention here to support the spell check?

Thanks
- Bruce