Go Back   vb.org Archive > vBulletin Article Depository > Read An Article > vBulletin 3 Articles
Javascript VBulletin Editor Toolbar Controls Framework
FractalizeR's Avatar
FractalizeR
Join Date: Oct 2005
Posts: 368

 

Russia, Moscow
Show Printable Version Email this Page Subscription
FractalizeR FractalizeR is offline 09-08-2008, 10:00 PM

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 jQuery 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 jQuery. 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/v...ols-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, 42 views)
File Type: zip editortoolbarframework_0.9Preview.zip (20.5 KB, 76 views)
Reply With Quote
  #2  
Old 09-11-2008, 08:53 AM
FractalizeR's Avatar
FractalizeR FractalizeR is offline
 
Join Date: Oct 2005
Location: Russia, Moscow
Posts: 368
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

This article is probably in a wrong section. It relates to programming, not to general VBUlletin use
Reply With Quote
  #3  
Old 04-14-2009, 09:53 PM
pein87's Avatar
pein87 pein87 is offline
 
Join Date: Sep 2008
Posts: 352
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Thanks I`ll take a peek at it after class is over.
Reply With Quote
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 12:00 AM.


Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.08512 seconds
  • Memory Usage 2,242KB
  • Queries Executed 19 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)ad_showthread_beforeqr
  • (4)bbcode_code
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)modsystem_article
  • (1)navbar
  • (4)navbar_link
  • (120)option
  • (3)post_thanks_box
  • (3)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (3)post_thanks_postbit_info
  • (2)postbit
  • (2)postbit_attachment
  • (3)postbit_onlinestatus
  • (3)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available:
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files:
  • ./showthread.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_postinfo_query
  • fetch_postinfo
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showthread_start
  • showthread_getinfo
  • forumjump
  • showthread_post_start
  • showthread_query_postids
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • fetch_musername
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_attachment
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete