Приглашаем посетить
Аксаков К.С. (aksakov-k-s.lit-info.ru)

Writing Scripts Using Data Binding

Writing Scripts Using Data Binding

The preceding section showed you how to write bindings using HTML. In this section, you'll learn how to combine script code with data binding to create actual data-access applications that can run in Internet Explorer 4.0. The discussion begins by introducing ADO (ActiveX Data Objects) and then proceeds to the events provided by Internet Explorer 4.0 on data-bound elements and data source objects.

ADO-Recordset Version

The current record-binding example presented earlier in this chapter used HTML button controls to move the current record pointer forward and backward. The script used for the onclick event was stocklist.recordset.MoveNext(). This code references the recordset object from the data source object stocklist and then invokes the MoveNext method on the recordset object.

The recordset object in this case is ADO-Recordset version, referred to here as ADOR, which includes only the recordset and field objects from the full version of ADO provided with various other Microsoft products, such as Active Server Pages. Internet Explorer 4.0 supplies ADOR to all data source objects on a Web page. As shown in the preceding example, the recordset object is accessible from the recordset property of the data source object.

You can access the data in an ADOR recordset using scripts. Through scripts you can change which record is current and perform calculations, validation, or any other function that requires access to the data. The data used in the ADOR recordset need not be bound to any HTML elements on the page. You can use the ADOR recordset solely for programmatic access to data from a data source object.

The specifics of using ADOR are beyond the scope of this chapter. However, the following sections touch on two key areas of functionality commonly used by Web pages: move methods and field objects.

Move Methods

The move methods allow you to change which record is current, thereby changing the values displayed in any bound elements. The methods used to move the current record pointer are: Move, MoveNext, MovePrevious, MoveFirst, and MoveLast. The Move method takes an argument to move the current record pointer to the specified position in the recordset. The functions of the other move methods are self-explanatory.

ADOR allows you to move the current record pointer before the first record in the data set (BOF, or beginning of file) or after the last record in the data set (EOF, or end of file). Because these positions have no data associated with them, moving to these positions will result in all bindings on the page having null values, which usually means nothing is displayed. This problem can be avoided by checking the current position in the recordset prior to moving the pointer. The following code checks whether the current record is the last record in the recordset prior to advancing the current record pointer:

<SCRIPT LANGUAGE="JavaScript" FOR=NextButton EVENT=onclick>
   if (stocklist.recordset.AbsolutePosition <
       stocklist.recordset.RecordCount)
      stocklist.recordset.MoveNext();
   else
      alert("Already at last record.");
</SCRIPT>


NOTE: The current record position can also be changed by setting the AbsolutePosition property on the recordset.

The fields Collection/The field Object

The fields collection provides a set of field objects for a recordset. A field object corresponds directly to a single column of data. The field object is used to read data values from the column for the current record of the recordset. For example, the data for the current record in a column named Last could be obtained using the following lines of code, all of which return the same value:

stocklist.recordset.Fields("Last").value
stocklist.recordset.Fields("Last")
stocklist.recordset("Last")

Assigning a value to the Value property of the field object modifies the value. The following code sets the last stock price in the current record to 103.0:

stocklist.recordset("Last") = 103.0;

Again, any of the three equivalent forms could be used to write this statement.

For more details about ADOR, consult the Internet Client SDK (Software Development Kit), available from the Microsoft Web site at www.microsoft.com/msdn/sdk/inetsdk.

Script Events

Internet Explorer 4.0 provides a rich event set to enable Web authors to write scripts in response to user actions on data-bound pages. The event set can be divided into two categories. One category of events fires on data-consuming elements. These events (onbeforeupdate, onafterupdate, and onerrorupdate) provide for validation of user input. The second category of events (onrowexit, onrowenter, ondatasetchanged, ondataavailable, and ondatasetcomplete) fires on data source objects to enable validation and processing when a new record becomes current or in response to data being asynchronously transmitted to the client. An additional event, onbeforeunload, is not specific to data binding but is particularly useful in data-binding applications. The following sections describe these events in greater detail.


NOTE: As with all events in the Dynamic HTML object model, the events described in this section bubble up the containment hierarchy. Handlers for them can be written at any level of the hierarchy. If multiple data source objects are present on the page, the Web author can include a single handler for any event in a common container to process the event.

