NaturalONE Version 8.3.7
 —  Custom Controls  —

Creating Macro Controls Out of Existing Controls

This document covers the following topics:


General Information

There are two types of controls that you can create with Natural for Ajax:

The following two aspects of macro controls are important:

Top of page

Creating Macro Controls

Creating a macro control consists of the following steps:

The topics below describe a sample control which is used to specify an address.

We recommend that you use all-lowercase letters for prefixes, control names and attributed names. A good example for this is:

nadc:zipcodecity

A bad example would be the following:

NaDc:zipCodeCity

Defining a New Control Library

Each control that is not supplied by Software AG requires a prefix that ensures that controls supplied by different providers can be used within one page. In our example, we use the prefix "nadc" for "Natural for Ajax Demo Controls".

The setup is done in the file <project>/cisconfig/controllibraries.xml.

An example for registering the nadc library would be:

<library prefix="nadc"
	        package="mycontrols.nadc">
</library>

The package that is included in the definition is the Java package that contains corresponding tag handlers (optional).

Note:
In order to activate new control libraries, you must restart the Tomcat server. For NaturalONE, this means restarting Eclipse.

Defining the Control Attributes and Control Hierarchy (Subtags, Container)

For our nadc control library, we create the file editor_nadc.xml. This file can be created using the Control Editor.

Note:
If you are working with NaturalONE, see Ajax Developer in the NaturalONE documentation for details on using the Control Editor. If you are working with the standalone version of Natural for Ajax, see Development Workplace in the Application Designer documentation, which is included in the Natural for Ajax distribution package, for details on using the Control Editor.

In the Control Editor, set up the file editor_nadc.xml. One file can contain a number of controls. For each control, you specify the following:

The name of the control

In our example, this is "nadc:address". Be sure to add the prefix when entering the name.

The control's attributes

This is the list of attributes that a user of the control must specify when using the control inside a page. In our example, the control "nadc:address" has the following attribute:

addressprop

A reference to the runtime property implementation.

Positioning definitions

These specify where the control can be added inside a layout definition. They are used by the layout editor, which only allows controls to be placed in the specified positions.

The positioning definitions include:

Name of the section in the controls palette

The layout editor arranges all controls within the controls palette. This palette is structured into sections. If the name of a section does not yet exist, a new section is created automatically. In our example, the name of the section is "NJXDemos".

Embedding containers

A list of all controls which allow the new control to be positioned inside it. In our example, we decide to position the controls below "pagebody", "rowarea", "colarea" and "splitcell".

After maintaining the information in the Control Editor, the content of the file editor_nadc.xml is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<controllibrary>
  <editor>
    <tag name="nadc:address">
      <attribute name="addressprop" mandatory="true"/>
      <taginstance>
      </taginstance>
      <protocolitem>
      </protocolitem>
    </tag>
    <tagsubnodeextension control="pagebody" newsubnode="nadc:address"/>
    <tagsubnodeextension control="rowarea" newsubnode="nadc:address"/>
    <tagsubnodeextension control="colarea" newsubnode="nadc:address"/>
    <tagsubnodeextension control="splitcell" newsubnode="nadc:address"/>
    <taggroupsubnodeextension group="NJXDemos" newsubnode="nadc:address"/>
  </editor>
</controllibrary>

Definining/Implementing the Rendering of the Control

You can define the rendering either in a descriptive way (XML) in the editor_nadc.xml file or you can define it by implementing a tag handler. The Natural for Ajax demos contain examples for both options. Here, we will describe how to implement the rendering using a tag handler. The tag handler is a Java class which defines how the control's "short XML" (for example, <nadc:address addressprop=’person’/>) is transformed into an XML layout definition which itself contains standard controls or own controls. The tag handler class must extend the interface IMacroTagHandler. For details, see the corresponding Java API documentation. The tag handler has to take care of two main issues:

First, we discuss the sample "nadc:address" control. The tag handler is implemented in the package com.softwareag.cis.test.customcontrols; this is the package that was defined with the control library prefix "nadc" in the configuration file controllibraries.xml. The name of the tag handler class follows the convention <controlInUpperCase>Handler, in our case "ADDRESSHandler".

package com.softwareag.cis.test.customcontrols;

