ASP 101 - Active Server Pages 101 - Web01
The Place ASP Developers Go!

Please visit our partners


Windows Technology Windows Technology
15 Seconds
4GuysFromRolla.com
ASP 101
ASP Wire
VB Forums
VB Wire
WinDrivers.com
internet.commerce internet.commerce
Partners & Affiliates














ASP 101 is an
internet.com site
ASP 101 is an internet.com site
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

ASP 101 News Flash ASP 101 News Flash



 Top ASP 101 Stories Top ASP 101 Stories
Migrating to ASP.NET
Getting Scripts to Run on a Schedule
The Top 10 ASP Links @ Microsoft.com

QUICK TIP:
Use the front door, please!
Show All Tips >>
ASP 101 RSS Feed ASP 101 Updates


Back Contents Next

Binding a DSO to HTML Controls

Once the data has been retrieved and cached locally, we can use it to populate HTML controls in a Web page (a process called data binding), or we can work with it directly using ADO code within the page. In fact, even when using data binding, we'll often still implement ADO code in the page. This is particularly the case when we want to update the data and submit the changes back to the server.

Data binding uses the Data Binding Agent object that is part of Internet Explorer 4 and higher. When programming in a language like Visual Basic or C++, the special controls that are part of that environment are used to implement data binding instead.

The Web-based Data Binding Agent can provide two types of data binding, either tabular data binding or single record data binding (often called current record data binding). All DSO controls can take part in tabular data binding or single/current record data binding. We'll briefly summarize the HTML controls that are used in Web pages next, then go on to look at the two types of data binding where they can be used.

Controls that can be bound to a DSO recognize special HTML attributes that provide the connection information they need. These are:

DATASRC - the ID of the DSO that will supply the data, prefixed by a '#' hash character.

DATAFLD - the name of the field in the DSO's recordset to bind this control to.

DATAFORMATAS - Either 'TEXT' (the default if omitted) to display the field value as plain text, or 'HTML' to specify that the browser should render any HTML content within the value.

The full list of controls that can participate in data binding in Internet Explorer 4 and onwards is:

HTML Element

Bound property

Update
data?

Tabular
binding?

Display
as HTML

A

href

No

No

No

APPLET

param

Yes

No

No

BUTTON

innerText and innerHTML

No

No

Yes

DIV

innerText and innerHTML

No

No

Yes

FRAME

src

No

No

No

IFRAME

src

No

No

No

IMG

src

No

No

No

INPUT TYPE=CHECKBOX

checked

Yes

No

No

INPUT TYPE=HIDDEN

value

Yes

No

No

INPUT TYPE=LABEL

value

Yes

No

No

INPUT TYPE=PASSWORD

value

Yes

No

No

INPUT TYPE=RADIO

checked

Yes

No

No

INPUT TYPE=TEXT

value

Yes

No

No

LABEL

innerText and innerHTML

No

No

Yes

MARQUEE

innerText and innerHTML

No

No

Yes

OBJECT

param

Yes

No

No

SELECT

text of selected option

Yes

No

No

SPAN

innerText and innerHTML

No

No

Yes

TABLE

none

No

Yes

No

TEXTAREA

value

Yes

No

No

So, as an example, we could bind a SPAN element to the value in a field named tTitle, which is in a recordset exposed by a DSO that has the ID of dsoBookList, using:

<SPAN DATASRC="#dsoBookList" DATAFLD="tTitle"></SPAN>

The value of the tTitle field in the current record in the recordset would then be displayed in the page within the SPAN element as plain text (the default). If the tTitle field contains HTML formatting within the value, we can cause the browser to render it as such using:

<SPAN DATASRC="#dsoBookList" DATAFLD="tTitle DATAFORMATAS="HTML"></SPAN>

We can also use client-side script to set up or change the bindings once the page has loaded, by changing the dataSrc, dataFld and dataFormatAs properties of the appropriate elements. To remove the bindings, set the properties to an empty string. To change the binding of elements within a bound table, we must remove the binding of the table first (in the <TABLE> tag), change the bindings of the elements in the table, and then reset the binding of the table.

