What is So Dynamic About Dynamic HTML?
Building a Dynamic Thank You Page
An Introduction to Microsoft Layers
You are here: irt.org | Articles | Dynamic HTML (DHTML) | Dynamic Table Sorting [ previous next ]
Published on: Friday 23rd January 1998 By: Martin Webb
This article will illustrate a method for sorting tables dynamically. The first method will use the search property of the location object to reload the document, which will be extended to demonstrate a generic solution for all tables. The second method will show the new data binding facility available in Microsoft Internet Explorer 4.
Consider the following table:
Number | Text | Date | Name |
---|---|---|---|
100 | abc | 19971104 | Me |
400 | zzz | 19961003 | You |
300 | fox | 19950902 | Them |
50 | bad | 19981201 | Us |
It contains a mix of different items and values. If we wanted to display the table but sorted by a particular column, then we would normally require a different HTML document per column. Using JavaScript we are able to control the output of a table, displaying it differently depending on the column to be sorted.
The following script, uses an myObjectArray object array to hold the data to be displayed, as myObject objects, in the table. The myObjectArray array is then sorted using the myObjectBubbleSort() function, this is similar to the sorting processes describe in the previous article Arrays, Object Arrays and Sorting. Finally the myObjectArray array is output as a table using the showObjectArray() function.
The myObjectArray array is not always sorted before being shown. It is only sorted, if the location object has a search property that isn't empty, i.e. sortProperty has a length greater than zero. This sortProperty is then passed to the myObjectBubbleSort() function which is used to dictate which property of the myObjectArray array is to be used when sorting the array.
When the table is ouput using the showObjectArray() function, the headers of each column have a link which reloads the document with the search property of the location object set to the required myObject property.
Therefore if you click one of the column headings the document will be redisplayed, showing the table sorted by the column selected.
<SCRIPT LANGUAGE="JavaScript"><!-- function myObject(number,text,date,name) { this.number = number; this.text = text; this.date = date; this.name = name; } var objectArrayIndex = 0; var myObjectArray = new Array(); function showObjectArray(object,length) { var output = '<CENTER><TABLE BORDER=1>'; output += '<TR>' + '<TH><A HREF="sort.htm?number">number<\/A><\/TH>' + '<TH><A HREF="sort.htm?text">text<\/A><\/TH>' + '<TH><A HREF="sort.htm?date">date<\/A><\/TH>' + '<TH><A HREF="sort.htm?name">name<\/A><\/TH>' + '<\/TR>'; for (var i=0; i<length; i++) output += '<TR>' + '<TD>' + object[i].number+ '<\/TD>' + '<TD>' + object[i].text + '<\/TD>' + '<TD>' + object[i].date + '<\/TD>' + '<TD>' + object[i].name + '<\/TD>' + '<\/TR>'; output += '<\/TABLE><\/CENTER>'; document.write(output); } function myObjectBubbleSort(arrayName,length,property) { for (var i=0; i<(length-1); i++) for (var j=i+1; j<length; j++) if (eval('arrayName[j].' + property + '<arrayName[i].' + property)) { var dummy = arrayName[i]; arrayName[i] = arrayName[j]; arrayName[j] = dummy; } } myObjectArray[objectArrayIndex++] = new myObject(100,'abc','19971104','Me'); myObjectArray[objectArrayIndex++] = new myObject(400,'zzz','19961003','You'); myObjectArray[objectArrayIndex++] = new myObject(300,'fox','19950902','Them'); myObjectArray[objectArrayIndex++] = new myObject(50,'bad','19981201','Us'); var sortProperty = window.location.search.substring(1); if (sortProperty.length != 0) myObjectBubbleSort(myObjectArray,objectArrayIndex,sortProperty); showObjectArray(myObjectArray,objectArrayIndex); //--></SCRIPT>
The previous example would need to be adapted for every different table you require to sort. The following example uses a generic approach which can be used for any table. All that is required is the number of columns, i.e. width.
The myObject() function, uses the functions arguments object to work out how many properties each myObject object should have.
The showObjectArray() function uses the width variable to enable it to control the output of the table, table headings and table contents.
<SCRIPT LANGUAGE="JavaScript"><!-- function myObject() { for (var i = 0; i<myObject.arguments.length; i++) this['n' + i] = myObject.arguments[i]; } var objectArrayIndex = 0; var myObjectArray = new Array(); function showObjectArray(object,length) { var output = '<CENTER><TABLE BORDER=1>'; output += '<TR>'; for (var j=0; j<width; j++) output += '<TH><A HREF="generic.htm?n' + j + '">' + eval('object[0].n'+j) + '<\/A><\/TH>'; output += '<\/TR>'; for (var i=1; i<length; i++) { output += '<TR>'; for (var j=0; j<width; j++) output += '<TD>' + eval('object[i].n'+j) + '<\/TD>'; output += '<\/TR>'; } output += '<\/TABLE><\/CENTER>'; document.write(output); } function myObjectBubbleSort(arrayName,length,property) { for (var i=1; i<(length-1); i++) for (var j=i+1; j<length; j++) if (eval('arrayName[j].' + property + '<arrayName[i].' + property)) { var dummy = arrayName[i]; arrayName[i] = arrayName[j]; arrayName[j] = dummy; } } var width = 4; myObjectArray[objectArrayIndex++] = new myObject('Number','Text','Date','Name'); myObjectArray[objectArrayIndex++] = new myObject(100,'abc','19971104','Me'); myObjectArray[objectArrayIndex++] = new myObject(400,'zzz','19961003','You'); myObjectArray[objectArrayIndex++] = new myObject(300,'fox','19950902','Them'); myObjectArray[objectArrayIndex++] = new myObject(50,'bad','19981201','Us'); var sortProperty = window.location.search.substring(1); if (sortProperty.length != 0) myObjectBubbleSort(myObjectArray,objectArrayIndex,sortProperty); showObjectArray(myObjectArray,objectArrayIndex); //--></SCRIPT>
One thing to note with the above two examples, because they use the locations search property, they will not work offline using Microsoft Internet Explorer.
Data Binding is a new feature introduced in Microsoft Internet Explorer version 4. It enables the browser to hold raw data in a text file, and then use that raw data in another document. It uses an inbuilt activeX component referenced by a CLASSID of clsid:333C7BC4-460F-11D0-BC04-0080C7055A83.
To be able to use the activeX component you must first declare the object itself, and at the same time give it a unique identity, or ID, that can be used to refer to it later.
As with all activeX objects, there are several additional parameters associated with it. For this example we will restrict ourselves to DataURL and UseHeader. DataURL specifies the location of the raw data. UseHeader indicates that the raw data has a heading, and that we should use it.
When outputing the raw data, for example to a table, we use the DATASRC attribute to link the table to the activeX object, by specifying the ID of the activeX object preceeded by a #.
When outputing the actual data, we use <DIV> and </DIV> tags along with the DATAFLD attibute. The value of the DATAFLD attribute corresponds with the headings in the raw data file.
To dynamically change the sort order of the table we can change the sort property of the required activeX object ID. This doesn't actually redisplay the table, so an added call to the Reset() method of the required activeX object ID is required.
When accessing the activeX object, we access it in JavaScript by document.all, where all is a new inbuilt object, holding all the various objects in the current document.
<HTML> <BODY BGCOLOR = "#FFFFFF"> <OBJECT ID="dataBindId" CLASSID="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"> <PARAM NAME="DataURL" VALUE="data.txt"> <PARAM NAME="UseHeader" VALUE="TRUE"> </OBJECT> <CENTER> <TABLE BORDER=1 DATASRC="#dataBindId"> <THEAD> <FORM> <TH><INPUT TYPE="BUTTON" VALUE="Number" onClick="document.all.dataBindId.sort='Number';dataBindId.Reset();"></TH> <TH><INPUT TYPE="BUTTON" VALUE=" Text " onClick="document.all.dataBindId.sort='Text';dataBindId.Reset();"></TH> <TH><INPUT TYPE="BUTTON" VALUE=" Date " onClick="document.all.dataBindId.sort='Date';dataBindId.Reset();"></TH> <TH><INPUT TYPE="BUTTON" VALUE=" Name " onClick="document.all.dataBindId.sort='Name';dataBindId.Reset();"></TH> </FORM> </THEAD> <TBODY> <TD><DIV DATAFLD="Number">Number Here</DIV></TD> <TD><DIV DATAFLD="Text">Text Name Here</DIV></TD> <TD><DIV DATAFLD="Date">Date Here</DIV></TD> <TD><DIV DATAFLD="Name">Name Here</DIV></TD> </TBODY> </TABLE> </CENTER> </BODY> </HTML>
Note, the names Number, Text, Date and Name are only the names of the columns, they do not actually represent the type of data in the columns. However, the DATAFLD values must match up with the first entry in the data file. The raw data held in the data.txt file is shown below:
Number,Text,Date,Name 100,abc,19971104,Me 400,zzz,19961003,You 300,fox,19950902,Them 50,bad,19981201,Us
There is some information available on Data Binding in the Internet Client SDK available for download at http://www.microsoft.com/msdn/sdk/inetsdk/asetup/default.asp
You can try the three examples out yourself: sort.htm, generic.htm and binding.htm
If you are using Microsoft Internet Explorer version 4 you will be able to sort the following embedded table dynamically:
If you can't see the above embedded table, then you are not using Microsoft Internet Explorer version 4. We may visit Data Binding in future articles. You may notice that when sorting the first column, that the 50 appears at the end of the list rather than the top of the list, this is because the items are sorted as text items, and alphabetically 50 follows 400.
You can view the source code:
What is So Dynamic About Dynamic HTML?
Building a Dynamic Thank You Page
An Introduction to Microsoft Layers
An Introduction to Netscape Layers
Creating a JavaScript site map