Monday, December 21, 2009

Creating a DataGrid Object











Creating a DataGrid Object


Data grid components offer a great way to display large amounts of data. This section will show you how to create a DataGrid object that will load XML, parse it, and delegate it to two other objects called the DataRow and the DataColumn, which we will create in the next section.


We first need to define and instantiate the DataGrid object before we can begin to use it. Listing 13.2 shows the code for accomplishing this. After the data grid has been defined, we will define its first method called init. This method creates the object properties, which in our case is simply a new array called rows.


Listing 13.2. Defining and Instantiating the DataGrid Object (DataGrid.js)





DataGrid = {};

DataGrid.init = function()
{
rows = new Array();
}




The data grid that we will create accepts an XML file with the structure that we created earlier. The XML acceptance occurs when the display method is invoked as the callback of an XHR. When the display method is invoked, it checks the readyState of the XHR and displays a loading message in the loading div that we added to our HTML. The loading message displays until the status reaches a completed state and returns the "OK" status code, which we added to the HTTP object in Chapter 9, "Extending the Engine".


if(Ajax.checkReadyState('loading') == "OK"){}


The first element that is created is an actual data grid div element. This element will be used as the container for all of the rows and columns that will eventually format the parsed XML data. The data parsing begins with retrieval of the categories, which provides us with an array that we will iterate to target each category's value. While iterating through the categories, we create titlebar elements, which will hold the category values and display them as the titles of each column in the grid. During the iterations, we will target each category value and add it to the innerHTML attribute of a category div element. After we have the titlebar and category element populated, we can append the titlebar element with the category. Listing 13.3 shows the code to create the categories.



Listing 13.3. Creating Category Titles (DataGrid.js)





[View full width]
var datagrid = Utilities.createElement("div", {id:'datagrid'});
var categories = Ajax.getResponse().getElementsByTagName('category');
for(var i=0; i<categories.length; i++)
{
var titlebar = Utilities.createElement("div", {id:'titlebar', className:'titlebar'});
var categoryText = Ajax.getResponse().getElementsByTagName('category')[i].firstChild.data;
var category = Utilities.createElement("div", {id: 'title', className: 'title',
innerHTML:categoryText });

Utilities.appendChild(datagrid, Utilities.appendChild(titlebar, category));
}




This code would essentially leave us with the following HTML structure:


<div id="titlebar">
<div id="category">value1</div>
<div id="category">value2</div>
<div id="category">value3</div>
</div>


Now that we have the category titles created, we need to display the rest of the data in a grid structure. We begin by targeting the row elements in the XML. This provides us with an array of rows in which we can iterate for the rest of the data. We need to target the items within the row tags and create an items array from the results. With this array, we can get the value of the attributes that each group of items contains. The first attribute is the action attribute, and the second is the icon attribute. Targeting these attributes provides us with their values. The next line of code requires a utility object that we will create shortly, which is called NumberUtil. We are calling its getParity method to decipher whether the value that we are passing it is an even or odd number. This value is eventually used in the DataRow object to decide which color the row will be. All of these values are passed as parameters to the DataRow object that we create and pushed to our rows array for later retrieval. The DataRow takes its parameters in the following order: id, items array, action, parity, and icon (see Listing 13.4).


Listing 13.4. Parsing Row Data (DataGrid.js)





var row = Ajax.getResponse().getElementsByTagName('row');
for(var i=0; i<row.length; i++)
{
var items = Ajax.getResponse().getElementsByTagName('items')[i].childNodes;
var action = Ajax.getResponse().getElementsByTagName('items')[i].getAttribute('action');
var icon = Ajax.getResponse().getElementsByTagName('items')[i].getAttribute('icon');

var parity = NumberUtil.getParity(i);
rows.push( new DataRow(i, items, action, parity, icon) );

Utilities.appendChild(datagrid, rows[i].display());
}




After we have parsed all the item data and created all the data rows, we append each row to the datagrid div element that we created at the beginning of the method. As you can see in Listing 13.5, we are calling the display method from the DataRow object, which will return all the HTML that we will be creating in the DataRow object.


Listing 13.5. Displaying the DataGrid Component (DataGrid.js)





[View full width]
DataGrid.display = function()
{
if(Ajax.checkReadyState('loading') == "OK")
{
var datagrid = Utilities.createElement("div", {id:'datagrid'});
var categories = Ajax.getResponse().getElementsByTagName('category');
for(var i=0; i<categories.length; i++)
{
var titlebar = Utilities.createElement("div", {id:'titlebar', className
:'titlebar'});
var categoryText = Ajax.getResponse().getElementsByTagName('category')[i]
.firstChild.data;
var category = Utilities.createElement("div", {id: 'title', className: 'title'
, innerHTML:categoryText });

Utilities.appendChild(datagrid, Utilities.appendChild(titlebar, category));
}

var row = Ajax.getResponse().getElementsByTagName('row');
for(var i=0; i<row.length; i++)
{
var items = Ajax.getResponse().getElementsByTagName('items')[i].childNodes;
var action = Ajax.getResponse().getElementsByTagName('items')[i].getAttribute
('action');
var icon = Ajax.getResponse().getElementsByTagName('items')[i].getAttribute
('icon');

var parity = NumberUtil.getParity(i);
rows.push( new DataRow(i, items, action, parity, icon) );

Utilities.appendChild(datagrid, rows[i].display());
}

//Utilities.appendChild(document.body, datagrid);
Utilities.appendChild(Utilities.getElement('list'), datagrid);
AjaxUpdater.saving = false;
}
}




The last line of code to include in the DataGrid object is triggering the init method to invoke the object's properties. Listing 13.6 shows us how to accomplish this.


Listing 13.6. Initializing the DataGrid Object (DataGrid.js)





DataGrid.init();




The NumberUtil object that we were using to get the parity is a simple utility object that can handle number-related functions. Although the object is currently handling only parities, it can be scaled to contain additional methods of your choice, such as complicated calculations that you may need to use multiple times and so on. Listing 13.7 shows the object in its entirety.


Listing 13.7. The NumberUtil Object (NumberUtil.js)





NumberUtil = {};

NumberUtil.getParity = function(num)
{
if(num % 2 == 0)
{
return "even";
}
else
{
return "odd";
}
}




Now that we have completed the DataGrid object, we need to create the rows and columns to structure the data. Let's get started by creating a DataRow object.












No comments: