יונ22
Written by:
ronen ariely
22/06/2013 19:54 
Adding RTL/LTR buttons to Telerik Editor on DotNetNuke System
1. Adding the buttons to VIEW by adding them to buttons list
1.1. Open the file: [portel]\Providers\HtmlEditorProviders\Telerik\Config\ToolsDefault.xml
1.2. Add new buttons section inside the root node:
<
tools
name
=
"Ariely Tools"
>
* this will add to the HTML:
<
ul
class
=
"reToolbar Vista"
onmousedown
=
"return false;"
>
it is important to understand this since in this location we can find the data for further work. For example, we can see that at the moment we are working under the
main Toolbar CSS class called
reToolbar and we are working with the skinName of the
Vista.
1.3. Add the buttons that you need, and configure the look and feel of the buttons using the build in attributes.
we will add 4 new buttons:
<
tool
name
=
"ArielyLTR"
/>
<
tool
name
=
"ArielyRTL"
/>
<
tool
name
=
"ArielyRTL_NewParagraph"
/>
<
tool
name
=
"ArielyRTL_NewParagraph"
/>
* For each button this will add to the HTML
<li> with a Link Tag inside.
* The name attribute will use as
commandName for the Telerik Editor
2. Add CSS Style to our buttons (add icon image)
in this section we will use the data from 1.2 and 1.3 to add a css style to our buttons.
* The iconUrl property is not supported by RadEditor for ASP.NET AJAX because it has "new" (several years old) toolbar architecture based on image sprites.
To set an image to a custom tool you should provide image files for it and declare the following CSS class:
<style>
.<main Toolbar CSS class>.<skinName> .<commandName>
{
background-image
:
url
(MyImage.gif);
}
</style>
2.1. We can use the site style editor and add the next code there or add it to the Telerik EditorOverride.css file. In our case we need to add those styles to the site style sheet.
* I am using the FCK Editor image that comes with the DotNetNuke. As FCK Editor Come with RTL/LTR support build in I have the buttons image there.
.reToolbar.Vista .ArielyRTL
{
background-image
:
url
(
'//Providers/HtmlEditorProviders/Fck/fckeditor/editor/skins/office2003/fck_strip.gif'
);
background-position
:
center
-1069px
;
}
.reToolbar.Vista .ArielyLTR
{
background-image
:
url
(
'//Providers/HtmlEditorProviders/Fck/fckeditor/editor/skins/office2003/fck_strip.gif'
);
background-position
:
center
-1056px
;
}
.reToolbar.Vista .ArielyRTL_NewParagraph
{
background-image
:
url
(
'//Providers/HtmlEditorProviders/Fck/fckeditor/editor/skins/office2003/fck_strip.gif'
);
background-position
:
center
-1069px
;
}
.reToolbar.Vista .ArielyLTR_NewParagraph
{
background-image
:
url
(
'//Providers/HtmlEditorProviders/Fck/fckeditor/editor/skins/office2003/fck_strip.gif'
);
background-position
:
center
-1056px
;
}
2.1.1. EditorOverride.css file locate at:
[portel]\Providers\HtmlEditorProviders\Telerik\EditorOverride.css
2.1.2. Using the site administration interfase:
open ADMIN -> Site Settings -> Stylesheet Editor
add the code above.
* IMPORTANT! Try to use CSS SPRIT and not an image for each button that you want to enter. In this section I only showed a basic example of how to add CSS style to our new button.
3. Adding language support
Telerik Aditor has build in language support using RES's files.
3.1. Open the main RES file (english):
[portel]\Providers\HtmlEditorProviders\Telerik\App_LocalResources\RadEditor.Tools.resx
* you can use the Visual Studio editor or just open it using Notepad. I will show the notepad way
3.1.1. Add the code:
<
data
name
=
"ArielyLTR"
xml:space
=
"preserve"
>
<
value
>Left To Right</
value
>
</
data
>
<
data
name
=
"ArielyRTL"
xml:space
=
"preserve"
>
<
value
>Right To Left</
value
>
</
data
>
<
data
name
=
"ArielyLTR_ NewParagraph"
xml:space
=
"preserve"
>
<
value
>Add Left To Right Paragraph</
value
>
</
data
>
<
data
name
=
"ArielyRTL_ NewParagraph "
xml:space
=
"preserve"
>
<
value
>Add Right To Left Paragraph</
value
>
</
data
>
3.2. Open the Hebrew RES file (and do the same for each language that you need support to):
[portel]\Providers\HtmlEditorProviders\Telerik\App_LocalResources\ RadEditor.Tools.he-IL.resx
* again you can use the Visual Studio editor or just open it using Notepad. I will show the notepad way
3.2.1. Add the code:
<
data
name
=
"ArielyLTR"
xml:space
=
"preserve"
>
<
value
>שמאל לימין</
value
>
</
data
>
<
data
name
=
"ArielyRTL"
xml:space
=
"preserve"
>
<
value
>ימין לשמאל</
value
>
</
data
>
<
data
name
=
"ArielyLTR_ NewParagraph"
xml:space
=
"preserve"
>
<
value
>הוסף פסקה משמאל לימין</
value
>
</
data
>
<
data
name
=
"ArielyRTL_ NewParagraph "
xml:space
=
"preserve"
>
<
value
>הוסף פסקה מימין לשמאל</
value
>
</
data
>
4. Adding the JavaScript for the buttons
this is the main work you should do. I will give an example of my JS. But this is where you need to use your insights and adapt the code to the system where you want to integrate the buttons.
4.1. Open the Telerik's JS file:
[portel]\Providers\HtmlEditorProviders\Telerik\js\RegisterDialogs.js
* for each button we need to bind a command to the CommandList and write a function for the event. This is done using a code block like this:
Telerik.Web.UI.Editor.CommandList["<commandName>"] = function (commandName, editor, args){
// here we can insert our JS code
}
4.1.1. Add the JS code:
Before we start the buttons code we need a helper function. In my real code I have several helper functions for different use like for button that open a dialog page and so on. The only function that I will use here is the " ArielyFindFirstDivPFather". This function will find the first father element of type P or DIV.
Then we can build 4 functions for each button. We will see why I prefer to use 4 buttons and not 2 as in other desktop application if you try and use them or just read the code. This is the whole clean JS (after remove as much as I can to make the function readable and simple to understand) ready for copy and paste:
/*********************************************************************
** developed by Ronen Ariely
** Adding Scripts for RTL?LTR buttons
******************************************************************** */
/* ------------------------------------------------------ Start Helper Functions */
function
FindFirstDivPFather(el)
{
var
_t = el;
if
((_t.tagName.toLowerCase() ==
'div'
) || (_t.tagName.toLowerCase() ==
'p'
) )
{
return
_t;
}
while
(_t.parentElement) {
_t = _t.parentElement;
//_t = _t.parentNode;
if
((_t.tagName.toLowerCase() ==
'div'
) || (_t.tagName.toLowerCase() ==
'p'
) )
{
return
_t;
}
}
return
null
;
}
/* ------------------------------------------------------ End Helper Functions */
/* ------------------------------------------------------ Start Buttons Functions & events binding */
Telerik.Web.UI.Editor.CommandList[
"ArielyLTR_NewParagraph"
] =
function
(commandName, editor, args)
{
editor.pasteHtml(
'<div style="direction:ltr;text-align: left;">insert text</div>'
);
}
Telerik.Web.UI.Editor.CommandList[
"ArielyRTL_NewParagraph"
] =
function
(commandName, editor, args)
{
editor.pasteHtml(
'<div style="direction:rtl;text-align: right;">הכנס טקסט</div>'
);
}
Telerik.Web.UI.Editor.CommandList[
"ArielyRTL"
] =
function
(commandName, editor, args)
{
var
selection = editor.getSelection();
var
selectedHTML = selection.getHtml();
var
elem = editor.getSelectedElement();
//returns the selected element.
if
(elem ==
null
) {}
else
{
var
Father_Div_P = FindFirstDivPFather(elem);
if
(Father_Div_P)
{
Father_Div_P.style[
"text-align"
] =
"right"
;
Father_Div_P.setAttribute(
"align"
,
"right"
);
// for FireFox
Father_Div_P.style[
"direction"
] =
"rtl"
;
//RemoveClass("ArielyClassLTR",Father_Div_P);
//AddClass("ArielyClassRTL",Father_Div_P);
}
else
{
elem.innerHTML =
'<div style="text-align: right; direction: rtl;">'
+ elem.innerHTML +
'</div>'
;
//editor.pasteHtml('<div style="direction:rtl;text-align: right;">' + selectedHTML + '</div>');
}
}
};
Telerik.Web.UI.Editor.CommandList[
"ArielyLTR"
] =
function
(commandName, editor, args)
{
var
selection = editor.getSelection();
var
selectedHTML = selection.getHtml();
var
elem = editor.getSelectedElement();
//returns the selected element.
if
(elem ==
null
) {}
else
{
var
Father_Div_P = FindFirstDivPFather(elem);
if
(Father_Div_P)
{
Father_Div_P.style[
"text-align"
] =
"left"
;
Father_Div_P.setAttribute(
"align"
,
"left"
);
// for FireFox
Father_Div_P.style[
"direction"
] =
"ltr"
;
//AddClass("ArielyClassLTR",Father_Div_P);
//RemoveClass("ArielyClassRTL",Father_Div_P);
}
else
{
elem.innerHTML =
'<div style="text-align: left; direction: ltr;">'
+ elem.innerHTML +
'</div>'
;
//editor.pasteHtml('<div style="direction:ltr;text-align: left;">' + selectedHTML + '</div>');
}
}
};
/* ------------------------------------------------------ End Buttons Functions & events binding */
/*********************************************************************
** developed by Ronen Ariely
** Adding Scripts for RTL?LTR buttons
******************************************************************** */
* We can make a different button for inline text that people mark. I decided that is a person mark a part of a text in a paragraph then the whole paragraph will get RTL/LTR attribute. This is how most of the application including Gmail, Microsoft Office and so on. But some time we need to wrap only part of the sentence with RTL/LTR. If you need this ability then your code can become much simpler. All you need is to use this code:
editor.pasteHtml(
'<span style="direction:rtl;">הכנס טקסט</span>'
);
In my applications I use a bit more complex code which check come more situations and bring back some different behaviors, but this is full working code for copy and paste at your system.
I hope the reading was fun and this is useful for you,
Have fun,
Ronen Ariely
* We can use CSS CLASS for the RTL, and ad/remove the class in the JS. In this case we need to add the class to the skin.css file since the Editor is working in iframe that use this CSS file and it is not use EditorOverride.css.
[portel]/Portals/_default/Skins/MinimalExtropy/skin.css
.ArielyClassLTR{
direction
:
rtl
;
text-align
:
right
;}
.ArielyClassLTR{
direction
:
ltr
;
text-align
:
left
;}
RemoveClass(
"ArielyClassLTR"
,Father_Div_P);
AddClass(
"ArielyClassRTL"
,Father_Div_P);
function
AddClass( classname, element ) {
var
cn = element.className;
//test for existance
if
( cn.indexOf( classname ) != -1 ) {
return
;
}
//add a space if the element already has class
if
( cn !=
''
) {
classname =
' '
+classname;
}
element.className = cn+classname;
}
function
RemoveClass( classname, element ) {
var
cn = element.className;
var
rxp =
new
RegExp(
"\\s?\\b"
+classname+
"\\b"
,
"g"
);
cn = cn.replace( rxp,
''
);
element.className = cn;
}
You can read more on using the Telerik Editor here:
http://www.telerik.com/help/aspnet-ajax/editor-getselection.html