Tabular Data Binding

Tabular data binding depends on the ability of the <TABLE> element to repeat the contents of the <TBODY> section once for each record. It's important to recognize that the use of the word tabular - in the sense of the way the data is bound to controls - is entirely unconnected with the name of the Tabular Data Control.

The data source object is identified within the opening <TABLE> tag, and the column or field name for each bound control is identified within each table cell. Note that the <TD> element itself does not take part in the data binding process. Instead, a bound element is placed within each cell. This could be a <SPAN> or a <DIV> element, or one of the other HTML controls. For example:

...
'definition of a DSO named dsoBookList is elsewhere in the page ...
...
<TABLE DATASRC="#dsoBookList">
 <THEAD>
  <TR>   
   <TH>Code</TH>
   <TH>Category</TH>
   <TH>Release Date</TH>
   <TH>Title</TH>
   <TH>Sales</TH>
  </TR>
 </THEAD>
 <TBODY>
  <TR>   
   <TD><SPAN DATAFLD="tCode"></SPAN></TD>
   <TD><I><SPAN DATAFLD="tCategory"></I></SPAN></TD>
   <TD><SPAN DATAFLD="dReleaseDate"></SPAN></TD>
   <TD><B><SPAN DATAFLD="tTitle"></SPAN></B></TD>
   <TD><SPAN DATAFLD="nSales"></SPAN></TD>
  </TR>   
 </TBODY>
</TABLE>
...

Table Paging with Tabular Data Binding

ADO recordsets support paging, as we discovered in Chapter 5 when we looked at the Recordset object. When tabular data binding is used, the <TABLE> element is bound to the DSO that provides the source recordset, and displays the records in that recordset. The DSO properties are exposed through the bound <TABLE> element, and this includes the dataPageSize property. In IE4 and above, this property is mapped to the DATAPAGESIZE attribute of the table as well:

DATAPAGESIZE - sets the maximum number of records that will be displayed within the body of a table.

By setting this attribute in the opening HTML <TABLE> tag, we can create a table that displays only a specified number of records:

<TABLE DATASRC="#dsoBookList" DATAPAGESIZE=10>

Then, we can move through the recordset by using the nextPage and previousPage methods. The bound table also exposes the recordNumber property of the underlying data set for each element within the table.

Single Record Data Binding

Tabular display is fine for displaying data, but for editing it we really need to be able to display the values from one record at a time within HTML controls. This is particularly true if we want to allow the user to update the source data.

As soon as a recordset is created by a DSO, the first record becomes the current record, in exactly the same way as when we create a recordset using ADO directly (if the recordset is empty, the EOF and BOF properties are both True at this point). We can display the values from the current record in any of the bindable HTML elements listed earlier by setting their DATASRC and DATAFLD properties. For example:

...
'definition of a DSO named dsoBookList is elsewhere in the page ...
...
Code: <INPUT TYPE="TEXT" DATASRC="#dsoBookList" DATAFLD="tCode" SIZE=6><P>
Title: <INPUT TYPE="TEXT" DATASRC="#dsoBookList" DATAFLD="tTitle" SIZE=20><P>
Category: <SELECT DATASRC="#dsoBookList" DATAFLD="tTitle" SIZE=1>
            <OPTION>HTML
            <OPTION>Scripting
            <OPTION>ASP
           </SELECT><P>
Release date: <SPAN DATASRC="#dsoBookList" DATAFLD="dReleaseDate"><P>
Sales to date: <SPAN DATASRC="#dsoBookList" DATAFLD="nSales"><P>
...

This produces the page we first saw earlier in this chapter, and the screenshot is repeated here. The buttons at the bottom of the page allow users to move around the recordset, and they work by calling the appropriate move methods of the underlying recordset object-as described below.

Moving Around and Updating the Data

