DHTML Event Model Support for Data BindingDHTML Event Model Support for Data Binding*
*Contents  *Index  *Topic Contents
*Previous Topic: DHTML Object Model Support for Data Binding
*Next Topic: Document Object Model

DHTML Event Model Support for Data Binding


The document object model exposes an extensive set of scriptable events that Web authors can use to customize the behavior of objects on an HTML page. The data binding architecture leverages this model by exposing an additional set of events that are of interest to authors creating data-driven pages. These events fall into three categories:

Web authors handle these events to maintain a finer grain of control over the page, especially those that support update. Events occur as the data is loaded and is manipulated by the DSO, as the user interacts with the data, and as the page unloads. The events allow the Web author to monitor changes in the state of the DSO, to perform field and record-level validation, and to execute cleanup processing as the page is unloaded.

The following table provides a quick reference on the events that are relevant to data binding; more detailed descriptions follow. For an overview on how to handle events in the document object model, see Understanding the Event Model.

EventBubblesCanceleableApplies To

The Bubbles column indicates whether or not the event bubbles up the containment hierarchy. Most data-related events bubble. The onbeforeunload event does not bubble because it fires on the window object, which is at the top of the containment hierarchy.

The Canceleable column indicates whether the default action associated with the event can be canceled. The onbeforeupdate event, for example, can be canceled to allow the author to prevent the field to which a consumer is bound from being updated. The onafterupdate event cannot be canceled because the update has already occurred by the time the event fires. It would not have fired had the author canceled the onbeforeupdate event.

The Applies To column indicates the type of element from which the event originates. Bound elements are elements on the page that consume data from a DSO. DSO is any object or application that conforms to the specification for data source objects.

Events That Apply to the DSO

The DSO sends notifications when the data set has changed, as data becomes available, when the data is completely available, and before and after a record supplied by the DSO is committed to the data cache.

ondatasetchanged

The ondatasetchanged event fires under two circumstances:

When the event occurs, data may not be available, but the recordset can be used to obtain the metadata for the data set. Metadata includes the list of fields and their types. Web authors can create truly dynamic pages using metadata.

The following example code adds the list of fields provided by a DSO to a drop-down list, cboSort. When the user selects an item in the drop-down list, the data is sorted by the selected field.

This code handles the ondatasetchanged event for the DSO name dsoComposers.

<SCRIPT FOR=dsoComposers EVENT=ondatasetchanged>
    FillSortDropDownWithFields(cboSort, this.recordset);
</SCRIPT>

The following code loops through the collection of fields provided by the ADO recordset and adds each field name to the options collection.

<SCRIPT>
// Add specified value/text to the dropdown list
function AddItemToDropDown(oDropDown, cValue, cText)
{
    oOption = document.createElement('OPTION');
    oOption.value = cValue;
    oOption.text = cText;	
    oDropDown.add(oOption);
}

// Fill dropdown with field names from the ADO RecordSet
function FillSortDropDownWithFields(oDropDown, oRecordSet)
{
// only fill once or let the caller clear list first
    if (oDropDown.options.length > 0)
        return;

    AddItemToDropDown(oDropDown, "None", "None"); // default
    // add each of the columns in the data set to the drop-down
    for (i = 0; i < oRecordSet.fields.count; i++)
    {
        oField = oRecordSet.fields(i);
        AddItemToDropDown(oDropDown, oField.name, oField.name); 
    }
    cboSort.selectedIndex = 0;
}
</SCRIPT>

When the user selects an item from the drop-down list, the following code sets the DSO sort property equal to the appropriate filter or to the empty string if "None" was selected. Note that while the previous code samples work with any DSO, the following code is specific to the Tabular Data Control (TDC).

<SCRIPT FOR=cboSort EVENT=onchange>
    cValue = this.options[this.selectedIndex].value;
    tdcComposers.object.Sort = (cValue == 'None' ? '' : cValue);
    tdcComposers.Reset();
</SCRIPT>

ondataavailable

DSOs typically fire the ondataavailable event when they provide their data asynchronously, indicating that additional records are accessible. Web authors should not rely upon this event to fire but might instead use it to indicate progress to the user. The event may fire zero or more times.

ondatasetcomplete

The ondatasetcomplete event fires when a DSO has cached all its data on the client. The reason property of the event object indicates success (0), abort (1), or failure (2) of the download. A failure might result from an error or from an explicit user action, such as clicking the Stop button. If reason indicates success, all the data is programmatically accessible through the ADO Recordset object.

onreadystatechange

While onreadystatechange is not specific to a DSO, understanding the state of an object can be useful. When this event fires, the event-handling code can retrieve the current value of the readyState property. It is typically safe to access the properties of an object when it reaches a ready state of complete.

<SCRIPT FOR=tdcComposer EVENT=onreadystatechange>
if (this.readyState == 'complete')
{
    // perform some action
}
</SCRIPT>

onrowenter

The onrowenter event fires when the current record pointer has changed, for example, through ADO Recordset navigation. Web authors can use this event to preprocess the data in the current record.

onrowexit

The onrowexit event fires before the current record pointer changes. This might occur for the following reasons:

The Web author can perform record-level validation prior to moving to the next record. By returning FALSE from this event handler, the Web author can prevent the user from moving to the next record.

The following code performs a simple validation to ensure that the data indicates that the composer's birthday occurred before his death.

<SCRIPT FOR=dsoComposers EVENT=onrowexit>
if (txtBorn.value > txtDied.value)
{
    alert("Birth date must be less than or equal to deceased dates");
    return false;
}
</SCRIPT>

Events that Apply to Data Consumers

Bound elements fire events that allow page authors to perform field-level validation and to handle errors that occur during an update.

onbeforeupdate and onafterupdate

The onbeforeupdate event fires when the data in an element has been changed and that element is about to lose the focus. An element loses focus when the user tabs to the next or previous field in the tab order, uses the mouse to select a different control, or unloads the page. The events do not fire if the value of a bound control is set programmatically. Should the validation code associated with the event detect invalid data, an author can return FALSE to prevent the user from leaving the field.

The following code performs some basic validation on the value entered into a text box. If the value is nonnumeric or outside a specified range, the user is alerted and prevented from leaving the field.

<SCRIPT FOR=txtBorn EVENT=onbeforeupdate>
    dToday = new Date();
    fRet = ValidateDate(parseInt(this.value), 0, dToday.getFullYear());
    event.cancelBubble = true;
    return fRet;
</SCRIPT>

<SCRIPT>
// perform some basic validation on the date
function ValidateDate(nValue, nMin, nMax)
{
    if (isNaN(nValue))
    {
        alert("Year required");
        return false;
    }

    if (nValue < nMin || nValue > nMax)
    {
        alert("Invalid year");
        return false;
    }
    return true;
}

Both the original and the modified data can be obtained while handling the onbeforeupdate event because, while the control's value has been updated, the data has not been committed to the DSO. Use the ADO recordset supplied by the DSO to get the original value. Use the appropriate control property to obtain the current value as entered by the user. Here's an example that works for any text box.

<SCRIPT FOR=txtBorn EVENT=onbeforeupdate>
    curValue = this.value;
    origValue = dsoComposers.recordset.fields(this.dataFld).value;
</SCRIPT>

If the onbeforeupdate event is not canceled, onafterupdate fires after data is transferred from consumer to data provider.

onerrorupdate

The onerrorupdate event fires when an error occurs while transferring data from the data consumer to the data source object through some user interaction. By canceling this event, any system-provided error dialog boxes are suppressed.

Events That Apply to the Page

In addition to the events specified above for data bound elements and data source controls, the onbeforeunload event allows the Web author to save data changed on the page that has not been committed to the location from which the DSO obtains its data. The following user actions are among those that cause onbeforeunload to fire:

In addition to these user actions, a script that causes the page to unload will also trigger this event.

window.location.href = "http://www.microsoft.com/ie/ie40";

While the onbeforeunload event is not cancelable, a script writer can return a string from the event through the returnValue property. The string is displayed along with an informative message giving the user the opportunity to cancel the navigation. For example, to warn the user of potential data loss, handle the event as follows:

<SCRIPT FOR=window EVENT=onbeforeunload>
    if (g_fFieldsChanged > 0)
        event.returnValue = "Warning: Modified data has not been saved.";
</SCRIPT>

The g_fFieldsChanged flag used in the example indicates that the page has changed. Page authors can track changes to fields by handling the onafterupdate event:

<SCRIPT FOR=document EVENT=onafterupdate>
    g_fFieldsChanged = g_fFieldsChanged + 1
</SCRIPT>

Putting It All Together with the Data Binding Event Tracker

Click the Show Me button to launch a sample that demonstrates many of the events and concepts discussed in this section.


The sample uses the TDC, so no data will be committed back to the data file. Data can be modified in the local cache, however. By modifying the values within the elements on the page, navigating through the records using the navigation buttons, and changing the filter and sort order through the drop-down lists, the majority of the events will fire. Observe the events and the order in which they occur as they are logged to the TEXTAREA on the right half of the sample page. Clear the event log at any time by clicking the Clear Log button.


Up Top of Page
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.