The onbeforeupdate Event

The onbeforeupdate event fires on HTML elements that support data updating. (See Table 15-1 earlier in this chapter for a list of data consumers that support updating.) The onbeforeupdate event fires when the user moves the focus from an element whose value has been updated and before the updated data is transmitted to the data source object by the binding agent. The previous value of the data can be obtained from the data source object using the ADOR recordset. The onbeforeupdate event can be used by the Web author to perform validation. If the Web author cancels the event, the focus remains on the element and the data is not transmitted to the data source object.

The following code demonstrates a handler for the onbeforeupdate event. In this example, the value in the HTML text box is verified to be in the range 5 through 15. If the value is outside the range, an error message is displayed and the event is canceled.

<SCRIPT LANGUAGE="JavaScript" FOR=textbox1 EVENT=onbeforeupdate>
   if (textbox1.value < 5 || textbox1.value > 15)
   {
      alert("Number must be in the range 5 through 15.");
      returnValue = false;
   }
</SCRIPT>

The onafterupdate Event

The onafterupdate event is also fired on HTML elements that support updating; however, it fires immediately after the data is transmitted from the element to the data source object. The onafterupdate event is not fired if the onbeforeupdate event is canceled, and onafterupdate itself is not cancelable.

One use of onafterupdate is for updating the value of a calculated amount. For example, suppose the user is filling out an order form, has selected an item, and is now selecting the quantity. When the quantity is entered, you want to calculate the line item total based on the price of the item and the quantity requested. You can accomplish this in the handler for the onafterupdate event of the text box in which the quantity is entered:

<SCRIPT LANGUAGE="JavaScript" FOR=quant_tbox EVENT=onafterupdate>
   line_total.value = quant_tbox.value * item_price.value;
</SCRIPT>

The onerrorupdate Event

The onbeforeupdate and onafterupdate events span the transfer of data from the HTML element to the data source object. But these two events don't cover the rare case in which the transfer of the data fails. In this case, the onerrorupdate event fires.

The onerrorupdate and onafterupdate events are mutually exclusive—that is, onafterupdate fires only if the data transfer succeeds, and onerrorupdate fires only when the data transfer fails. The onerrorupdate event provides the Web author with an opportunity to display a sensible error message to the user when the data transfer fails.


NOTE: A data transfer occurs when the binding and repetition agent notices that the value in a bound element has changed. But the binding and repetition agent might not notice the change in value immediately after the change takes place. For example, if a bound value is changed through a script, the binding and repetition agent won't notice the change until the current record pointer is moved or the page is unloaded.

Additionally, because an object or applet is not required to fire notifications when the value of one of its bound properties changes, the binding and repetition agent automatically transfers data from an object or applet when the current record pointer is moved or the page is unloaded, even if the value has not changed.


The onrowexit Event

The onrowexit event is the first of the set of events that fire on the data source object. Recall that each data source object has one record that is the current record. A different record can be made current by using the move methods in ADOR. The onrowexit event fires on the data source object to signify that the current record pointer is about to be moved.

A number of steps must take place before onrowexit is fired. First the current record pointer must be requested to move, generally by the execution of a move method on the ADOR recordset. Once the request is received, the binding agent examines each bound HTML element to determine whether any data items from the current record have been modified. It does this by comparing the value in the element to the value in the column of the data source object. If the columns differ, the binding agent fires the onbeforeupdate event on that element. If the event is canceled, the sequence is terminated and the current record pointer remains unmoved. If onbeforeupdate is not canceled, the onafterupdate event is fired on the element. This process is repeated for each bound HTML element. After all elements have been synchronized, the onrowexit event is fired on the data source object.

The onrowexit event is cancelable. When the Web author cancels the event, the current record pointer remains in place. The onrowexit event is useful for performing record-level validation or for recalculating columns of the data source object that are not bound but are based on the values in other columns.

The following example shows an onrowexit handler:

<SCRIPT LANGUAGE="JavaScript">
   function myrowexit() {
      if (stocklist.recordset("Last") * stocklist.recordset("Shares")
            > my_cash_balance) {
         alert("Purchase exceeds cash position in your account.");
         returnValue = false;
      }
   }
</SCRIPT>

The onrowenter Event

As its name implies, the onrowenter event fires immediately after the current record pointer has been moved. When it fires, all data from the new current record will be present in the HTML elements bound to the data source object.

