Using Zen Mojo Plugins
Working with Plugins
|
|
Zen Mojo
plugins are utility classes containing layout objects that provide access to several popular third-party JavaScript libraries and frameworks. Zen Mojo currently provides plugins for the Twitter Bootstrap library, the Chart.js library, the ChocolateChip-UI framework, the Dojo Toolkit, the Google Maps API, the Highcharts library, the jQuery Mobile framework, and HTML5 standard. You can also extend Zen Mojo by creating your own plugins for other third-party libraries.
This chapter discusses the following topics:
-
Overview provides a simple description of helper plugins, which define layout objects, and page manager plugins, which contain specified sets of helper plugins.
-
-
-
-
-
A Zen Mojo application consists of the following primary components:
-
one or more
template classes, which determine what is displayed on your web page
-
a set of
plugin classes, which define the layout objects used by the templates
-
the
page class, which specifies the plugin classes and other resources available to your template classes
Each documentView element must specify a single
page manager plugin, which will contain one or more
helper plugins. Each helper plugin defines a set of
layout objects. These elements perform the following functions:
-
The page manager creates a list of all layout objects defined in the specified list of helper plugins, and resolves any naming conflicts (for example, two helper plugins may define two different
button layout objects). Page managers may also provide library-specific utility functions that can be used by all layout objects associated with a given JavaScript library or framework.
-
Helper plugins define layout objects and other library-specific resources used by template classes.
When you specify a helper plugin in your page class, the layout objects defined in that helper become available to your template classes. A helper plugin may also provide additional resources, such as utility methods for common tasks.
-
A template class uses one or more layout objects to determine the appearance of your web page. A typical layout object renders a graphical element, usually by using a corresponding element in the JavaScript library. For example, a
button layout object might render itself by calling a
button function in the library.
Zen Mojo provides plugins for several popular JavaScript libraries and frameworks. When designing your Zen Mojo application, pick the helpers that you will need, and then chose a page manager that supports all of them.
The following helper plugins can be used in any application:
-
Zen Mojo
Default helper provides utility layout objects used by most helper plugins. It can be used by any page manager (not just the Default page manager).
-
HTML5 helper provides layout objects for most standard HTML5 elements.
-
Bootstrap helper provides layout objects for many of Twitter Bootstrap’s enhanced versions of HTML5 elements.
-
Chart.js helper provides layout objects for the lightweight Chart.js library.
-
Highcharts helper similar to Chart.js, but Highcharts provides a much greater variety of charts.
-
Google Maps helper provides layout objects that support an online connection to the Google Maps API.
These helper plugins can be used with any page manager.
All other helper plugins require support for a specific JavaScript library or framework, and can only be used by the page manager that provides that support. The following page managers and specialized helpers are available:
-
-
The
ChocolateChip-UI page manager supports a helper containing layout objects for the enhanced ChocolateChip-UI versions of HTML5 elements. This page manager is best for relatively simple mobile applications.
-
The
jQuery Mobile page manager supports a helper containing layout objects for the long list jQuery Mobile enhanced HTML5 elements. This page manager may be preferable for complex mobile applications.
-
The
Dojo page manager supports three helpers for three different APIs in the Dojo Toolkit. This page manager is best for complex desktop applications.
Plugins are added to your application by specifying some or all of the following items in the page class:
-
Most helper plugins depend on external JavaScript and CSS files. All required files should be located in or under
<install-dir>/csp/broker (where
<install-dir> is the is directory in which Caché is installed). Lists of installed files are specified as comma-delimited strings in the
JSINCLUDES and
CSSINCLUDES (or
CSS3INCLUDES) parameters. The following example demonstrates how to list the required files for the Bootstrap helper plugin:
Parameter JSINCLUDES As STRING = "jquery-1.11.3.min.js,bootstrap-3.3.5/js/bootstrap.min.js"
Parameter CSSINCLUDES As STRING = "bootstrap-3.3.5/css/bootstrap.min.css"
Caché assumes that
/csp/broker is the root directory for each of these paths and filenames.
The order of the
JSINCLUDES list determines the order in which the JavaScript libraries will be loaded, from left to right. In this example, the jQuery library must be loaded first because the Bootstrap library depends on it.
-
-
-
Include one or more helper plugins as child elements of the page manager plugin.
The following example shows the general structure (with optional indentation for clarity):
<mojo:documentView id="mainView" ongetlayout = "return zenPage.getContent('layout',key);">
<mojo:mojoDefaultPageManager>
<mojo:bootstrap-3.3.x-Helper/>
<mojo:mojoDefaultHelper/>
</mojo:mojoDefaultPageManager>
</mojo:documentView>
-
For each plugin or set of plugins, this book describes all page class requirements at the beginning of the relevant chapter. See the
Bootstrap chapter for the information used in the previous examples.
It is important to consider the order in which you list the helper plugins, in the case of
plugin conflict. A plugin conflict occurs when a single
documentView uses multiple helper plugins and those plugins have layout objects with the same name. A plugin conflict is not an error condition, but rather a situation that requires special handling. There is a default behavior and a way to override it.
In the case of a plugin conflict, by default, Zen Mojo uses the layout object rendering logic as given in the helper plugin that is listed
first. If you do not want the default behavior, you can modify it.
To override the default handling, do the following:
-
onresolvepluginconflicts="zenPage.onResolvePluginConflicts(zenThis, conflicts);"
In this callback, you can use the variable
conflicts, which Zen Mojo provides. This variable is an array that contains the names of layout objects defined by more than one plugin.
-
Implement the method to which your callback attribute refers. In this method, use the
setPluginMapping() method of the
documentView instance. The following shows a simple example:
ClientMethod onResolvePluginConflicts(docView, conflicts) [ Language = javascript ]
{
for (prop in conflicts) {
if (conflicts[prop].indexOf('HTML5') > -1) {
docView.setPluginMapping(prop, 'HTML5');
}
else if (conflicts[prop].indexOf('html5') > -1) {
docView.setPluginMapping(prop, 'html5');
}
}
}
For any given layout object type, your implementation can specify which helper plugin should perform the rendering for that layout object type.
Depending on the plugins you choose, your application may have to implement the
adjustContentSize() method or the
onPageShow() callback, as described in the following sections:
-
-
Implementing the onPageShow() Callback this callback method performs extra processing before the page is displayed. It is required when the Google Maps helper is used, and optional in all other cases.
ClientMethod adjustContentSize(load, width, height) [ Language = javascript ]
Where
load indicates if the page is being loaded. This argument is 1 when the page is loaded and is 0 at other times.
width and
height are the current width and height, respectively, of the
pageContents pane, in pixels.
In this method, it is typically necessary to do the following for each
documentView on this page:
-
var mainView = zen('mainView');
mainView.setSize(width, height);
where
width and
height are the desired width and height in pixels.
-
var mainDiv = mainView.getEnclosingDiv();
mainDiv.style.top = '0px';
mainDiv.style.left = '0px';
Example: Implementing adjustContentSize() for a page with two documentView instances
In the following example, there are two
documentView instances. The left one is one-fourth of the width of the
pageContents area, and the right one uses the rest of the space.
ClientMethod adjustContentSize(load, width, height) [ Language = javascript ]
{
var leftView = zen('leftView');
var mainView = zen('mainView');
var leftWidth = Math.floor(width/4);
// This method should have an if{} block for each component.
if (leftView) {
leftView.setSize(leftWidth-2,height);
var leftDiv = leftView.getEnclosingDiv();
leftDiv.style.top = '0px';
}
if (mainView) {
mainView.setSize(width - leftWidth - 2, height);
var mainDiv = mainView.getEnclosingDiv();
mainDiv.style.top = '0px';
mainDiv.style.left = leftWidth + 'px';
}
}
You can specify the optional
onPageShow callback attribute in the page manager element of your
pageContents XData block, as demonstrated in the following example:
<mojo:chui-3.5.2-PageManager onPageShow="zenPage.onPageShow(layoutkey,documentkey);">
This attribute defines the callback method to be invoked after rendering the layout objects for the plugin. For example, you could implement a method that adjusts the display for a layout object provided by a different plugin. Each page manager plugin contains appropriate code to invoke the callback if it has been defined.
Currently, the callback is only required when using the Google Maps plugin, which needs a way to resize the map after rendering the other page items. The following example implements a callback method that triggers a Google Maps resize event:
Example: Implementing onPageShow() for Google Maps
Specify the
onPageShow callback attribute of the page manager element. This example uses the jQuery Mobile page manager:
<mojo:jQM-1.4.5-PageManager onPageShow="zenPage.onPageShow(layoutkey,documentkey);">
In your page class, implement a method similar to the following:
ClientMethod onPageShow(layoutkey, documentkey) [ Language = javascript ]
{
if (layoutkey == 'maps-demo') {
zen('mainView').getPluginByLayoutObjectType('$map').resizeMap();
}
}
Both helper plugins and layout objects sometimes contain methods that provide object-specific utilities, as described in the following sections:
Some plugin classes provide special methods that directly invoke utilities defined in the supporting JavaScript library. To use them, get an instance of the plugin object (via
documentView methods such as
getPluginByLayoutObjectType() or
getPluginByName()), and then call the plugin method. The following example gets a Google Maps plugin object and calls its
resizeMap() method. The plugin method then uses the current map instance to directly access the Google Maps API and trigger a
resize event:
zen('mainView').getPluginByLayoutObjectType('$map').resizeMap();
Individual layout objects may also contain special methods. For example, many layout objects have a
$refresh method. The following call would refresh the display of the layout object identified by key
'person1':
zen('mainView').getItemByKey('person1').$refresh();