My goal is to be able to click on a toolbar button and have a modal dialog box with a lightbox effect appear. The contents of the dialog is a custom search result where individual result items can be selected, causing the dialog to close and inserting a link to that item in the rich text edit.
Create a New Plugin
Since writing code from scratch is tedious (I am impatient) I always prefer to start with something that works and then modify it to meet my needs. In this case I've taken the plugin named factory\dojo\dijit\_editor\plugins\ToggleDir.js since it's nice and short, and re-purposed it to create a modal popup window when clicked. I'm going to copy it into a new file named SearchPopup.js.dojo.provide("dijit._editor.plugins.SearchPopup"); dojo.require("dijit._editor._Plugin"); dojo.declare("dijit._editor.plugins.SearchPopup", dijit._editor._Plugin, { // summary: // This plugin provides a popup window to search and select content // // description: // The commands provided by this plugin are: _initButton: function(){ // summary: // This is the button that will appear on the toolbar this.button = new dijit.form.Button({ label: "Search and add content", showLabel: false, iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "CreateLink", tabIndex: "-1", onClick: dojo.hitch(this, function(){popupSearch()}) }); } } ); // Register this plugin. dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){ if(o.plugin){ return; } switch(o.args.name){ case "searchPopup": o.plugin = new dijit._editor.plugins.SearchPopup(); } });
This is probably the most basic plugin that can be created. All it does is invoke a javascript function named popupSearch() when the button is clicked:
onClick: dojo.hitch(this, function(){popupSearch()})
The code to pick an icon is a little tricky, it refers to factory\dojo\dijit\themes\tundra\images\editor.gif which is an image containing a long strip of icons like this:
and finally the iconClass can be tracked down in factory\dojo\dijit\themes\tundra\Editor.css:
Code: iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "CreateLink", Matching CSS: .tundra .dijitEditorIconCreateLink { background-position: -90px; }
If I wanted to use my own icon I'd have to edit the icon strip and add a new image, but since I can't draw to save my life I decided to just reuse the one for creating a link. The rest of the code is just boilerplate, and we can add our newly minted plugin to the toolbar with some javascript:
dojo.addOnLoad(function(){ dojo.require("dijit._editor.plugins.SearchPopup"); var widget = dijit.byId(gcps.assessmentWidget); widget.addPlugin('searchPopup'); });
EDIT 2/14/2012: I found a pretty good developerworks article on this topic. Check it out.
This tutorial is spot on, except when I try to add this plugin the button is "disabled" by the toolbar. Have you noticed this behavior?
ReplyDeleteI haven't had any issues with the button being disabled. I took a quick look at isFocusable() in dijit._form._FormWidget.js and there seems to be some other code that could cause that symptom. Try stepping through it with chrome's debugger.....
ReplyDeleteYeah, it's very strange. Dojo runs each plugin through a piece of code which tries to enable/disable the plugin.
ReplyDeleteHere is the piece that's telling the plugin to be disabled, it comes from RichText.js:
try{
return elem.queryCommandEnabled(command);
}catch(e){
//Squelch, occurs if editor is hidden on FF 3 (and maybe others.)
return false;
}
Welp, I've figured it out. I had to add my "commandName" to the commands.js file in dijit/_editor/nls.
ReplyDeleteThanks again for your help and for the tutorial.
Ah - I'm going to take a guess that you had an indirect reference like
ReplyDeletelabel: strings["newPage"]
where I have
label: "Search and add content"
I'm glad I was able to help.
Any chance you can post a working example of this because I can't seem to get it working :(
ReplyDeleteI have tried this code to develop Dojo Rich Text Edit toolbar but I can't get it. Can you explain by video?
ReplyDeleteI'm not sure exactly why but I think you need to set the variable
ReplyDeleteuseDefaultCommand: false,
Which tells the editor that this is not a default command as described in the IBM article. Otherwise the button does not appear (working in dojo 1.6)
My working code:
dojo.declare("my.widgets.LoadQuery", dijit._editor._Plugin, {
// When you click the command button, you show a toolbar,
// instead of executing some editor commands.
useDefaultCommand: false,
_initButton: function () {
// summary:
// This is the button that will appear on the toolbar
this.button = new dijit.form.Button({
label: "This",
showLabel: false,
iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "CreateLink",
tabIndex: "-1",
onClick: dojo.hitch(this, function () {
alert('click');
})
});
}
});
// Register this plug-in so it can construct itself when the editor publishes a topic.
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin", null, function (o) {
if (!o.plugin && o.args.name.toLowerCase() === "loadquery") {
o.plugin = new my.widgets.LoadQuery();
}
});
I have been looking to extend the toolbar to add in the create link plugin for a short time now.
ReplyDelete