The onrowenter event is not cancelable because the data from the new current record is already displayed to the user. The onrowenter event is useful for calculating fields based on the data elements in a row. The following example demonstrates how to use onrowenter:

<SCRIPT LANGUAGE="JavaScript">
   function myrowenter() {
      total_value.text =
         stocklist.recordset("Price") * stocklist.recordset("Shares");
   }
</SCRIPT>

The ondatasetchanged Event

Web authors need to know when the data source object is ready to supply data, and the ondatasetchanged event is the first of three events available to help. The ondatasetchanged event fires on the data source object as soon as data is available, signifying that the ADOR recordset can now be obtained from the data source object. The ondatasetchanged event is not cancelable.

In addition to firing when an HTML page is initially displayed, ondatasetchanged fires when data source objects perform data manipulations. This manipulation can be in response to a reordering of the data set caused by sorting or to a change in the underlying structure of the data set (number of rows or columns, or column names) caused by filtering.

The ondataavailable Event

Web authors can be notified when more data from a data source object has arrived by handling the ondataavailable event. The ondataavailable event fires when data from a data source object has been received by the browser; ondataavailable is not cancelable.

The data source object determines the firing frequency of ondataavailable. For performance reasons, most data source objects don't fire ondataavailable for each record displayed. Instead, data source objects will collect a number of rows as a block and fire ondataavailable for the block of rows. The ondataavailable event does not, however, indicate the number of rows available nor does it indicate their position within the data set. This information must be determined directly from the ADOR recordset.

The ondataavailable event can be used to calculate a running total of records as they are received or to perform script operations as data arrives in the browser:

<SCRIPT LANGUAGE="JavaScript">
   var count;
   function myondataavailable() {
      total_stocks.value = stocklist.recordset.RecordCount;
   }
</SCRIPT>

The ondatasetcomplete Event

Rounding out the set of asynchronous events is the ondatasetcomplete event. Probably the most useful asynchronous event, ondatasetcomplete notifies the Web author that asynchronous transmission is complete and the entire data set is available.

The ondatasetcomplete event sets the reason property on the event object to inform the Web author of the status of the transmission. The following table lists the three possible values for the reason property.


Value Description
0 Transmission was completed without error.
1 User aborted the transmission. Generally, this interruption occurs when the user clicks the Stop button on the page.
2 Transmission generated an error. This is the catchall case for transmission failures of all sorts, including the inability to contact the host or a dropped connection.

The onbeforeunload Event

The onbeforeunload event is not specific to data binding, but handling it can be useful for avoiding data loss on data-bound pages. Some data source objects can cache updates to the data they supply on the client until a method is invoked on the object to save the updated values to the server. Because these values can be cached, the user can attempt to navigate away from the page prior to saving the updated values. The onbeforeunload event can be used to prompt the user to cancel the navigation, avoiding the loss of the changes.

The operation of the onbeforeunload event is somewhat different from the other events discussed so far. The onbeforeunload event fires in response to a request from the user to navigate to a new page—for example, when the user clicks on a hyperlink, clicks the Back or Forward button, or types a new URL in the address bar. The onbeforeunload event fires on the window object prior to the unload event on a page. When the event fires, the Web author can set the returnValue property on the event object to a string value, which will be displayed to the user along with a standard message from the browser explaining that the user has the option to cancel the requested navigation. Generally, Web authors will return a message instructing the user that continuing with the navigation will result in the cached changes being discarded. If the user chooses to cancel the navigation, the page remains visible and the user can interact with it as if the hyperlink or other navigation method was never invoked. If the user continues the navigation, the page is unloaded and the changes to the data are discarded.


Canceling the unload Event Requires User Interaction

Shouldn't the author be able to simply cancel the unload event without prompting the user? The answer to this question is centered in operating system security issues. If the Web author were able to cancel the unload event, it would be possible to create a page that would never unload—that is, the unload event would always cancel the navigation. The only way for the user to navigate away from the page would be to kill the browser process, which is a violation of basic operating system integrity because the user should be in control of his or her local machine and processes at all times. Although onbeforeunload can be canceled, it is the user who chooses to cancel the unload event, not the Web author. The Web author only has the ability to provide the user with an informational message.


[Содержание]