Developing custom widgets for Business Space using Dojo, Part 1: Generating Dojo markup using a generic markup handler

Make Dojo iWidget developement easy by learning to write generic code. You can apply what you learn to help you develop custom Dojo-based iWidgets for Business Space powered by WebSphere®. In Part 1, you'll learn how to generate Dojo markup using a generic markup handler.

Meenakshi Guruaribam Khanna (mekhanna@in.ibm.com), Staff Software Engineer, IBM

Meenakshi Khanna photoMeenakshi Guruaribam Khanna is a Staff Software Engineer at the IBM India Software Lab. She has worked extensively on J2EE and Java technologies, and is a Sun Certified Java Programmer and a Sun Certified Web Component Developer. Meenakshi has published several articles on developerWorks.



Divya Satyavarapu (divyalakshmi@in.ibm.com), Associate System Engineer, IBM  

Divya Satyavarapu photoDivya L Satyavarapu is an Associate System Engineer at IBM, and has been with IBM for 2 years . She is a Sun Certified Java Programmer and has developed JSF portlets on WebSphere Portal Server.



Anil R Patlolla (apatloll@in.ibm.com), Staff Software Engineer, IBM  

Anil R Patlolla is a Staff Software Engineer at India Software Labs in Bangalore. He earned his Bachelor’s in Electronics Engineering from Bangalore University. He has 10 years of experience, mainly in the Java and J2EE space, and has been with IBM for the past five years.



Mallikarjun P Javali ( mallikarjun@in.ibm.com), Software Engineer, IBM  

Mallikarjun Javali has over seven years of experience in various J2EE technologies and has worked in both product development and pre-sales. He focuses on rich internet application technologies. Currently he is working on Dojo-based widget development for the Business Space framework as part of the WebSphere B2B Development UI Team.



Anand Bandaru ( abandaru@in.ibm.com), Staff Software Engineer, IBM  

Anand Bandaru photoAnand Bandaru is a Staff Software Engineer at India Software Labs in Bangalore. He earned his Master’s in System Software from Birla Institute of Technology and Sciences, and his Master’s degree in Computer Applications from Osmania University. Anand is a Sun Certified Java2 Programmer. He has 10 years of experience, mainly in the Java and J2EE space, and has been with IBM for the past seven years.



09 December 2009

Also available in Chinese

Developing widgets for Business Space using DOJO

The custom widgets that we developed for this series are based on the Dojo version that ships with Business Space V7.0 and have been tested on Mozilla Firefox 3.0.11. However, the generic framework concept that we developed would apply even to applications that use Dojo, but don't use Business Space. A basic knowledge of Dojo and the iWidget framework is required to understand the series.

We've tried to cover those topics that are frequently used in Dojo-based applications. The series is organized into the following parts:

  • Part 1: Generating Dojo markup using a generic markup handler
  • Part 2: Creating a Dojo DataGrid component with paging using a generic grid handler
  • Part 3: Using multiple templates in iWidget and how to inherit from a base widget
  • Part 4: Making configurable REST calls from an iWidget using a generic REST handler

For your reference, the following files are provided for download in sampleCode.zip:

  • DojoMarkupHandler.js: This is the generic markup handler JavaScript class.
  • markuphandler.json: This is the JSON file containing the attributes for the widgets in the screen.
  • markuphandler.html: This is the template HTML file that contains the HTML markup . All divs declared in the JSON file should be present here.

Introduction

In Part 1, you'll learn how to create Dojo markup on the fly with minimal coding effort using a generic markup handler. Writing Dojo code has never been easier! We'll describe a simple way to generate Dojo-type markup using a DojoMarkupHandler JavaScript class. The markup handler class can generate programmatic markup for Dojo widgets such as dijit.form.ValidationTextBox, dijit.form.SimpleTextarea, dijit.form.MultiSelect, and so on.

This article walks you through the steps required for using the Dojo markup handler and shows you how the markup handler works.


Understanding the widget attributes

The first thing you'll need to do is define the attributes for all the widgets in your screen in a JSON file. Following is a list of the required and optional attributes:

Required attributes

  • divname: This is the name of the div where the component should be placed in the html. This div should be present in the template HTML file.
  • type: This is the type of the Dojo widget . The following types are supported:
    • radiogroup (dijit.form.RadioButton)
    • textfield (dijit.form.ValidationTextBox)
    • combobox (dijit.form.ComboBox)
    • filteringselect (dijit.form.FilteringSelect)
    • button (dijit.form.Button)
    • textarea (dijit.form.SimpleTextarea)
    • checkbox (dijit.form.CheckBox)
    • multiselect (dijit.form.MultiSelect)
    • datetextbox (dijit.form.DateTextBox)
    • autocompleter (Autocompleter)
  • id: This is the ID or dojoAttachPoint of the component getting created.
  • searchAttr: Search for items in the data store based on this field when entered a value in combobox. (This attribute is mandatory for MultiSelect, ComboBox, FilteringSelect, and Autocompleter.)
  • labelAttr: Label to be displayed. (This attribute is mandatory for MultiSelect, ComboBox, FilteringSelect, and Autocompleter.)

