Bitrix Site Manager

Adding custom toolbars

The visual editor user interface can be easily enriched with custom user defined controls. Using the visual editor API, you can create and dock (or float) your own bars, and add controls to the bar that can perform virtually any function. Adding a custom bar requires that you:

  1. declare the custom bar class;
  2. add the bar by calling addTaskBar of the oBXEditorUtils global object.

Declaring the custom bar class

You have to strictly follow to JavaScript class declaration rules when developing the custom bar class. Bear in mind that JavaScript does not implement the concept of class; hence, you will have to use a special syntax of JavaScript functions to declare pseudo classes.

The simplest way to create classes in JavaScript is using the syntax of functional literals to declare class methods as properties of the prototype object.

To interact with the visual editor API, you can use the following approaches and features in your class:

A standard event handler is a method that is bound to an event which is raised when a user or system performs an action that can be processed by the class. With the concept of events, you can create interactive code that responds to environmental occurrences.

Standard event handlers

Handler Description
OnTaskbarCreate Called when the taskbar is being created. Override this method to prepare the taskbar for display and perform any needed initialization.
OnTaskbarRemove Called to inform the object that it is being removed. Can be used to free memory, and to detect memory leaks.
OnElementDragEnd(object oElement) Fires when a drag operation is ended. The operation may have been initiated from a list formed by the toolbar creation methods (parent class). The oElement parameter references an instance of BXNodeElement, which inherits properties of a DOM node and allows to uniquely identify it.
UnParseElement(object oElement) Called when the editor switches from the visual mode to the source code or split mode. The oElement parameter have the same meaning as with OnElementDragEnd.

The handler is to return a string containing the code with which the source element is to be replaced, or false if no replacement is required.

Important! This handler is called for every irregular visual element. You will have to verify the __bxtagname attribute to identify the required element. For example:

CustomTaskbar.prototype.UnParseElement = function(node)
{
    if (node.arAttributes["__bxtagname"] == '__customtag1')
        return '<?MyPHPFunction(0)?>'
    if (node.arAttributes["__bxtagname"] == '__customtag1')
        return '<?MyPHPFunction(1)?>'
    if (node.arAttributes["__bxtagname"] == '__customtag2')
        return '<?MyPHPFunction(2)?>'

    return false;
}

Properties and methods of the parent class

To use properties or call methods of the parent class in the custom bar class handler, define a function scope variable and set it to this. Make all further calls on the methods and access properties of the parent class on this variable.

Example

function CustomTaskbar()
{
    var oTaskbar = this;
    CustomTaskbar.prototype.OnTaskbarCreate = function ()
    {
        var pDataCell = oTaskbar.CreateScrollableArea(oTaskbar.pDataCell);
        //......
    }
    //....
}

Parent class properties

Property Description
pDataCell Area in the taskbar where the interface can be created.

Parent class methods

Method Description
object
CreateScrollableArea(
  object nodeElement
);
Creates a scrollable area inside the DOM node nodeElement, and returns a reference to the area (DOM node).
bool
DisplayElementList(
  array arElements,
  object oCont
);
Takes an array of control description data, creates a common set of controls and attaches it to the container oCont, which is the DOM node object. Returns true on success or false otherwise. oCont must not contain elements other than the list.

arElements is an indexed array; each of its element is an associated array having the following structure:
Index Description
string name The element.
string title The display name (title) of the element.
string tagname Tag name. Used to display data in the property bar, as well as to handle the element when switching to the code view mode.
string icon Path to the image to be displayed in the list.
bool isGroup true if the element is a group; false otherwise;
array params Array of parameters (associated and nested arrays supported).
array childElements For group elements (isGroup). Each element is an array whose elements have the structure described in this table.

You will find an example of creation of elements below.

Currently, 2-level nesting (childElements) is supported for this structure.
bool
RemoveElementList(
  object oCont
);
Deletes elements from oCont. Returns true on success or false otherwise.
bool
AddElement(
  array oElement,
  object oCont,
  [string sPath],
  [int orderInd]
);
Adds an element to the list.
  • oElement - element descriptor array (see the description for DisplayElementList);
  • oCont - element container;
  • sPath - (optinal): defines the nesting level of the element. Contains names of parent groups separated with comma. If omitted, the top level is used;
  • orderInd - (optinal): defines the element order (z-index) within the level specified in sPath. -1 appends the element to the end.
    Returns true on success or false otherwise.
bool
RemoveElement(

  string elName,
  object oCont,
  [string sPath]
);
Deletes an element elName from oCont.

sPath
- see AddElement for description.

Returns true on success or false otherwise.

Other API methods

In addition to the described parent class methods, you can use other methods of the visual editor API which cover common programming tasks.

Adding taskbar element handler

You can install a property bar handler if you need to display and edit properties of custom elements. To add a property bar handler, call addPropertyBarHandler.

Adding a taskbar

To install a previously declared taskbar, call addTaskBar on oBXEditorUtils. You will find the detailed description of its parameters in the addTaskBar topic.

Example of a custom taskbar


<script>