If we display a single record, we need a way to move to another record. We also need a way to update the source data (if this is appropriate, depending on the DSO we are using) by adding, deleting and editing records. And we will probably also need to cancel updates, and refresh the data displayed in the controls at some stage. All these tasks are accomplished using the standard methods of the DSO that are exposed via ADO. The most common methods are:

Method

Description

move, moveFirst, moveLast, moveNext, movePrevious

move the current record pointer within the cached recordset

cancelUpdate

cancels all changes made to cached records

refresh

re-queries the data source and reloads the recordset data cache

delete

removes the current record from the cached recordset

addNew

adds a new record to the cached recordset

submitChanges

updates the source data with all the changes made to the cached recordset

To move to the next record, as shown in the previous screenshot, we can use a normal HTML BUTTON control to call the exposed methods of the DSO:

<button onclick="dsoBookList.recordset.MoveNext()"> > </button>

See Appendix F for a full list of the properties, methods and events for the ADO recordset object.

Events Raised by Internet Explorer 4/5 and the RDS DSO

Both a DSO embedded within the page, and the browser itself, raise events that can be trapped and used in script on the client. We'll look at these events briefly next. They can be divided into two groups: those raised by the browser or the controls on the page (when the user navigates to another page or edits the data in the HTML controls), and those raised by a DSO as the user edits the data it exposes.

Events Raised by HTML Elements and the Browser

When a page containing a DSO is unloaded, or when the user edits the data in HTML controls that are bound to a DSO, various events are raised. Some can be cancelled by returning the value false from the event handler routine:

Event

Cancel?

Description

onbeforeupdate

Yes

Occurs before the data in the control is passed to the DSO.

onafterupdate

No

Occurs after the data in the control has been passed to the DSO.

onerrorupdate

Yes

Occurs if an error prevents the data being passed to the DSO.

onbeforeunload

No

Occurs before the current page is unloaded.

The onbeforeunload is raised by the window object, while the remainder are raised by the HTML controls on the page. With the exception of the onbeforeunload event, all events bubble up through the document hierarchy. So, we can display a message when the user changes the value in a control with:

<INPUT ID="txtTitle" DATASRC="#dsoBookList" DATAFLD="tTitle">
...
<SCRIPT LANGUAGE="JavaScript">
function txtTitle.onbeforeupdate() {
  return confirm("Are you sure you want to change this value ?");
}
</SCRIPT>

Events Raised by the RDS Data Source Object

The RDS Data Source Object itself raises events as various actions take place. Most are concerned with indicating the current state of the DSO as it loads the data. However, the first two are fired when the 'current record' changes as the user moves through the recordset. This could be by clicking on a tabular data-bound table, or when the code in a page that uses single-record data binding calls one of the recordset move methods:

Event

Cancel?

Description

onrowenter

No

Occurs for a record when it becomes the current one during navigating the recordset.

onrowexit

Yes

Occurs for a record before another record becomes the current one during navigating the recordset.

ondataavailable

No

Occurs periodically while data is arriving from the data source.

ondatasetcomplete

No

Occurs when all the data has arrived from the data source.

ondatasetchanged

No

Occurs when the data set changes, such as when a filter is applied.

onreadystatechange

No

Occurs when the readyState property of the DSO changes.


Only the
onrowexit event can be canceled by returning false from the event handler routine. All events bubble up through the document hierarchy. It's usual to take advantage of the ondatasetcomplete event for any script that you want to run once the data has arrived:

<INPUT ID="txtStatus" VALUE="Initializing, please wait ...">
...
<SCRIPT LANGUAGE="JavaScript">
function dsoBookList.ondatasetcomplete() {
  txtStatus.value = "Data arrived OK";
}
</SCRIPT>

Manipulating Data Directly with ADO

It's important to realize that each data source object is itself a DataControl object, and as such is an OLE-DB data provider. This has to be the case for ADO to be able to access the data exposed by the DSOs-remember that ADO is a way of communicating with an OLE-DB data provider (or an ODBC driver that exposes an OLE-DB interface).

