Back to vBulletin 3 Articles

Javascript VBulletin Editor Toolbar Controls Framework
by FractalizeR 09 Sep 2008

Intro

Writting VBulletin addons, especially those, related to BBCodes extending, I always had difficulties with adding BBCode buttons to editor toolbar. Standard way is too limited: you cannot select which editor to add buttons to, you cannot choose to what line to add these buttons, you cannot create a new toolbar for them… Adding buttons to AJAX-produced editor windows causes troubles… You are TOO limited…

Thinking about the solution I tried to do that via plugins and didn’t come to any acceptable solution. I always care about my code beauty so I am strongly against modifying VBulletin PHP code (because that makes updating VBulletin complicated for user. Each new update vanishes your code hacks).

The solution I suggest is DHTML way. I have written a small frawework to control editor toolbar. Let me first consider it from the surface (developer article will come in the future, but framework's source code is all commented and (I beleive) easily understandable).

Offtopic: you know, with all the power http://www.jquery.com gives to you why to bother modifying your code via template hooks or via actual template modification if you can do that in one line of code with jQuery by DHTML? It's a question...

Using EditorToolbarFramework

Framework consists of:
  • Core (core.js) and
  • Controls (so far button.js, separator.js and panel.js)
In order to start using it you need to add the following code to any plugin, that is executed before content rendering. My favourite is editor_toolbar_start. By executing the following code inside a plugin we are attaching our scripts to page HEAD to be sure they will be loaded before page contents.

Code:
//Injecting scripts
$GLOBALS['headinclude'].='
<script src="clientscript/fractalizer/jquery.js"></script>
<script src="clientscript/fractalizer/editorbtnframework/core.js"></script>
<script src="clientscript/fractalizer/editorbtnframework/core.js"></script>
<script src="clientscript/fractalizer/editorbtnframework/button.js"></script>
<script src="clientscript/fractalizer/editorbtnframework/separator.js"></script>
<script src="clientscript/fractalizer/editorbtnframework/panel.js"></script>
<script src="clientscript/fractalizer/test.js"></script>
';
You need to include jquery.js and core.js. jquery.js contains compressed image of wonderful DHTML and AJAX library named http://www.jquery.com. core.js contains core services of my framework. All others are optional. If you plan to use buttons or add new panels to editor, include corresponding js files. If not - leave them. The last one - test.js is our script in which we will actually manipulate editor toolbar. Let’s have a look at it now.

Code:
myBtn = new FRVBEditorCommandButton("TestBTN", "FRControlsPanel_0_LeftEdge", "images/editor/attach.gif", function(){alert("TEST!!!")});
myBtn.tooltip = "MyButton!";
mySep = new FRVBEditorSeparator("TestSep", "TestBTN");
myPanel = new FRVBEditorPanel("TestPanel", "FRControlsPanel_0");
FRVBEM.registerControl(myBtn);
FRVBEM.registerControl(mySep);
FRVBEM.registerControl(myPanel);
Each control, located at the toolbar has:
  • a name
  • associated control relative to which it’s position is determined,
  • position (before or after) it should be placed at relative to that control
  • processing order (to setup in which order controls appear on toolbar relative to each other)
  • script restriction (to restrict toolbar to be shown only in showthread.php for example)
  • editor-type restriction (e.g. appear only in QuickReply editor or only in AJAXed QuickEdit)

At the first line we create FRVBEditorCommandButton object which is just a clickable toolbar button. We call it “TestBTN“. We set it up to be relative to predefined “FRControlsPanel_0_LeftEdge” button. This is autocreated hidden button, that is located at the left of the first (0-index) editor panel. Bu default position is set to “after”, so our button will be located just after this invisible button, e.g. at the left side of the panel. We also provide an image for this button and onclick handler for button, that just shows us a simple message. At the next line we set up button tooltip and left all other things by default.

After that we create a separator between buttons. It also has a name and location set. It will be located just after our just created button.

With the next line we create a new toolbar panel for buttons. We call it “TestPanel” and set it up to be located just after the first standard VBulletin toolbar. On single line editors panel will be added, on double-lined will be inserted after the first standard panel.

And at last we just register all objects we created in FRVBEM object to be displayed in every editor including AJAX-produced.

That’s all. As soon as document DOM will be ready, FractalizeR’s VBulletin Editor Manager will start working for you integrating buttons into all editors in realtime.
Some more details…

Locations to choose from

While we create controls we have to choose their position. We have the following choice:
  • FRControlsPanel_0_LeftEdge - left edge of the first VBulltin standard toolbar
  • FRControlsPanel_0_RightEdge - right edge of the first VBulltin standard toolbar
  • FRControlsPanel_1_LeftEdge - left edge of the first VBulltin standard toolbar. Please note, that this panel does not exist in all editors.
  • FRControlsPanel_1_RightEdge - right edge of the first VBulltin standard toolbar. Please note, that this panel does not exist in all editors.
  • FRControlsPanel_XXX_LeftEdge - left edge of the panel XXX we (or somebody else’s addon) created
  • FRControlsPanel_XXX_RightEdge - right edge of the panel XXX we (or somebody else’s addon) created
  • Standard existing VBulletin buttons: cmd_removeformat, popup_fontname, popup_fontsize, popup_forecolor, popup_smilie, popup_attach, cmd_undo, cmd_redo, cmd_switchmode, cmd_bold, cmd_italic, cmd_underline, cmd_justifyleft, cmd_justifycenter, cmd_justifyright, cmd_insertorderedlist, cmd_insertunorderedlist, cmd_outdent, cmd_indent, cmd_createlink, cmd_unlink, cmd_email, cmd_insertimage, cmd_wrap0_quote, cmd_wrap0_code, cmd_wrap0_html, cmd_wrap0_php

Please note, that if control we are positioning our one relative to does not exist, our button will not appear and you will have a warning visible in FireBug console.
Editor types to locate buttons in

Going back to our previous example, we can position our button in:
  • myBtn.editor = [FRVBEM.editorType.quickReply] - only in QuickReply editors (generally, they are displayed only at the bottom of showthread.php
  • myBtn.editor = [FRVBEM.editorType.quickEdit] - only in QuickEdit editors (they are displayed when we edit our post just-in-place, pressing Edit button at the bottom of a particular post in the thread displayed. This editor is shown, of course, only on AJAX-capable browsers).
  • myBtn.editor = [FRVBEM.editorType.quickEdit] - only in full-featured editors like one appears when we press Go advanced in any Quick editor.
  • myBtn.editor = [FRVBEM.editorType.quickReply, FRVBEM.editorType.quickEdit] - in BOTH quickReply AND quickEdit editors.
  • ………………..

We can make any combinations of these three.

Control orientation

We may want to locate our button

Code:
myBtn.controlOrientation = FRVBEM.controlOrientations.after - after related control. This is the default orientation button gets after it is created. No need to set it up manually
myBtn.controlOrientation = FRVBEM.controlOrientations.before - or before it
By-script restriction

By default buttons are shown in any script. But, for example, you can restrict them to only certain scripts, so that extended buttons would not appear in blogs or any other add-on. Just set
  • myBtn.byScriptRestriction = ["showthread", "newreply"] - allowed scripts for buttons to appear only in showthread and newreply scripts.

By default this restriction is - myBtn.byScriptRestriction = []; - turned off.
Processing order

If we position our new button relative to another button we created, in order to all work correctly, that migt be necessary to setup processing order. The independent button must have lowest processing order possible, the dependent one should get highest. Order values should start from 0. -1 is reserved as a default value for all newly created buttons, -2 for all newly created panels (so that that would be created before all buttons).
  • myBtn.processingOrder = 5;

CommandButton onClick handler

Each command button have it’s associated onClick handler. From this handler you can access methods of vB_Editor object, that will help you manipulate the text in this editor.

Code:
 myBtn = new FRVBEditorCommandButton("TestBTN", "FRControlsPanel_0_LeftEdge",
"images/editor/attach.gif", function() {
  event.data.editor.write_editor_contents("We replaced that text with this one!", false);
});
event.data.editor object is actually a vB_Editor instance, which definition resides at clientscript/vbulletin_textedit.js file (before inspecting it’s contents don’t forget to download VBulletin version with scripts uncompressed!).

Let’s look at the most common methods of this object (class?):
  • get_editor_contents() - returns the HTML contents of the editor
  • write_editor_contents(textToSet, doInit) - replaces editor HTML contents with the text we provide. doInit parameter should always be false.
  • get_selection() - returns the text, that is selected inside the editor. Returns en empty string, when no text is selected.
  • insert_text(textToInsert, moveStart, moveEnd) - inserts a text into editor at the position of cursor. If there is any text selected at the moment, selection is replaced by the inserting text. moveStart and moveEnd usually equals false.
  • wrap_tags(tagName, useOption, selection) - function wraps current selection with the tag with the specified name. If useOption is used, user will be asked for an option for this tag. For example: editor.wrap_tags(”CODE”, true);

VBulletin code, even JS code is pretty straightforward. So, just open vbulletin_textedit.js and find there all you want!

That’s all folks! Pretty easy, isn’t it?

P.S. I am not sure I will continue to work on this project because of VBulletin 4 release announced with heavily changed API. But I strongly believe this project will be interesting to most of VBulletin developers at least as a compex Javascript programming for VBulletin.


You are free to take this and to modify this and redistribute this in any way, but, please make me credited in all derived works and works, that use my library. Thank you.

This article is also published at my site here: http://www.fractalizer.ru/frpost_3/vbulletin-fractalizers-editor-toolbar-controls-framework/

In the attachment you will also find sample VBulletin product to create new panels at the editor. Please note, that a panel will not be shown until you add some controls to it (what is actually you need to do manually).
Attached Files
File Type: xml product-fr_vbempanels.xml (4.3 KB, 44 views)
File Type: zip editortoolbarframework_0.9Preview.zip (20.5 KB, 78 views)

vblts.ru supports vBulletin®, 2022-2024