function CustomTaskbar()
{
    var pDataCell;
    var oTaskbar = this;

    CustomTaskbar.prototype.OnTaskbarCreate = function ()
    {
        // Create scrollable area
        pDataCell = oTaskbar.CreateScrollableArea(oTaskbar.pDataCell);
        // install taskbar handler for "_customtag2"
        oBXEditorUtils.addPropertyBarHandler('_customtag2',this.ShowProperties);
        // Display list of elements
        this.DisplayTree();
    }

    CustomTaskbar.prototype.DisplayTree = function()
    {
        // Define the array of elements
        var arElements = [];
        var _arElement = [];
        _arElement['name'] = 'group1';
        _arElement['title'] = 'Group 1';
        _arElement['tagname'] = '';
        _arElement['icon'] = '';
        _arElement['isGroup'] = true;
        _arElement['params'] = [];
        _arElement['childElements'] = [];
            var __arElement = [];
            __arElement['name'] = 'el_1_1';
            __arElement['title'] = 'Element 1.1';
            __arElement['tagname'] = '_customtag';
            __arElement['icon'] = '/images/icon1.gif';
            __arElement['isGroup'] = false;
            __arElement['params'] = [];
            __arElement['childElements'] = [];
            _arElement['childElements'].push(__arElement);

            __arElement = [];
            __arElement['name'] = 'el_1_2';
            __arElement['title'] = 'Element 1.2';
            __arElement['tagname'] = '_customtag2';
            __arElement['icon'] = '/images/icon2.gif';
            __arElement['isGroup'] = false;

                ___arPar = [];
                ___arPar[0] = {name:'param0',title:'Параметр0',value:'value0'};
                ___arPar[1] = {name:'param1',title:'Параметр1',value:'value1'};
                ___arPar[2] = {name:'param2',title:'Параметр2',value:'value2'};
            __arElement['params'] = ___arPar;
            __arElement['childElements'] = [];

            _arElement['childElements'].push(__arElement);

        arElements.push(_arElement);

        _arElement = [];
        _arElement['name'] = 'el_2';
        _arElement['title'] = 'Element 2';
        _arElement['tagname'] = '_customtag';
        _arElement['icon'] = '/images/icon3.gif';
        _arElement['params'] = [];
        _arElement['isGroup'] = false;
        _arElement['childElements'] = [];
        arElements.push(_arElement);

        // Add elements to the scrollable area
        oTaskbar.DisplayElementList(arElements,pDataCell);
    }

    // Property handler for _customtag2
    CustomTaskbar.prototype.ShowProperties = function(_bNew, _pTaskbar, _pElement)
    {
        // _pTaskbar.pCellProps - scrollable area
        var arParams = oBXEditorUtils.getCustomNodeParams(_pElement);
        var _input,_div;
        var __saveParams = function(e)
        {
            for (var _i=0; _i<arParams.length;_i++)
            {
                _input = document.getElementById('__param_'+arParams[_i].name);
                arParams[_i].value = _input.value;
            }

            //oBXEditorUtils.setCustomNodeParams(_pElement,arParams);
        }

        if (_bNew)
        {
            oBXEditorUtils.BXRemoveAllChild(_pTaskbar.pCellProps);
            for (var _i=0;_i<arParams.length;_i++)
            {
                _input = document.createElement('INPUT');
                _input.type = 'text';
                _input.id = '__param_'+arParams[_i].name;
                _input.value = arParams[_i].value;
                _input.onblur = __saveParams;

                _div = document.createElement('DIV');
                _div.id = '__vd_'+arParams[_i].name;
                _div.innerHTML = arParams[_i].title;
                _div.appendChild(_input);
                _pTaskbar.pCellProps.appendChild(_div);
            }
        }
        else
        {
            for (var _i=0;_i<arParams.length;_i++)
            {
                _input = document.createElement('INPUT');
                _input.type = 'text';
                _input.id = '__param_'+arParams[_i].name;
                _input.value = arParams[_i].value;
                _input.onblur = __saveParams;

                _div = document.getElementById('__vd_'+arParams[_i].name);
                _div.innerHTML = arParams[_i].title;
                _div.appendChild(_input);
            }
        }
    }

    CustomTaskbar.prototype.UnParseElement = function(node)
    {
        if (node.arAttributes["__bxtagname"] == '_customtag')
            return '<?SomeSuperFunction(3)?>'
        if (node.arAttributes["__bxtagname"] == '_customtag2')
            return '<?SomeSuperFunction(1)?>'

        return false;
    }

    CustomTaskbar.prototype.OnElementDragEnd = function(oEl)
    {
        if (oEl.getAttribute('__bxtagname') == '_customtag')
        {
            oEl.parentNode.removeChild(oEl);
            oTaskbar.insertHTML('snippet');
            alert('Element _customtag was added');
        }
        else if(oEl.getAttribute('__bxtagname') == '_customtag2')
            alert('Element _customtag2 was added');

    }
}

// Now, install the declared taskbar
oBXEditorUtils.addTaskBar('CustomTaskbar',2,"Help",[]);

</script>