The only difference here is that the data store is now a locally cached recordset, and so the DataControl object or DSO takes the place of the server-side OLE-DB data provider. In fact, ADO continues this terminology by referring to bound controls on a Web page as data consumers.

Filling a SELECT List

Each DSO exposes the cached recordset to code running on the client through its recordset property. We can create a reference to this and work with the contents of the recordset. So, once we've got the data into a client-side cached recordset, we can use it just like we would in ADO on the server. For example we can use it to populate a <SELECT> list by iterating through the recordset. Note that we do it in the ondatasetcomplete event handler, where we know that the data has arrived:

<OBJECT CLASSID="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"
        ID="dsoBookList" WIDTH=0 HEIGHT=0>
  <PARAM NAME="DataURL" VALUE="booklist.txt">
  <PARAM NAME="FieldDelim" VALUE=";">
  <PARAM NAME="UseHeader" VALUE="true">
</OBJECT>

<INPUT TYPE="HIDDEN" DATASRC="#dsoBookList" DATAFLD="tTitle">

<SELECT ID="MyList" SIZE=1>
  <OPTION>Initializing ... please wait ...
</SELECT>

<SCRIPT LANGUAGE="JavaScript">
function dsoBookList.ondatasetcomplete() {
  objListBox = document.all("MyList");             
// get reference to SELECT list
  objListBox.options[0].text = "Select a book..."; // change current OPTION text
  recBooks = document.dsoBookList.recordset;       // the DSO's recordset
  while (!recBooks.EOF) {                          // add titles to SELECT list
    strTitle = '' + recBooks("tTitle");
    objListBox.options.length += 1;
    objListBox.options[objListBox.options.length - 1].text = recBooks("tTitle");
    recBooks.MoveNext();   
  }
}
</SCRIPT>

Here's the result, showing the list box contents after the ondatasetcomplete event has fired, and the values have been inserted into the list by creating new <OPTION> elements within it:

In some circumstances, the RDS control can fail to initiate the data transfer from server to client as there are no bound controls on the page. You can get round this by placing a HIDDEN-type control on the page and binding it to one field in the recordset, for example:
<INPUT TYPE="HIDDEN" DATASRC="#dsoBookList" DATAFLD="tTitle">

Using the Recordset with Internet Explorer Dynamic HTML

As another example of using the recordset directly, we can create output in the page using Dynamic HTML-here to place values from the records into a <H3> heading element previously defined in the page:

<OBJECT CLASSID="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"
        ID="dsoBookList" WIDTH=0 HEIGHT=0>
  <PARAM NAME="DataURL" VALUE="booklist.txt">
  <PARAM NAME="FieldDelim" VALUE=";">
  <PARAM NAME="UseHeader" VALUE="true">
</OBJECT>

<INPUT TYPE="HIDDEN" DATASRC="#dsoBookList" DATAFLD="tTitle">

<H3 ID="MyHeading">Initializing, please wait ...</H3>

<SCRIPT LANGUAGE="JavaScript">
var strList = 'List of books:<P>';

function dsoBookList.ondatasetcomplete() {
  recBooks = document.dsoBookList.recordset;     
// the DSO's recordset
  while (!recBooks.EOF) {                        // add titles to strList string
    strTitle = '' + recBooks("tTitle") + '<BR>';
    strList += strTitle;
    recBooks.MoveNext();   
  }
  document.all("MyHeading").innerHTML = strList; 
// put string into H3 element 
}
</SCRIPT>

Both of these examples use similar code to get a reference to the client-side ADO recordset object, and then iterate through it extracting values from the records. You can use the values in more creative ways of course, and these two simple examples are designed just to show the basic technique.

The samples for this book contain several examples that uses the various DSOs we've discussed. You can download the samples, and even run some of them directly, from our Web site at http://webdev.wrox.co.uk/books/1835/


Back Contents Next
�1998 Wrox Press Limited, US and UK.
Home |  News |  Samples |  Articles |  Lessons |  Resources |  Forum |  Links |  Search |  Feedback


The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers