9 min read

An integration example

We are going to discuss an example of integrating a data grid widget as it is offered by the Ext JS framework, into the Backbase framework.

We have a dual purpose for this:

  • Firstly, it will give you a feel for what it is like to program using a framework that employs JavaScript exclusively
  • Secondly, we show that it is fairly easy to incorporate functionality that is offered by another framework or library, if for some reason you prefer that over what is offered by Backbase or if it offers something additional

To start, we are going to display a data grid with XML data. For clarity, we show the code for the dataGrid here:

<b:dataGrid width="100%" e_behavior="b:dataGridSortOneColumn" 
sortDirection="descending" sortField="startDate">
<b:dataGridCol dataField="name" width="150px">
name</b:dataGridCol>
<b:dataGridCol dataField="description" width="250px">
description</b:dataGridCol>
<b:dataGridCol dataField="startDate" width="90px">
start date</b:dataGridCol>
<b:dataGridCol dataField="endDate" width="90px">
end date</b:dataGridCol>
<b:dataSource e_behavior="b:localData"
dataType="application/xml"
requestType="application/xml">
<b:dataContainer>
<xi:include href="data/tripdata.xml" />
</b:dataContainer>
</b:dataSource>
</b:dataGrid>

Of course, we have to embed this file into an HTML page, which we assume that you know how to do.

So far, nothing new. But we know that Ext JS offers a very nice data grid and let’s assume now that we would like to use the Ext JS grid in our application instead of the Backbase dataGrid.

Our first question is what the example would look like, without using the Backbase framework:

<html> 
<head>
<title>XML Grid Example</title>
<link rel="stylesheet" type="text/css"
href="ext/ext-all.css" />
<script type="text/javascript" src="ext/ext-base.js">
</script>
<script type="text/javascript" src="ext/ext-all.js">
</script>
<link rel="stylesheet" type="text/css"
href="ext/grid-examples.css" />
<link rel="stylesheet" type="text/css"
href="ext/examples.css" />
<!-- The javascript for the example -->
<script type="text/javascript" src="tripdata-grid.js">
</script>
</head>
<body>
<h1>XML Grid Example</h1>
<p>
The data in the grid is loaded from tripdata.xml
</p>
<div id="tripdata-grid"></div>
</body>
</html>

We hear you say :”Huh! Where is my grid?” We just see a div that suggests holding the div because of the value of the id attribute.

In the previous sections, we have claimed a few times that declarative code using XML markup is preferable over a pure JavaScript approach, and here you see why.

Compare this with the grid we coded for the pure Backbase solution and then decide for yourself. We do not want to pick on Ext JS in particular because all pure JavaScript libraries and frameworks are like this.

Some call this unobtrusive JavaScript and will tell you it is a virtue!

To know what is going on, we need to look at the JavaScript file in tripdata-grid.js:

Ext.onReady(function(){
// create the Data Store
var store = new Ext.data.Store({
// load using HTTP
url: 'data/tripdata.xml',
// the return will be XML, so let's set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'record',
id: 'id',
totalRecords: '@totalRecords'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
'name', 'description', 'startDate', 'endDate',
])
});
// create the grid
var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{header: "Name", width: 200, dataIndex: 'name',
sortable: true},
{header: "Description", width: 400,
dataIndex: 'description', sortable: true},
{header: "Start Date", width: 80,
dataIndex: 'startDate', sortable: true},
{header: "End Date", width: 80, dataIndex: 'endDate',
sortable: true}
],
renderTo:'tripdata-grid',
width:780,
height:160
});
store.load();
});

If you study this piece of JavaScript, you will probably understand how the grid is coded. You can see that similar concepts are used as for a dataGrid in the Backbase framework. There is a data source called Ext.data.Store with fields, there is an Ext.data.XmlReader that reads and maps the data like a data container in the Backbase framework, and there is a grid with columns, here it’s called Ext.grid.GridPanel, where the columns are embedded as anonymous objects.

Here is a picture of what the grid looks like when the example is executed:

Another problem with this kind of JavaScript coding is that everything, the name of the XML file, the names of the columns, and the div where the grid is rendered is hard coded. If we want to use the grid in a different situation, the best we can do is cut and paste this code and adapt it to the new situation. For our example, we have already done this, using the original example and changing it to suit our trip data.

What if you have five grids in your application? Do you still know from the id of the div which is which? And what particular mappings to XML fields you were using or column sorting, and so on? Or which JavaScript file contains the code to fill the grid? You would have to open up the JavaScript files to find out.

To improve on the situation, you could try to generalize the data grid functionality and encapsulate it into a parameterized function. You could embed the JavaScript code in script tags right where the div is that contains the grid. Within a short time, your HTML page will become cluttered with intangible JavaScript and your UI designers will probably not be very happy.