import org.xml.sax.AttributeList;

import com.softwareag.cis.gui.generate.IMacroTagHandler;
import com.softwareag.cis.gui.generate.IXSDGenerationHandler;
import com.softwareag.cis.gui.protocol.Message;
import com.softwareag.cis.gui.protocol.ProtocolItem;

public class ADDRESSHandler
    implements IMacroTagHandler
{

    public void generateXMLForStartTag(String tagName,
                                       AttributeList attributes,
                                       StringBuffer xml,
                                       ProtocolItem protocolItem)
    {
        // read attributes
        String ap = attributes.getValue("addressprop");
        // rendering
        xml.append
        (
            "<rowarea name='Address'>" +
              "<itr>" +         
                "<label width='120' name='First/ Last Name'/>" +
                "<field valueprop='"+ap+".firstName' width='150'/>" +
                "<hdist width='5'/>" +
                "<field valueprop='"+ap+".lastName' width='150'/>" +
              "</itr>" +
              "<itr>" +
                "<label width='120' name='Street'/>" +
                "<field valueprop='"+ap+".street' width='305'/>" +
              "</itr>" +
              "<itr>" +         
                "<label width='120' name='Zip Code/ City'/>" +
                "<field valueprop='"+ap+".zipCode' width='80'/>" +
                "<hdist width='5'/>" +
                "<field valueprop='"+ap+".city' width='220'/>" +
                "<hdist width='10'/>" +
                "<button name='Check' method='"+ap+".onCheck'/>" +
              "</itr>" +
            "</rowarea>"
        );
        IXSDGenerationHandler xga = protocolItem.findXSDGenerationHandler();
	    xga.addControlInfoClass(protocolItem, ap, ADDRESSInfo.class);
	}
       

    public void generateXMlForEndTag(String arg0, StringBuffer arg1)
    {
    }

}

Here are the major processing steps of the tag handler:

Implementing the Control's Server-Side Processing (Optional)

You can apply binding objects to controls. The association of a control to a binding object is specified in the control's tag handler via the method addControlInfoClass of the interface IXSDGenerationHandler.

The server binding objects are optional. They may encapsulate functions with the control which are executed for the control on the server side. Example: In our address control, a zip code validity check will be added. This check is automatically executed within the control when the user presses the Check button that is part of the control's rendering.

This server-side processing for a control is defined in a class that extends the existing class NDOCustomControlInfoBase. See the following code:

package com.softwareag.cis.test.customcontrols;

import com.softwareag.cis.adapter.ndo.NDOCustomControlInfoBase;
import commonj.sdo.DataObject;

public class ADDRESSInfo 
    extends NDOCustomControlInfoBase
{
    public void onCheck()
    {
        // first execute the control's logic
        DataObject address = getDataObject();
        String zipCode = address.getString("zipCode");
        String city = address.getString("city");
        if ("64297".equals(zipCode) &&
            (city == null || city.length() ==0))
        {
            address.set("city","Darmstadt");
        }
        // delegate the method to the normal event processing
        super.invokeMethod("onCheck");
    }
}

We recommend the following guidelines:

The class extends the class NDOCustomControlInfoBase which is supplied with Natural for Ajax. The base class provides some useful functions:

Putting Things to Work

Now we show how to use the control within a page.

When you open the Layout Painter, you can see a new section in the controls palette which has the name "NJXDemos". In this section, you can find the control "nadc:address".

If you define a layout as follows:

<natpage>
   ...
    <pagebody>
        ...
        <nadc:address addressprop="person">
        </nadc:address>
        ...
    </pagebody>
    ...
</natpage>

the corresponding page looks as shown below:

Custom control sample

When you run a corresponding Natural program with this layout and you then enter "64297" in the field defined by zipCode and choose the Check button, the name of the corresponding city is "calculated" by the control processing. Note that the event person.onCheck is then delegated to the normal Natural adapter event processing. This means that this method can be implemented just as a normal event in the Natural program.

Important:
To activate/refresh new/changed controls in existing control libraries, you must choose the Use latest Version for Applications in new Session, Refresh Text Buffer and Refresh Layout Repository Buffer buttons in the monitoring tool.

Monitoring tool

Top of page