Developing custom widgets for Business Space using Dojo, Part 2: Creating a Dojo DataGrid component using a generic grid handler

In Part 2 of this series, learn how to use a generic grid handler to create a reusable, easy to maintain Dojo DataGrid component with paging for use in Business Space powered by WebSphere®.

Share:

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, WSO2 Inc

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.



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

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.



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

Anil Patlolla photoAnil 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.



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.



20 January 2010

Also available in

Introduction

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

In Part 2, we'll show you how to programmatically create a Dojo DataGrid component with paging using a generic grid handler. Keeping reusability and ease of maintenance in mind, we have come up with a flexible design in which the layout itself is defined in a JSON file.

This article walks you through the required steps for using the DojoGridHandler JavaScript class to create a Dojo DataGrid component, and also shows you how the grid handler works. The following sample files are provided for download in Dojo_sample.zip:

  • DojoGridHandler.js: The generic grid handler JavaScript class.
  • gridHandlerLayout.json: The JSON file containing the layout information for the DataGrid widget.
  • DojoItemFileWriteStore.js: The custom data store that overrides the ItemFileWriteStore.js.
  • DojoPagingTable.js: The paging table Javascript class that handles paging functionality.
  • pagingTable.html: The HTML template file used by the paging table widget; it contains the divs for placing buttons to navigate to various pages
  • gridView.html: The HTML template file that contains the HTML markup; it contains the divs in which the grid and paging table widgets should be placed.

Define the grid layout

The first step to creating a Dojo DataGrid is to define the layout of your grid. Layout information can contain the columns you want to place in the grid, as well as additional information such as formatting information, column grouping, column width, and so on.

Figure 1 shows a sample Business Space screen displaying a DataGrid generated using DojoGridHandler.

Figure 1. DataGrid generated using DojoGridHandler
DataGrid generated using DojoGridHandler

(See a larger version of Figure 1.)

We'll show you how to write the JSON file to generate the layout for the example above, but first we'll describe how the grid handler actually generates the Dojo DataGrid widget.

How the Dojo grid handler works

The DojoGridHandler class loads the JSON file containing the layout information in the createGrid( ) method, as shown in Listing 1.

Listing 1. The createGrid( ) method
createGrid : function(thisVar,gridHeadersURL,gridComponentId,gridDisplayDivId,
				pagingDivId,onCellClickMethodName)
	{
		this.gridComponentId=thisVar.iContext.widgetId+gridComponentId;
		this.pagingDivId=thisVar.iContext.widgetId+pagingDivId;
		this.thisVar = thisVar;
		
		var req = {	url:gridHeadersURL,
				handleAs: "json",
				sync:true,
				load: dojo.hitch(this, function(data){ 
this._gridHeadersURLDef(data,gridDisplayDivId,onCellClickMethodName); }),
				error: dojo.hitch(this, this._gridHeadersURLDefError)
			  };

		 dojo.xhrGet(req);

	}

The createGrid method calls the _gridHeadersURLDef method upon successful loading of the JSON file. The _gridHeadersURLDef method reads the layout information from the JSON file. It also checks whether each of the columns in the layout has a formatter attribute. If a formatter attribute is present , the corresponding formatter method is hitched to the correct scope.

The _gridHeadersURLDef() method then calls the drawDataGrid() method.

Listing 2. The _gridHeadersURLDef( ) method.

Listing 2. The _gridHeadersURLDef( ) method
_gridHeadersURLDef: function(response,gridDisplayDivId, onCellClickMethodName){
		
		this.gridSearchResultDef=response.layout;
	
		for(var i=0; i<this.gridSearchResultDef.length;i++){
			
			rowheaders = this.gridSearchResultDef[i];
			for(var j=0; j<rowheaders.length;j++)
			{
				var callback=rowheaders[j].formatter;
				if(callback){
					rowheaders[j].formatter=dojo.hitch
						(this.thisVar,callback);
					console.debug(callback);
				}
				var displayName=this.iwidget_messages
					[rowheaders[j].name];
				
				rowheaders[j].name=displayName;
			}
		}

		this._drawDataGrid(this.gridSearchResultDef, gridDisplayDivId,
onCellClickMethodName);

	}

The drawDataGrid method instantiates the DataGrid widget and calls the startup method of the DataGrid. The code snippet in Listing 3 creates a DataGrid widget with columnReordering, clientSort and autoHeight set to true. Data for the grid comes from the custom data store DojoItemFileWriteStore. The DojoItemFileWriteStore store overrides the _getItemsFromLoadedData() method in ItemFileWriteStore to read the attributes (totalRecords, startRecordIndex and endRecordIndex) needed for displaying paging information.

The main reason we've overridden the ItemFileWriteStore is to get the total row count (because we wanted to display the total number of rows in our user interface) since ItemFileStore doesn't have an API that returns the total row count.