Optional attributes

  • value: The default value to be set to the component.
  • trim: If set to true, this trims the entered text if any spaces.
  • required: Set to true if the field is required field.
  • style: This is the style of the field.
  • maxlength: Maximum length allowed to be entered in the field.
  • regExp: Regular expression to validate the field.
  • constraints: Constraints for the field.
  • invalidMessage: Invalid message to be displayed in case of any wrong value entered.
  • promptMessage: Message to be displayed as prompt for the field.
  • scriptmethod: The event type (onClick, onChange, and so on) and the method name for the method that should be called in case of an event. Example: scriptmethod:'onclick:clickMe'
  • cssclass: This is the css class variable for the field. Class takes precedence over style.
  • options: This specifies the options in the drop-down menu for MultiSelect, ComboBox, FilteringSelect, and Autocompleter.
  • rows: Number of rows to be displayed for a SimpleTextarea.
  • cols: Number of columns be displayed for a SimpleTextarea.
  • iconClass: Icon css class displays the specified icon on the button.

The DojoMarkupHandler JavaScript class processes the above attributes in the JSON file and generates the widgets on the fly without the developer having to write any Dojo markup.

Later in the article, we'll show you how to write the JSON file to generate the markup shown in Figure 1. However, first we'll walk through how the markup handler actually generates the Dojo type markup.

Figure 1. Sample screen generated using generic markup handler
Sample screen generated using generic markup handler

(See a larger version of Figure 1.)


How the Dojo markup handler works

The DojoMarkupHandler.js first loads the JSON file as shown in Listing 1.