There is nothing technically wrong with putting any JavaScript in your Backbase application, although it is probably necessary to keep grid code like this outside the Backbase areas. But, there is an alternative: use the TDL markup language of the Backbase framework. We are going to encapsulate the Ext JS grid into a Backbase widget.

From the description above, you would’ve guessed that we need four elements for our grid example. We will call them grid, gridCol, dataStore, and field. Further more, we thought it was a good idea to place the widgets in their own namespace: http://www.extjs.com/ext30.

The code that you need to put into a Backbase application for an Ext JS grid, after you have done the integration, looks like this:

<ext:grid  width="780">
<ext:dataStore url="data/tripdata.xml">
<ext:field name="name" />
<ext:field name="description" />
<ext:field name="startDate" />
<ext:field name="endDate" />
</ext:dataStore>
<ext:gridCol header="Name" width="200" dataIndex="name"
sortable="true" />
<ext:gridCol header="Description" width="400"
dataIndex="description" sortable="true" />
<ext:gridCol header="Start Date" width="80"
dataIndex="startDate" sortable="true" />
<ext:gridCol header="End Date" width="80"
dataIndex="endDate" sortable="true" />
</ext:grid>

We hope you agree that this code is similar to the code we made for the pure Backbase example, except for the names of the widgets and the attributes used. We could have made them more similar to the Backbase equivalents, but we have chosen to define names closer to the names used in the pure Ext JS example.

Now that you have seen what the final result is, it will be easier to understand the definition in TDL for the grid itself:

  • The grid needs to have two attributes to hold the size of the grid: width and height.
  • The template of the grid element needs to be a div that can be used to attach the Ext JS grid to. Using this div to put the grid, we do not need the external div with a specific id
<d:element name="grid"> 
<d:attribute name="width" default="500" />
<d:attribute name="height" default="160" />
<d:template type="application/xhtml+xml">
<div >
<d:content />
</div>
</d:template>
<d:handler event="DOMNodeInsertedIntoDocument"
type="text/javascript">
// The rendering of the div takes place here.
</d:handler>
</d:element>

If you look at the JavaScript code for the example (tripdata-grid.js), you will see that the grid is rendered after the page is loaded, using Ext.onReady(function(){…}. We mimic this behavior by using the DOMNodeInsertedIntoDocument event. Here is the code for the event handler:

<d:handler event="DOMNodeInsertedIntoDocument" 
type="text/javascript">
// get the store
var oStoreEl =
this.getElementsByTagNameNS('http://www.extjs.com/ext30',
'dataStore')[0];
var store = oStoreEl.getStore();
// create the grid columns
var aColElements =
this.getElementsByTagNameNS ('http://www.extjs.com/ext30',
'gridCol');
var aCols = new Array();
for (var i=0; i < aColElements.length ; i++) {
aCols[i] = {
header: aColElements[i].getAttribute('header'),
width: parseFloat(aColElements[i].getAttribute('width')),
dataIndex: aColElements[i].getAttribute('dataIndex'),
sortable: (aColElements[i].getAttribute('sortable') ==
'true')? true : false
};
}
// create the grid
var grid = new Ext.grid.GridPanel({
store: store,
columns: aCols,
renderTo: this.viewGate,
width: parseFloat(this.getAttribute('width')),
height: parseFloat(this.getAttribute('height'))
});
store.load();
</d:handler>

The code in the DOMNodeInsertedIntoDocument event handler is essentially a copy of the original example code. Look carefully at the following though:

  • The dataStore widget is created by placing the widget as a nested element within the grid element. All we need to do is find it, using this.getElementsByTagNameNS(‘http://www.extjs.com/ext30’, ‘dataStore’)[0].
  • The Ext JS dataStore object is created by calling the getStore() method on the dataStore element. Be careful to make the distinction between the Ext JS data.Store object that we get returned from the getStore() method and the Backbase dataStore that is returned by the getElementsByTagNameNS function.
  • In a very similar way as finding the data store, we find a set of gridCol elements. The anonymous column elements in the array that we will need to create the grid are created using the attributes provided in the gridCol elements.
  • Next, the grid itself, a new Ext.grid.GridPanel object is created, which has the store object and the column array we created before as arguments. The width and the height are taken from the width and height attributes, which have a default value, therefore, you will always see a grid, even if it does not have theproper size.
  • Note in particular the renderTo attribute, which specifies this.viewGate, indicating that the grid will be rendered as child of the view node of the widget. This is exactly what we want because the grid will be shown where the grid widget is placed, and no extra div with a specific id is needed.

LEAVE A REPLY

Please enter your comment!
Please enter your name here