Listing 3. The _drawDataGrid( ) method
_drawDataGrid : function(resultDef,gridDisplayDivId,onCellClickMethodName){
			console.debug("begin startUpGrid searchResultDef."+resultDef);
			var pmi=new dojox.widget.PlaceholderMenuItem
				( {label : "GridColumns"});
			var gridMenu= new dijit.Menu({style : "display: none;"});
			gridMenu.addChild(pmi);

			this.dataStore = new com.ibm.bcgex.common.DojoItemFileWriteStore
({data:{items:[]}});
			this.gridWidget= new dojox.grid.DataGrid({
					id:this.gridComponentId,
		dojoAttachPoint:this.gridComponentId,
					store: this.dataStore,
					autoHeight:true,
					rowSelector: '20px',
					clientSort:true,
					style:"border: solid black 1px",
					structure: resultDef ,
					columnReordering: true,
					headerMenu: gridMenu}, 
dojo.byId(this.thisVar.iContext.widgetId+gridDisplayDivId));
	

this.gridWidget.startup();
dojo.connect(this.gridWidget, "onCellClick", dojo.hitch(this.thisVar,
onCellClickMethodName));
},

The populateGrid() method loads data into the DataGrid widget. This method makes a call to the REST API and then calls the _loadRestGridData method, as shown in Listing 4, which does the actual data population.

Listing 4. The _loadRestGridData() method
_loadRestGridData: function(data)

{

	this.data=eval(data);   
		
	this.dataStore = new com.ibm.bcgex.common.DojoItemFileWriteStore
		({ data: this.data});

	var grid = dijit.byId(this.gridComponentId);

	grid.setStore(this.dataStore);

	this.populatingPagingDiv(this.dataStore);   	

}

The _loadRestGridData() method in turn calls the populatingPagingDiv() method, which is used to construct the paging table.

The populatingPagingDiv() method is used to populate the paging data in the grid. This in turn calls the _drawPagingTable() method, as shown in Listing 5, which is used to construct the paging table. For paging to work, the following attributes should be returned as part of the data from the REST call:

  • totalRecords
  • startRecordIndex
  • endRecordIndex
Listing 5. The _drawPagingTable () method
_drawPagingTable: function(totalRecords,startRecordIndex,endRecordIndex){

		console.debug("Inside drawPagingTable...");

		if(this.pagingTable==null)

		{
			this.pagingTable = new
com.ibm.bcgex.common.DojoPagingTablethis.thisVar.iContext,this.iwidget_messages,
this.gridComponentId);

			this.pagingTable.setPagingCallback
(this, "pagingTableActionPopulateGrid");

			dojo.byId(this.pagingDivId).appendChild
(this.pagingTable.domNode);

			this.pagingTable.insertLayoutDijits();
		}
                                            this.pagingTable.setRecordNbrNTotalCounts
(startRecordIndex,endRecordIndex,totalRecords);
}

How to use the grid handler in your code

Now let's learn how to invoke the grid handler JavaScript class from your code.

  1. Define the layout attributes in a JSON file.

    You need to define the layout attributes for all the columns in your DataGrid in a JSON file, such as gridHandlerLayout.json. The code snippet below shows the gridHandlerLayout JSON file containing the layout information for the DataGrid for the sample screen shown in Figure 1.

    ({
    	"layout" : [[
    		{
    		    "field" : "name",
    		    "name": "Name",
    		    "formatter" : "formatName" 
    		},
    		{
    		    "field" : "gender",
    		    "name": "Gender"
    		},
    		{
    		    "field" : "fullName",
    		    "name": "Full Name",
    		    "formatter" : "formatFullName" 
    		  
    		},
    		{
    		    "field" : "department",
    		    "name": "Department"
    		},
    		{
    		    "field" : "location",
    		    "name": "Location"
    		},
    		{
    		    "field" : "delete",
    		    "name": "Delete",
    		    "formatter" : "formatDelete" 
    		}
    	    ]]
    })
  2. Next , instantiate the DojoGridHandler JavaScript class as shown here:

    this.gridHandler = new com.ibm.bcgex.common.DojoGridHandler(this.iContext,this.rootContext);
  3. Define a variable pointing to the JSON file that contains the layout information as shown here:

    var configURL = this.iContext.io.rewriteURI(""+"gridHandlerLayout.json");
  4. Call the createGrid method as follows:
    this. gridHandler.createGrid(this, configURL, " employeeGrid "," employeeGridDiv ",
    	" employeeGridPagingDiv ","gridOnCellClick");
  5. In the HTML template file, there should be two divs with the IDs employeeGridDiv and employeeGridPagingDiv. (See the gridview.html provided for download.)
  6. To populate the data in the grid, call the populateGrid method as shown here:
    this. gridHandler.populateGrid();
  7. To format columns in the DataGrid (for example, if you want some fields to display as image links) you need to define the formatter attribute in the layout. So, the formatDelete() method look something like this:
    formatDelete : function(value){
    		
    var imagePath=this.getImageRootContext(); // give the image path here
    return "<img src=\""+imagePath+"redx.gif\"\"/>";
    		
    }

Summary

You've now learned the steps to creating a Dojo DataGrid widget programmatically using the DojoGridHandler. You can use the grid handler to create a DataGrid component with paging in Business Space with minimal coding If you need to change the layout, you can do so easily without impacting the code.


Download

DescriptionNameSize
Source codeDojo_sample.zip6KB

Resources

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=462296
ArticleTitle=Developing custom widgets for Business Space using Dojo, Part 2: Creating a Dojo DataGrid component using a generic grid handler
publish-date=01202010