Listing 1. Loading the JSON file
loadConfigFile: function(fileName){		
	   
		var FUNCTIONNAME = "loadConfigFile()";
console.debug("Trace: " + "Class: " + this.CLASSNAME + " Function: 
	" + FUNCTIONNAME + " - Action: Entry");

var configUrl=this.rootContext+"com/common/markupHandlerJson/
	"+fileName+".json";
		console.debug("Config URL="+configUrl);

		
		var req = {	url:configUrl,
				handleAs: "json",
				sync: true,
				load: dojo.hitch(this, 
					"_markupHandlerInitiator"),
				error: dojo.hitch(this, 
					"_markupHandlerInitiatorError")
			  };

		 dojo.xhrGet(req);
	}

The markupHandler then traverses the JSON file in the _getConfigMarkup method and, for each item, checks the type of the widget to be rendered. Depending on the type, the corresponding method is invoked, as shown in Listing 2.

Listing 2. _getConfigMarkup method
_getConfigMarkup:function(navigationItems)
	{
		var FUNCTIONNAME = "getConfigMarkup()";
console.debug("Trace: " + "Class: " + this.CLASSNAME + " Function: " 
	+ FUNCTIONNAME + " - Action: Entry");
		
		for(var i=0;i<navigationItems.length;i++){
			var itemObj=navigationItems[i];			
			type = itemObj.type;
			
			if(type =='filteringselect'){
				this.createFilteringSelectMarkup(itemObj);
			}

			if(type =='combobox'){
				this.createComboBoxMarkup(itemObj);
			}

			if(type =='multiselect'){
				this.createMultiSelectMarkup(itemObj);
			}

			if(type =='validationtextbox'){
				this.createValidationTextBoxMarkup(itemObj);
			}


			if(type =='simpletextarea'){
				this.createSimpleTextAreaMarkup(itemObj);
			}
			
			if(type =='radiogroup'){
				this.createRadioGroupMarkup(itemObj);
			}

			if(type =='checkbox'){
				this.createCheckBoxMarkup(itemObj);
			}
						
			if(type =='button'){
				this.createButtonMarkup(itemObj);
			}
		}
		
	}

In the createComboBoxMarkup method, the markup handler programmatically generates the Dojo markup for creating a Combo Box widget, as shown in Listing 3.

Listing 3. createComboBoxMarkup method
createComboBoxMarkup: function(comboBoxSelectObject)
	{
		var FUNCTIONNAME = "createComboBoxMarkup()";
		console.debug("Trace: " + "Class: " + this.CLASSNAME + 
			" Function: " + FUNCTIONNAME + " - Action: Entry");	
		optionStore = this._getOptionsStore(comboBoxSelectObject);

		var props = {		
			name:this.widgetId+comboBoxSelectObject.id,
			id:this.widgetId+comboBoxSelectObject.id,
			dojoAttachPoint:this.widgetId+comboBoxSelectObject.id,
			store: optionStore,
			searchAttr:""+comboBoxSelectObject.searchAttr,
			labelAttr:""+comboBoxSelectObject.labelAttr,
			maxLength: this._getMaxLengthField
				(comboBoxSelectObject.maxlength),
			required: this._getRequiredField
				(comboBoxSelectObject.required),
			style: comboBoxSelectObject.style,
			invalidMessage: this._getNLSMessage
				(comboBoxSelectObject.invalidMessage),
			promptMessage: this._getNLSMessage
				(comboBoxSelectObject.promptMessage)
		};
		

		this.comboBox = new dijit.form.ComboBox(props, 
				this._getDivElement(comboBoxSelectObject));
					this.comboBox._setClassAttr
				(this._getObjectClass
					(comboBoxSelectObject.cssclass,
					comboBoxSelectObject.style));
		this.comboBox.setValue(comboBoxSelectObject.value);
		this._configureScriptHitch(this.comboBox,comboBoxSelectObject);
		this.objectsList.add(this.objectsList.count,this.comboBox);

console.debug("Trace: " + "Class: " + this.CLASSNAME + " Function: " + 
			FUNCTIONNAME + " - Action: Exit");
	}

The source code for generating the markup for the other DOJO types (textfield, checkbox, datetextbox, button, multiselect, textarea) is provided in the attached DojoMarkupHandler.js file.

In the configureScriptHitch method, we hitch the script method with the component, as shown in Listing 4.

Listing 4. configureScriptHitch method
configureScriptHitch:function(){

			if(itemObj.scriptmethod)
		{
			if(this.thisVar.iContext.getElementById
				(this.widgetId+itemObj.id)!=null) {
				elementId = this.thisVar.iContext.getElementById
					(this.widgetId+itemObj.id);
			} else {
				elementId = dojo.byId(this.widgetId+itemObj.id);
			}

			var scriptKeys = itemObj.scriptmethod.split(":");
			var eventType = scriptKeys[0];
			var scriptName =scriptKeys[1];
			
			if(itemObjId==null)
			{
dojo.connect(elementId,eventType, dojo.hitch(this.scriptMethodObj, scriptName));
			} else {
dojo.connect(itemObjId,eventType, dojo.hitch(this.scriptMethodObj, scriptName));
			}
		}

Invoke the markup handler in your code

Complete the following steps to invoke the markup handler JavaScript class from your code.

  1. Define the attributes in a JSON file. You need to define the attributes for all the widgets in your screen in a JSON file (for example, markuphandler.json), as shown in the JSON file snippet below. Make sure that you specify all required attributes for each widget, in addition to any optional attributes desired.
    {
    	divname:'employeename',
    	type:'validationtextbox',
    	id:'employeename',
    	regExp:"[a-zA-Z0-9_\*%\?\$\.=,-]*",
    	value:"",
    	constraints:'',
    	required:"true",
    	maxlength:'30',
    	style:'width: 100px;height:17px;',
    	invalidMessage:'Invalid value'					
    }
  2. Write the HTML template. For every ID that's present in the JSON file, a div with the same ID should be present in the HTML file (for example, markuphandler.html), as shown in the HTML template snippet below.
    <th width="7%" class="body-copyboldleft">Employee Name</th>
    <td width="7%"><div  id="${widgetId}employeename"></div> </td>
  3. Invoke the DojoMarkupHandler.js class. First, instantiate the markup handler JavaScript class from your calling JavaScript and then, call the loadConfigFile with the name of the JSON file as shown in Lw.
    this._markUpHandler = new com.ibm.bcgex.common.DojoMarkupHandler 
    	(this,this, this.getRootContext(),this.iContext.widgetId);
    
    this._markUpHandler.loadConfigFile("alertsList");

Summary

In this article, you've learned how you can develop Dojo-based iWidgets with relative ease. The main benefit to this approach is that you don't have to write the markup code for every screen in the HTML file. The HTML template would only have the layout information and the divs wherein the components need to be placed.


Download

DescriptionNameSize
Source codesampleCode.zip7KB

Resources

  • Writing a custom Dojo application (developerWorks 2008): Learn the tips, techniques, and pitfalls when developing Web 2.0 and Dojo applications. Wendi Nusbickel and Melissa Betancourt have worked on the Dojo application documented in this article for over a year. Having recently completed the development of a Web 2.0 Dojo prototype, they share the experience they gained when creating a custom Dojo application.
  • Overview of developing widgets: Learn more about how to develop an iWidget for Business Space in the Business Space Information Center.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Business process management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Business process management, WebSphere
ArticleID=453897
ArticleTitle=Developing custom widgets for Business Space using Dojo, Part 1: Generating Dojo markup using a generic markup handler
publish-date=12092009