Widget JavaScript file
A widget JavaScript (.js) file contains specific JavaScript code that implements a widget as an element of the user interface. This page shows examples of how to extend existing widgets and implement changes by registering them as new widget classes.
The widget JavaScript (.js) files contain functions for rendering the widget template file (.tpl.html) and dynamically building the DOM element. To customize a widget, you need to extend the standard widget class in a new widget .js file contained in your customization project directory.
The widget JavaScript (.js) file is associated with a template
file. If the widget JavaScript (.js) file and the template file are in the same
directory and have the same name (for example, MyEditWidget.js and
MyEditWidget.tpl.html), they are associated automatically. If the template file
does not have the same name as the widget JavaScript (.js) file, you can
associate them by setting the __templateName
value in the .js
file.
Simple widget
This sample code shows the minimal code you need to extend a simple widget in JavaScript:
"use strict";
modulum('newWidget', ['baseWidget', 'WidgetFactory'],
function(context, cls) {
cls.newWidget = context.oo.Class(cls.baseWidget, function($super) {
return {
__name: "newWidget",
__templateName: "newTemplate",
/* your custom code */
};
});
cls.WidgetFactory.registerBuilder(parentSelector nodeSelector, cls.newWidget);
});
where:
newWidget
is your custom widget.baseWidget
is the built-in widget that it extends.newTemplate
(optional) is the template file to associate with the widget. If the .tpl.html file has the same name as the .js file, you do not need to specify the template name.parentSelector
(optional) designates one of the targeted node's ancestors.nodeSelector
designates the targeted node.parentSelector
andnodeSelector
are both types of selector. A selector takes the following format:nodeName.4stStyleName [4stAttribute=value] ...
nodeName
is the AUI node name. It is optional.4stStyleName
is the AUI node style name. It is mandatory ifnodeName
is omitted but optional ifnodeName
is present. If4stStyleName
is omitted, the leading dot is also omitted.[4stAttribute=value]...
is a list of zero to N items. For each item in the list:4stAttribute
is the name of an attribute belonging to one of the Genero presentation styles of this node.value
is the targeted value for this Genero presentation style attribute.
In most cases, you would use the simplest form of the
cls.WidgetFactory.registerBuilder
function:
cls.WidgetFactory.registerBuilder(nodeName, cls.newWidget)
However, you would specify extra parameters when you want to provide a widget that responds to an object that uses a specific Genero presentation style and Genero presentation style attribute.
Example 1:
cls.WidgetFactory.registerBuilder('Stack Group', cls.StackGroupWidget);
The StackGroupWidget is used for the Group AUINode if one of its ancestors is Stack AUINode.
Example 2:
cls.WidgetFactory.registerBuilder("CheckBox[customWidget=toggleButton]", cls.MyToggleButtonWidget);
The MyToggleButtonWidget
is used for any CheckBox AUINode where the form object
(the CheckBox) specifies the Genero presentation style attribute customWidget
with
the value toggleButton
.
Container widget
For container widget customization, you can set a file gbc-project-dir/customization/customization-project-dir/js/myComposedWidget.js:
"use strict";
modulum('MyComposedWidget', ['WidgetGroupBase', 'WidgetFactory'],
function(context, cls) {
cls.MyComposedWidget = context.oo.Class(cls.WidgetGroupBase, function($super) {
/** @lends classes.MyComposedWidget.prototype */
return {
__name: "MyComposedWidget",
_label: null,
_edit: null,
constructor: function() {
$super.constructor.call(this);
this._label = cls.WidgetFactory.createWidget('Label');
this._edit = cls.WidgetFactory.createWidget('Edit');
this.addChildWidget(this._label);
this.addChildWidget(this._edit);
},
[...]
destroy: function() {
this.removeChildWidget(this._label);
this.removeChildWidget(this._edit);
this._label.destroy();
this._label = null;
this._edit.destroy();
this._edit = null;
$super.destroy();
},
[...]
};
});
cls.WidgetFactory.registerBuilder('MyComposed', cls.MyComposedWidget);
});
For a Container widget, the root base widget is always
WidgetGroupBase
. You add the child elements with
this.addChildWidget
and remove child elements with
this.removeChildWidget
.