
Microsoft® Internet Explorer 4.0 enables content providers to develop data-centric Web applications that support retrieval and update through native data binding facilities. The use of HTML extensions and pluggable data source objects makes data-driven pages easy to author with minimal scripting required. Because data is downloaded to the client asynchronously, pages render quickly and provide immediate interactivity. Once downloaded, the data can be sorted and filtered without requiring additional trips to the server. Compare that to traditional Web pages and those generated by server-side scripts. Once the data reaches the client, it's static, and any manipulation of that data requires another server request.
Consider a simple example, the list of samples in the Internet Client SDK. While the list could be hard-coded into this text, a better solution is to store the data external to the document in a delimited text file. If the samples change, only the data in the database needs to be modified. Once the modifications are made, this page and any others that display that data will reflect the changes.
While this maintenance issue justifies the use of data binding in place of a static page, consider a slightly more complex scenario, an online classical music catalog maintained on a server in a relational database management system. Using today's server-side technologies such as the Common Gateway Interface (CGI), the Internet Server API (ISAPI), or one of its derivatives such as Active Server Pages (ASP), a developer can write a script to extract a subset of data based on criteria specified by the client, such as all titles by a particular composer. The script might generate and return to the client a Web page including a tabular view of this data, including the title, the year composed, the type of composition, and a list of the movements in the composition. While the page may contain the information in date order, if the user wants to view the compositions in alphabetical order or to limit their view to orchestral works or fugues, the user is forced to submit additional requests to the server. This is an expensive way to view the same data in only a slightly different way. The problem is compounded if the Web author decides to present each composition in single record view, that is, one record per page. A full round-trip to the server is required to obtain each subsequent record.
If Web authors want to allow the user to add or update the data, they typically create HTML forms and submit GET and POST requests to an application running on the server. The server application parses out the data from an HTTP data stream and then logs the data to a database. For every update request, the page containing the Submit button and the form data is reloaded. This is not a seamless experience for the user.
The following sections show how the various components in the data binding architecture offer solutions to these problems and make the most efficient use of the Web.
Adding a Data Source Object to a Page
DHTML Object Model Support for Data Binding
DHTML Event Model Support for Data Binding
Microsoft Tabular Data Control (TDC)
Microsoft Remote Data Service (formerly ADC)
Data binding is based on a component architecture consisting of four major piecesdata source objects, data consumers, the binding agent, and the table repetition agent. Data source objects provide the data to a page, data-consuming HTML elements display the data, and the agents ensure that both provider and consumer are synchronized. The following diagram illustrates how the components fit together.
To bind data to the elements of an HTML page in Internet Explorer 4.0, a data source object (DSO) must be present on that page. DSOs implement an open specification that leaves it to the DSO developer to determine the following:
A DSO typically exposes this functionality through an object model accessible to scripts.
The only strict requirement imposed upon a DSO is that it must provide access to its data through the OLE DB or OLE DB Simple Provider APIs. Because all DSOs provide data access through a standard set of interfaces, MSHTML extends the object model of the DSO with a standard set of properties, methods, and events. It is through this object model that scripts can manipulate the data.
Specifics on adding a DSO to a page are provided below. Information on implementing custom data source objects is available in IE4/MSHTML Data Binding Interfaces.
Data consumers are elements on the HTML page capable of rendering the data supplied by a DSO. Elements include many of those intrinsic to HTML, as well as custom objects implemented as Java applets or ActiveX Controls. Internet Explorer 4.0 supports HTML extensions to allow authors to bind an element to a specific column of data in a data set exposed by a DSO. Applets and ActiveX Controls support additional binding semantics described below.
Elements support the consumption of either single-valued or tabular data. Single-valued consumers such as INPUT elements consume a single value from the current record provided by a data source. Tabular data consumers such as the TABLE element repeat an entire set of records from a data provider. This is called set binding.
The section on HTML extensions explains the extended attributes that allow Web authors to bind elements to the data supplied by a DSO. For further information on the individual elements that support data binding, see Binding an HTML Element to Data.
The binding and repetition agents are implemented by Mshtml.dll, the HTML viewer for Internet Explorer 4.0, and they work completely behind the scenes. When a page is first loaded, the binding agent finds the DSOs and the data consumers among those elements on the page. Once the binding agent recognizes all DSOs and data consumers, it maintains the synchronization of the data that flows between them. For example, when the DSO receives more data from its source, the binding agent transmits the new data to the consumers. Conversely, when a user updates a data bound element on the page, the binding agent notifies the DSO.
To signal the Web author of important changes in the state of the data caused by providers and consumers, the binding agent fires a variety of scriptable events.
The repetition agent works with tabular data consumers such as the HTML TABLE element to repeat the entire data set supplied by a DSO. Note that individual elements in the table are synchronized through interaction with the binding agent.
To enable Web authors to add data binding to their pages, Internet Explorer 4.0 provides support for several new HTML attributes. All data binding-related HTML attributes correspond to a similarly named property in the Document Object Model. The following section introduces these attributes and describes their use.
The key to data binding is connecting a data source object to a data consumer. To achieve a binding between a data source object (DSO) and a data consumer, Internet Explorer 4.0 extends HTML to support the following attributes:
| DATASRC | Specifies the identification of the DSO to which a consumer is bound. |
| DATAFLD | Identifies the specific column exposed by the DSO to which the element is bound. |
| DATAFORMATAS | Indicates how the data in the specified column should be rendered. |
| DATAPAGESIZE | Indicates how many records are displayed in a table at once. |
Bound elements fall into two specific categories:
The binding agent takes a single value from the current record of a data source and passes it to a single-valued consumer. The repetition agent works with the binding agent to pass the entire set of records to a tabular data consumer.
By specifying the DATASRC and DATAFLD attributes on a single-valued data consuming element of a Web page, the Web author fully specifies the binding of an element to data. By specifying DATAFORMATAS on a single-valued element, the Web author indicates how the data should be interpreted. DATAPAGESIZE allows the author to restrict the number of records that are displayed by a tabular consumer. All these properties can be set at run time through the document object model.
Here's a sample declaration for a single-valued data consuming element that might appear on an HTML page.
<SPAN DATASRC=#dsoComposer DATAFLD=compsr_first></SPAN>
The DATASRC attribute in this example is set to the ID (dsoComposer) of a data source object (DSO) embedded on the page. The DATAFLD is set to the name of a column in the data set provided by the DSO. For this binding to succeed, the data set retrieved by the DSO must contain a column named "compsr_first".
Click the Show Me button to see a working example.
The following example shows how a table, a tabular data consumer, can be bound to a data source object. The repetition agent uses the table row (TR) in the table body as a template. As the DSO identified in this example as "dsoComposer" supplies each record in the data set, the template including the DIV is repeated, until all composers' first names are displayed.
<TABLE DATASRC=#dsoComposer>
<TR><TD><DIV DATAFLD=compsr_first></DIV></TD></TR>
</TABLE>
Click the Show Me button to see a working example that uses the TDC to display a table of composers, including their first and last name, date of birth and death, and country of origin.
The data supplied by a DSO can be in a variety of formats, and the page author can use the DATAFORMATAS attribute on single-valued consumer elements that support the attribute to indicate how the data should be rendered. In Internet Explorer 4.0, HTML and TEXT are the valid values for this attribute.
<MARQUEE DATASRC=#dsoAdvertisement DATAFLD=banner
DATAFORMATAS=html>
</MARQUEE>
The previous example describes a MARQUEE that calls upon a data source object that supplies various banners for display in a page. Click the Show Me button to see how a timer can be used to randomly select and display an advertisement supplied by a data source.
When binding a TABLE to a data source, all the records in the data set will be displayed by default. If the data set is large, the page may grow beyond what is visible to the user. In addition, any content positioned below the table will get pushed off the screen. The DATAPAGESIZE attribute can be applied to a TABLE to specify the maximum number of records that should be displayed at any one time. To enable the user to move to the next and previous page of records viewed in the table, Web authors can use the nextPage and previousPage methods exposed by the TABLE object in the document object model. Authors can also change the page size of the table at run time by setting the dataPageSize property. Click the Show Me button to see how it works.
In addition to limiting table size, Web authors should investigate the specific functionality exposed by the DSO they have chosen for use on their HTML page. Both the TDC and RDS provide filtering capabilities.
Once a Web author has identified the data that she wishes to display on a page, the next step is to choose the data source object (DSO) that will supply that data and to add a reference to that DSO to that page. Internet Explorer 4.0 ships with a number of data source objects. These include
In addition to these data providers, Microsoft maintains a gallery of data source objects. Jump to this site to learn about other data providers as they become available.
A DSO can be implemented as an ActiveX control or as a Java applet. The OBJECT tag is used to embed an ActiveX control on the page; the APPLET tag is used to embed a Java applet on the page. In general, Web authors can copy and paste the appropriate OBJECT or APPLET declaration corresponding to the DSO of their choosing and modify the PARAM tags appropriately. So that elements on the page can bind to the data source, the declaration should include the ID attribute.
Because the data source object specification imposes no requirements on the DSO regarding the object model it exposes, Web authors should familiarize themselves with the documentation associated with the DSO they select to provide data to their page.
The TDC is a simple DSO that provides access to delimited text files. This is the DSO used in the majority of the samples provided with this section. Consider using the TDC if:
The following example represents a declaration specific to the Tabular Data Control (TDC).
<OBJECT CLASSID="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"
ID=dsoComposer WIDTH=0 HEIGHT=0>
<PARAM NAME="DataURL" VALUE="composer.csv">
</OBJECT>
DataURL is a property specific to the TDC. The TDC uses this property to allow an author to specify the data set that should get loaded along with the page. For more information about the TDC, see the companion documentation for this component in the Component Library included with the Internet Client SDK.
The Remote Data Service is a more sophisticated DSO that ships with Internet Explorer 4.0. RDS obtains its data from a database using OLE-DB or ODBC. Consider using RDS if:
A declaration specific to RDS follows:
<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"
ID=dsoComposer HEIGHT=0 WIDTH=0>
<PARAM NAME="Server" VALUE="http://musicserver">
<PARAM NAME="Connect" VALUE="dsn=music;uid=guest;pwd=">
<PARAM NAME="SQL" VALUE="select compsr_name from composer">
</OBJECT>
First, note the class identifier (CLSID) specific to RDS. Every ActiveX component requires a CLSID to differentiate it from other objects registered on the system. Next, note that the base properties exposed by RDS differ significantly from those exposed by the TDC. That's because the TDC derives its data from a flat text file, while the RDS is capable of retrieving and updating data from any OLE-DB or ODBC-compliant database. The following are the properties specified in the example declaration above:
| Server | String identifying the protocol and the server that supplies the data. |
| Connect | Standard ODBC connection string identifying the data source name configured on the server. |
| SQL | SQL query identifying the table and columns to be selected from the database. |
For the specifics on how to use RDS, see the companion documentation in the Component Library of the Internet Client SDK.
The JDBC DataSource Applet is a DSO available for download from the Microsoft Data Source Object Gallery. Consider using this applet if:
<APPLET CODE=JDC.class NAME="DSA1" ID="DSA1" WIDTH=0 HEIGHT=0>
<PARAM NAME=cabbase VALUE=
"http://www.microsoft.com/gallery/files/datasrc/jdbcapplet/jdc.cab">
<PARAM NAME=dbURL VALUE="jdbc:odbc:Northwind">
<PARAM NAME=showUI VALUE=false>
<PARAM NAME=sqlStatement VALUE="select ProductName, CompanyName,
CategoryName from Products, Suppliers, Categories where
Suppliers.SupplierID=Products.SupplierID and Categories.CategoryID =
Products.CategoryID and Categories.CategoryID < 5">
<PARAM NAME=allowInsert VALUE="true">
<PARAM NAME=allowDelete VALUE="true">
<PARAM NAME=allowUpdate VALUE="false">
<PARAM NAME=user VALUE="">
<PARAM NAME=password VALUE="">
</APPLET>
Instead of a CLSID, the CODE attribute uniquely identifies the DSO. Note that the basic properties exposed by this DSO differ from those exposed by the TDC or RDS. The following properties are specified in the example declaration above:
| cabbase | General property, applicable to all applets, that specifies the location of the code for the applet. The code will be downloaded to the client if not already installed. |
| dbURL | Required string that identifies the ODBC data source name (DSN) configured in the user's control panel. |
| showUI | Optional Boolean value indicating whether a user interface should be displayed. |
| sqlStatement | SQL string identifying the table and columns to be selected from the database. |
| allowInsert | Boolean value indicating whether new records can be inserted into the data set. |
| allowDelete | Boolean value indicating whether existing records can be deleted. |
| allowUpdate | Boolean value indicating whether existing records can be updated. |
| user | Optional string identifying the user. Some ODBC data sources require authentication. |
| password | Optional string identifying the specified user's password. |
Extensible Markup Language (XML) describes data and structured text on the Web in a standard way. Internet Explorer 4.0 ships with an application that serves as an XML data provider. While the XML DSO is a read-only data provider, Web authors should consider using it to display hierarchical data.
To use the XML data source object, add an APPLET tag to your page, as in the following:
<APPLET
CLASS=com.ms.xml.dso.XMLDSO.class
ID=xmldso
WIDTH=0
WIDTH=0
MAYSCRIPT=true>
<PARAM NAME=URL VALUE="composer.xml">
</APPLET>
Since the DSO is implemented in Java, embedding it on the page requires the use of the APPLET tag. The CLASS attribute specifies the package in which the code is implemented. The URL property specifies the location of the data. The XML DSO retrieves the XML from this location, parses it, and provides the data to bound elements on the page. The data consuming elements are isolated from the details of XML.
Click the Show Me button to see a simple example that uses the XML DSO to display an XML data set in a tabular format.
The following example shows how the XML DSO can be used to bind nested tables to hierarchical XML data. The XML data contains a list of CUSTOMERS. Each customer contains a list of ORDERS. Each order contains a list of ITEMS yielding three levels of repetition bound to three nested tables.
For additional information on XML, see the following resources:
In addition to using external components as data source objects, Web authors can define their data sets within an HTML document and use MSHTML itself to provide read-only data to a page. For the purposes of this section, the page supplying the data is called the data page.
When MSHTML is used as a DSO, it parses through the data page in search of elements with an ID attribute. The set of unique IDs defines the columns in the data set, and Web authors use these ID attributes as the value for the DATAFLD attribute on elements of the bound page. For example, given the following SPAN from a data page, MSHTML interprets compsr_last as the name of a column and Mozart as data in that column.
<SPAN ID=compsr_last>Mozart</SPAN>
Multiple elements on the page sharing the same ID identify additional records in the data set. A column that is not represented is given the null value in the corresponding data set. Only elements with an opening and closing tag (for example, DIV, SPAN, H1) can be used to supply data. The following example defines a two-column table consisting of three records.
<<H1 ID=COMPSR_FIRST>Hector</H1> <MARQUEE ID=COMPSR_LAST>Berlioz</MARQUEE> <DIV ID=COMPSR_BIRTH>1803</DIV> <H2 ID=COMPSR_FIRST>Modest</H2> <H3 ID=COMPSR_LAST>Moussorgsky</H3> <BUTTON ID=COMPSR_BIRTH>1839</BUTTON> <TEXTAREA ID=COMPSR_FIRST>Franz</TEXTAREA> <XMP ID=COMPSR_LAST>Liszt</XMP> <SPAN ID=COMPSR_BIRTH>1811</SPAN>
Observe that the MSHTML DSO disregards the lack of consistency in the elements used. In the example above, the H1, H2, and TEXTAREA elements represent the data for the first name column in the data set; the P, H3, and XMP elements represent the last name column; the DIV, BUTTON, and SPAN elements represent the date of birth column.
Once the data page is defined, use an OBJECT tag on the data bound page to supply the data as follows:
<OBJECT ID=htmlComposer DATA="compdata.htm" HEIGHT=0 WIDTH=0> </OBJECT>
The DATA attribute points to the data page and can specify a complete or relative URL.
Elements on the page used to present the data can be bound using the data binding extensions.
Click the Show Me button to see how the MSHTML DSO works.
While the components described above are implementations of data source objects (DSO) provided with Internet Explorer 4.0 and available through the DSO gallery, the specification is completely open and language independent so that independent software vendors (ISVs) can create their own data providers. For more information on creating a DSO, see the COM Objects as Data Providers document.
To display the data provided by a data source object (DSO), the page author binds elements on an HTML page to the DSO. Using the data binding extensions or the corresponding data binding properties makes it easy. This section shows how to bind an element to data, the elements that support data binding, and the capabilities of those elements. Capabilities include support for updating the data to which an element is bound and the format in which the data is displayedHTML or plain text.
Bindable HTML elements fall into two categoriessingle-valued and tabular consumers. Single-valued consumers bind to a single field of the current record provided by a DSO. Tabular consumers bind to an entire data set and use their contained elements as a template to repeat the data. In Internet Explorer 4.0, the TABLE element is an example of a tabular data consumer, and the procedure for binding it to data is described below.
The procedure for binding a single-valued element to data is the same regardless of the element. Elements can be bound to data at design time using the DATASRC and DATAFLD attributes or at run time using the dataSrc and dataFld properties exposed by the corresponding objects in the document object model.
To specify a complete binding to a field in a data set, data-consuming elements use the DATASRC and DATAFLD attributes. Given a text box, for example, a page author can bind that element to data as follows:
<INPUT TYPE=TEXTBOX DATASRC=#dsoComposers DATAFLD=compsr_last>
The DATASRC attribute in this example specifies the ID, prefixed by a hash mark (#), of a data source object (DSO) embedded on the page. The hash mark is required. The DATAFLD attribute identifies the field in the data provided by the DSO to which the text box should be bound.
Click the Show Me button to see how it works.
Because the TABLE element is a tabular data consumer, it relies upon the elements that it contains to bind to the individual fields in the data set provided by the DSO. The contained elements serve as a template, and they are repeated once for each record in the data set. The TABLE specifies the DATASRC attribute. The contained elements specify the DATAFLD attribute and inherit the DATASRC from the table. Here's a simple example:
<TABLE DATASRC=#dsoComposer>
<TR><TD><SPAN DATAFLD=compsr_first></SPAN></TD></TR>
</TABLE>
Click the Show Me button to see how it works.
As with single-valued consumers, a tabular data consumer can be bound to data at run time using the document object model. The procedure for accomplishing this is described below.
The previous sections used a TEXTBOX, a SPAN, and a TABLE element to illustrate how to bind single-valued and tabular consumers to the data provided by a DSO. Many other HTML elements can be bound to data. Some of these elements support updating the data to which they are bound. Changes can be persisted to the back-end data set if the DSO supports update. Other elements support rendering of the data as HTML in addition to the plain text default using the DATAFORMATAS attribute.
The following table presents the single-valued HTML elements that support data binding. Additional columns indicate:
Use the drop-down list to filter the elements appropriately.
| Element | Updatable | Renders HTML | Bound Property |
Bindable HTML elements that supply read-only functionality include A (anchor), BUTTON, DIV, IMG (image), FRAME, IFRAME, LABEL, MARQUEE, and SPAN.
Additionally, the BUTTON, DIV, LABEL, MARQUEE, and SPAN elements support the usage of the DATAFORMATAS attribute and the corresponding dataFormatAs property to render the data to which they are bound as plain text (default) and as HTML. The data displayed by the element is automatically updated as the record pointer maintained by the DSO moves or the underlying data to which the element is bound changes. Individual descriptions for these elements follow.
A
An anchor element applies the data supplied by a DSO to the HREF attribute; thus, the supplied data should represent a URL. An example of a bound anchor is:
<A DATASRC=#dsoLinks DATAFLD=link_href><SPAN DATASRC=#dsoLinks DATAFLD=link_friendly></SPAN></A>
BUTTON
A BUTTON element renders the data supplied by a DSO on its face. An example of a bound BUTTON is:
<BUTTON DATASRC=#dsoLinks DATAFLD=link_friendly></BUTTON>
Click the Show Me button to see a working example.
DIV
A DIV element is useful for displaying a block of text. An example of a bound DIV is:
<DIV DATASRC=#dsoComposer DATAFLD=compsr_biography></DIV>
IMG
An IMG element applies the data supplied by a DSO to locate, load, and display the image typically pointed to by its SRC attribute. Supplying raw image data through the bound column is not supported.
An example of a bound IMG tag is:
<SPAN DATASRC=#dsoImages DATAFLD=image></SPAN>
Click the Show Me button to see a working example.
FRAME
A FRAME element applies the data supplied by a DSO to its HREF attribute; thus, the bound value should represent a URL. So that the binding occurs successfully, the data source object supplying data to a bound frame should be present in the HEAD section of the HTML file containing the FRAMESET. An example of a bound FRAME is:
<HTML>
<HEAD>
<<!-- Add DSO reference here -->
</HEAD>
<FRAMESET>
<FRAME DATASRC=#dsoFAQ DATAFLD=frame_question ...>
<FRAME DATASRC=#dsoFAQ DATAFLD=frame_answer ...>
</FRAMESET>
</HTML>
The code behind the following Show Me button implements a frame-based FAQ. The first frame displays the question; the second frame displays the answer; the third frame contains navigation buttons. The first and second frames are bound to a two-column table. The first column in the table contains relative paths to pages containing questions. The second column contains relative paths to pages containing the answers. Since the DSO is embedded in the HEAD of the outer page containing the FRAMESET, the code behind the navigation buttons drills out of the page in which it resides using the top object and references the DSO by its ID. top returns an object reference to the outermost containing window.
IFRAME
An IFRAME element applies the data supplied by a DSO to its HREF attribute; thus, the data should represent a URL. In contrast to the FRAME case, the DSO can be declared anywhere on the page. An example of a bound IFRAME is:
<IFRAME DATASRC=#DSC1 DATAFLD=iframe_url>
Click the Show Me button to see a working example.
LABEL
Use a LABEL element to describe another bound element on the page. A label applies the data supplied by a DSO to its caption. An example of a bound LABEL is:
<LABEL FOR=somecontrolid DATASRC=#DSC1 DATAFLD=label_col></LABEL>
Since a LABEL is associated with other elements indicated by its FOR attribute, using a bound LABEL within a repeated table can yield unexpected results. If the FOR attribute references another element within the repeated table, the LABEL tag will not be associated with the elements, since there will be multiple elements with the same ID/NAME as a result of the repetition.
MARQUEE
A MARQUEE element uses its bound data to replace the text that appears between its opening and closing tags.
An example of a bound MARQUEE is:
<MARQUEE DATASRC=#dsoComposer DATAFLD=bio DATAFORMATAS=HTML></MARQUEE>
Click the Show Me button to see a working example.
SPAN
Like a DIV, a SPAN is a read-only data consumer. Use a SPAN to display inline text or limited HTML text. If the SPAN is used to display HTML text, that text should not include any HTML block elements. When the current record or the underlying value in the bound column provided by the DSO changes, the SPAN reflects the change. An example of a bound SPAN is:
<SPAN DATASRC=#dsoComposer DATAFLD=compsr_last></SPAN>
Click the Show Me button to see a working example.
The APPLET, INPUT (with the exception of the button type), SELECT, TEXTAREA, and OBJECT elements support updating the data to which they are bound if the underlying DSO supports update functionality. Descriptions of these individual elements follow.
INPUT
The INPUT element represents a set of HTML intrinsic controls. Each of the types that support data binding is detailed in the following sections.
RADIO
Radio buttons are used to select a single value from a set of alternatives. These can be used to select the value for an enumerated field in a database. One radio button is specified for each of the alternatives using a separate INPUT. The NAME attribute on the INPUT determines the logical grouping of alternatives. One value is bound for all the INPUTs with the same NAME attribute. All members of a group must specify the corresponding DATASRC and DATAFLD attributes.
An example of a bound radio button group is:
<INPUT TYPE=RADIO NAME=cards VALUE=mc DATASRC=#dsoOrders DATAFLD=cardname>MasterCard <INPUT TYPE=RADIO NAME=cards VALUE=amex DATASRC=#dsoOrders DATAFLD=cardname >American Express <INPUT TYPE=RADIO NAME=cards VALUE=visa DATASRC=#dsoOrders DATAFLD=cardname >Visa
Click the Show Me button to see a working example.
CHECKBOX
Although check boxes allow a value attribute that is used when submitting an HTML form on a page, IE4/MSHTML uses check boxes as simple Boolean selections. Check boxes generate the Boolean values TRUE or FALSE depending on whether they are checked or not. The binding agent coerces the values to and from the underlying data set. The following coercions are supported based on the type of the bound column.
The following table describes the values that a bound check box expects a DSO to supply for various data types.
| Data type | Expected True Value | Expected False Value |
| String | "True" | "1" | <non-empty string> | "False" | "0" | <zero-length string> |
| Integer | non-zero | 0 |
| Float | non-zero | 0 |
| Date | invalid | invalid |
| Currency | non-zero | 0 |
An example of a bound check box is as follows:
<INPUT TYPE=CHECKBOX DATASRC=#dsoSurvey DATAFLD=us_resident> U.S. Resident
Click the Show Me button to see a working example.
TEXT
The TEXT type is used as a simple text box. The value of the text box can be bound to a field in the data source using the DATASRC and DATAFLD attributes.
An example of a bound text box is:
<INPUT TYPE=TEXT DATASRC=#DSC1 DATAFLD=name>
HIDDEN
The HIDDEN type is used to store information in the page that isn't displayed to the user. The element is populated with data from the current record, but it cannot be modified.
An example of a bound hidden field is:
<INPUT TYPE=HIDDEN DATASRC=#DSC1 DATAFLD=key>
PASSWORD
The PASSWORD type is basically the same as the TEXT type except that the bound text is not displayed to the user. Use this input type with care since the associated data is fully accessible to scripts through the data-binding object model, as well as directly through the element's value.
An example of a bound password is:
<INPUT TYPE=PASSWORD DATASRC=#DSC1 DATAFLD=password>
SELECT
A SELECT element supplies the functionality of a drop-down list (combo box) or a list box. Internet Explorer supports binding to a single selected element; binding to multiple selections is not supported.
The items in a SELECT control are specified using OPTION tags. The document object model defines an options array that corresponds to the collection of OPTION tags for a SELECT. Each OPTION has a corresponding index, text, and value. The SELECT has a selectedIndex property that corresponds to the index of the OPTION currently selected. If no item is selected, the selectedIndex is set to -1. The text attribute of an OPTION corresponds to the text following the OPTION tag and represents the string that is displayed for that OPTION in the SELECT. The VALUE attribute provides the value that is to be returned when the HTML form is submitted. Value is also what is stored into the bound column of the data source.
Initially, the selectedIndex property of a bound SELECT control will be set to the index of the value in the options array corresponding to the field of the data source. If the value is not a member of the options array, the index property is set to -1 and, if the SELECT is a combo, no value is displayed. When a user changes the selected item, the corresponding OPTION value (attribute) is used to update the value of the bound field of the data source. Validation events are fired as with other controls.
An example of a bound SELECT is:
<SELECT DATASRC=#DSC1 DATAFLD=cardname> <OPTION VALUE=mc>MasterCard <OPTION VALUE=amex>American Express <OPTION VALUE=visa>Visa </SELECT>
Click the Show Me button to see a working example.
TEXTAREA
A TEXTAREA is a multirow text box for data input similar to the INPUT TYPE=text intrinsic. As such it supports the update of the data if the DSO supports the update feature.
An example of a bound TEXTAREA is:
<TEXTAREA DATASRC=#dsoComposer DATAFLD=bio></TEXTAREA>
Click the Show Me button to see a working example.
OBJECT
When DATASRC and DATAFLD are specified on an OBJECT, Internet Explorer 4.0 attempts to bind to the object's default property. The defaultbind attribute specified in an object's type information uniquely identifies the default property. If a default property is not specified in this way, Internet Explorer 4.0 uses the property with DISPID 0.
An example of binding the default value on the object tag is:
<OBJECT ID=oControl1 WIDTH=100 HEIGHT=100
CLASSID="CLSID:xxxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxxxxxx"
DATASRC=#DSC1 DATAFLD=controlData>
</OBJECT>
Additionally, Internet Explorer 4.0 supports binding to arbitrary OBJECT properties through the object's contained PARAM tags. Apply the DATASRC and DATAFLD attributes to the PARAM tag. The property is initialized with the data supplied by the DSO.
An example of binding the PARAMs on the object tag is:
<OBJECT ID="oControl1" WIDTH=100 HEIGHT=100
CLASSID="CLSID:xxxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxxxxxx">
<PARAM NAME="ForeColor" DATASRC=#DSC1 DATAFLD=forecolor>
<PARAM NAME="BackColor" DATASRC=#DSC1 DATAFLD=backcolor>
</OBJECT>
Bindings can be simultaneously applied to both the object's default value as well as its PARAM tags.
APPLET
Internet Explorer 4.0 supports binding to the PARAM tags of an APPLET. For example, the following specifies a binding on the xyz property of the application:
<APPLET CODE=somecode>
<PARAM NAME="xyz" VALUE="abc" DATASRC="#Ctrl1" DATAFLD="Column1">
<PARAM NAME="Title" VALUE="BoundApplet">
</APPLET>
Property name resolution
The NAME attribute of the PARAM specifies the basename of the Java methods used to get and set the value of the property. This is termed basename since the method of the Java applet to retrieve the value of the property is get<basename>. Correspondingly, the method to set the value of the Java applet is set<basename>. This naming convention is consistent with the JavaBeans 1.0 specification. The applet used in the previous section is expected to have methods named getxyz and setxyz.
Notifications
Notifications are not fired by the application when property values change. Property changes are only detected when the current record is changed. During this transition, the binding agent interrogates the application and transfers a modified data value, after validation, to the data source. When values are changed directly in the data source, the binding agent is notified by the data source and transfers the value to the application immediately. See the section on data binding events for details about data binding extensions to the event model.
Name space co-mingling
The bound PARAM in the preceding example is the most complicated specification possible. That is, it addresses the case where there is a binding to a property specified by the NAME attribute, and there is a parameter to the application with the same NAME with a corresponding VALUE attribute. This essentially co-mingles two name spaces: the parameter name space for the application and the binding name space, since the NAME attribute is used for both. In such cases, the application ignores the unexpected DATASRC and DATAFLD attributes on the PARAM when fetching a parameter (applications explicitly fetch parameters using the getParameter method), and the binding agent recognizes the attributes and attempts binding using the get and set methods specified above.
The simplest example is one where there is no conflict between the parameter name space and the property name space. An example would be:
<APPLET> <PARAM NAME="backcolor" DATASRC="#DSC1" DATAFLD="Color"> </APPLET>
Here, the backcolor property only has DATASRC and DATAFLD attributes. No VALUE attribute is specified.
In Internet Explorer 4.0, elements are exposed to scripts as objects. The attributes supported by those elements are exposed as properties. Just as a user can perform actions on most elements (clicking a button for example), scripts can call methods of the corresponding object. Scripts can also customize the behavior of elements by handling the events exposed by the corresponding object.
Web authors can achieve dramatic effects on their data bound pages by adding simple scripts that manipulate the properties, methods, and events exposed by the document object model. The document object model supports the following capabilities at run time:
Modifying the Binding of Elements to Data
Dynamically Adding Bound Elements and Data Providers
Dynamically Changing the Way Elements Render Data
Dynamically Controlling the Amount of Displayed Data
Manipulating Data with Active Data Objects (ADO)
This section discusses how to use these features. Because the event model exposed by the document object model for data binding is so extensive, it is treated in a separate section below.
The DATASRC and DATAFLD attributes, introduced above, allow an author to bind an HTML element to data. The document object model exposes these attributes as the properties dataSrc and dataFld, and their values can be modified at any time through scripts.
Web authors may want to perform the following operations on elements that support data binding:
The following sections assume that the element is not serving as a template element in a repeated table scenario. Dynamic tabular binding is discussed below.
Given an element that supports data binding, such as a SPAN or TEXTAREA, adding a binding is as simple as setting the dataSrc and dataFld properties of that element. For example, to bind a span with ID span1 to the first name field in a data set provided by a DSO with id dsoComposer, use the following script:
span1.dataSrc = "#dsoComposer"; span1.dataFld = "compsr_first";
The same binding can be accomplished at design time using the following HTML code:
<SPAN DATASRC="#dsoComposer" DATAFLD="compsr_first"></SPAN>
In both cases compsr_first is the name of an actual field in the data set. The binding will not occur until both properties are set, and any prior value stored by the element will be lost. If the value is required at a later time, for example when the binding is removed, the page author must cache the value prior to binding the element.
Click the Show Me button to see an example.
To remove the binding from a currently bound element, simply set the dataSrc and dataFld properties to the empty string. For example:
span1.dataSrc = ""; span1.dataFld = "";
The previous Show Me button demonstrates this behavior.
Modifying an existing binding is similar to binding an unbound element. Two cases are described:
To bind an element to another field in the same data set, modify the dataFld property. For example, given a SPAN with ID span1 that is currently bound to a composer's first name, the following code binds the SPAN to the composer's last name.
span1.dataFld = "compsr_last";
To bind an element to a field in a different data set:
The section on Binding HTML Elements to Data explained how to bind a table to data at design time. Binding a table at run time requires three steps:
Note that modifying the bindings of any of the individual elements contained within a table requires that the entire table be unbound and then rebound to the DSO. This is necessary because while the table is bound, changes to elements inside the table are applied to the generated rows. Changes while the table is unbound affect the template. Click the Show Me button to see an example that modifies the binding at run time.
<SCRIPT FOR=cboField EVENT=onchange>
cDSO = tblComposers.dataSrc; // remember the DSO
tblComposers.dataSrc = ""; // unbind the table
// set the binding for the contained element
spanField.dataFld = this.options(this.selectedIndex).value;
tblComposers.dataSrc = cDSO; // rebind the table
</SCRIPT>
<TABLE ID=tblComposers DATASRC=#dsoComposers>
<THEAD><TR STYLE="font-weight:bold">
<TD>Last Name</TD>
<TD><SELECT ID=cboField>
<OPTION VALUE=compsr_first SELECTED>First Name</OPTION>
<OPTION VALUE=compsr_last>Last Name</OPTION>
<OPTION VALUE=compsr_birth>Date of Birth</OPTION>
<OPTION VALUE=compsr_death>Date of Death</OPTION>
<OPTION VALUE=origin>Origin
</SELECT>
</TD>
</TR></THEAD>
<TR>
<TD><SPAN DATAFLD=compsr_Last></SPAN></TD>
<TD><SPAN ID=spanField DATAFLD=compsr_first></SPAN></TD>
</TR>
</TABLE>
This example uses the drop-down list to dynamically set the binding of the second column of the table. When a value is selected in the drop-down list, the onchange event handler stores the table's previous binding in a temporary variable. It then unbinds the table by setting its dataSrc property to the empty string. Finally, the code rebinds the table to the DSO by setting the dataSrc property to the previous value.
In addition to modifying the bindings of existing elements on the page, the document object model supports the dynamic addition of both data bound elements and data source objects at run time. By adding these elements at run time, Web authors can reduce the initial download time of their content and can use a single page to display various sets of data to the user.
Click the Show Me button to see an example that dynamically adds a data source object and bound elements to the page.
The DATAFORMATAS attribute, introduced above, allows an author to change the way an element renders its data. The document object model exposes the dataFormatAs property on elements that support rendering in formats other than text. Click the Show Me button to see how it works.
The DATAPAGESIZE attribute introduced above allows an author to restrict the number of records displayed by a tabular data consumer. The document object model exposes this attribute as the property dataPageSize, and its value can be modified at any time through scripts. In addition, the page author can control the currently viewed page of records displayed by a tabular consumer using the nextPage and previousPage methods.
Click the Show Me button to see how the dataPageSize property and accompanying methods work on a TABLE, a tabular data consumer.
Previous sections have shown how to use HTML elements to bind and display the data provided by a DSO. Independent of the user interface, scripts can access and manipulate the data provided by a DSO in a consistent manner using the ADO recordset object. The recordset object is exposed by all data source objects through the extended recordset property.
Scripting the ADO recordset object, Web authors can add rich functionality to their pages, including:
For complete information on ADO, see the accompanying Active Data Objects documentation.
Given a reference to a data source object, accessing the ADO recordset is easy. The following code sample assumes that dsoComposer is a valid DSO.
var oRecordSet = dsoComposer.recordset;
When using a case-sensitive scripting language such as JScript, observe that the recordset property is completely lowercase.
Data binding in Internet Explorer 4.0 uses the notion of a current record to indicate the record in a data set to be displayed by single-valued consumers. When a data set is first loaded, the first record is typically identified as the current record. The current record is affected by any filter or sort order applied to the data. Single-valued consumers always display the current record.
To change the current record and hence the data displayed by single-valued consumers, Web authors can provide users with a set of navigation buttons like the ones shown below.
The code behind these buttons calls the MoveFirst, MovePrevious, MoveNext, and MoveLast methods on the ADO recordset, respectively.
<INPUT ID=cmdNavFirst TYPE=BUTTON VALUE="<<"
onclick="tdcComposers.recordset.MoveFirst()">
<INPUT ID=cmdNavPrev TYPE=BUTTON VALUE=" < "
onclick="tdcComposers.recordset.MovePrevious();
if (tdcComposers.recordset.BOF)
tdcComposers.recordset.MoveFirst();">
<INPUT ID=cmdNavNext TYPE=BUTTON VALUE=" > "
onclick="tdcComposers.recordset.MoveNext();
if (tdcComposers.recordset.EOF)
tdcComposers.recordset.MoveLast();">
<INPUT ID=cmdNavLast TYPE=BUTTON VALUE=">>"
onclick="tdcComposers.recordset.MoveLast()">
Using the recordNumber property
If a page displays both single-valued and tabular data consumers on the page, the Web author can add functionality so that when the user clicks a row in the table, the current record and single-valued consumers are set to display the selected row. Likewise, when the user clicks navigation buttons on the page, the table can be synchronized to indicate the currently selected record. Click the Show Me button to see how it works.
The script behind the example uses the recordNumber property available on all repeated elements within a data bound table. This includes both bound and unbound elements. The property returns the number of the record displayed by the table row. In the example, when the user clicks any element within a table row, the click-handling code sets the AbsolutePosition property of the ADO recordset to the value of that element's recordNumber property.
In turn, if the user clicks a navigation button, the appropriate Move method is called on the ADO recordset. Then the highlighted row in the table is updated by searching for the table row with the recordNumber that corresponds to the value of the AbsolutePosition property on the ADO recordset. Once found, the background color of the table row is set to yellow.
To support the addition and deletion of records from a recordset, the ADO recordset object supports both AddNew and Delete methods. When AddNew is called from a script, the DSO adds a new record to the locally cached data set. When Delete is called, the current record is removed from the local data cache.
Bound elements are immediately updated to reflect the addition, removal, and modification of records through scripts. If the current record is removed, single-valued elements are updated to display the next record in the data set. If the last record in the data set is deleted, the previous record is displayed. Tabular data consumers are updated to no longer display the deleted record.
It is important to distinguish between operations that are performed on the local data cache and those that affect the back-end data set. While the TDC, for example, supports the modification of data in the local cache, it does not support committing those changes to the file from which the data was obtained. In contrast, the Remote Data Service (RDS) does support this feature.
Click the Show Me button to see an example that exercises the ADO object model to insert, delete, and update records in the local data cache.
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.
| Event | Bubbles | Canceleable | Applies 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.
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.
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>
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.
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.
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>
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.
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>
Bound elements fire events that allow page authors to perform field-level validation and to handle errors that occur during an update.
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.
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.
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>
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.
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.