Search

Data Binding and XMLHTTP

0 views

Live Data Integration with XMLHTTP

When a web page sits entirely on the client side, the data it displays is either baked into the HTML or fetched when the page loads. Both approaches work fine for static content, but they fall short when you need up‑to‑date information - whether it's a weather feed, stock tickers, or customer orders. The key to solving this problem is to let the browser request fresh data from a server without reloading the entire page. That’s where XMLHTTP steps in.

XMLHTTP, provided by Microsoft’s MSXML library, allows JavaScript to make HTTP requests directly from the browser. You can request XML, JSON, or plain text from a web service and then inject the response into the DOM. By keeping the page alive while pulling in new data, you create a smoother, more responsive experience for the user. For developers who already use Data Islands to store structured data in the page, XMLHTTP offers a natural way to refresh those islands or populate new ones.

The combination of XMLHTTP and Data Islands has a few distinct advantages. First, the data model stays in the browser, which means you don’t have to involve a server for every read operation. Second, you can control exactly when and how often the data updates, reducing unnecessary traffic. Third, the Data Islands can be bound to form controls or tables, so changes in the XML automatically ripple through the UI.

In practice, the workflow looks like this: 1) the page loads and initializes one or more Data Islands, perhaps with placeholder values; 2) the JavaScript engine creates an XMLHTTP object; 3) an asynchronous call is fired to a web service that returns fresh XML; 4) once the response arrives, the JavaScript parses it and updates the relevant Data Island; 5) the binding engine updates any linked form controls or table cells. No full page refresh is needed, and the user sees the new data almost immediately.

Because many developers are more comfortable with RESTful services that return JSON, you might wonder why XMLHTTP is still relevant. The answer is that the same technique works with JSON; you simply parse the response text with JSON.parse. However, when you’re already working with XML, especially when using Data Islands that are defined in the same XML format, it’s simpler to stay within the XML ecosystem. It keeps the code consistent and eliminates the need for additional parsing logic.

Beyond the technical aspects, using XMLHTTP for live data has business implications. Faster updates mean more accurate dashboards, real‑time inventory checks, and dynamic pricing models. For clients who value immediate feedback, the shift from static to dynamic pages can be a major competitive advantage. Moreover, keeping the UI lightweight by offloading data retrieval to the server reduces the amount of code that runs in the browser, which can improve performance on older machines.

To get started, make sure your HTML document includes a reference to the MSXML library. In Internet Explorer, you can instantiate it directly with new ActiveXObject('Microsoft.XMLHTTP'). In other browsers, the standard new XMLHttpRequest() object is available, which behaves similarly. The rest of the code is nearly identical, so you can write a single function that works across platforms. Keep this in mind when you later decide whether to target older IE versions or modern browsers exclusively.

In the next section we’ll dive into how to structure those calls so they’re both efficient and responsive. By the end of this article you’ll have a fully working example that pulls data from a web service, updates a Data Island, and refreshes the user interface - all without a single page reload.

Asynchronous XMLHTTP Communication in the Browser

Asynchronous calls are the backbone of modern web applications. They let the browser continue to respond to user actions while data travels across the network. For developers who want to keep the UI snappy, understanding how to set up an asynchronous XMLHTTP request is essential.

The process splits into two parts: establishing the connection and sending the request, and then handling the response when it arrives. The first part is straightforward - create the XMLHTTP object, set the request method (GET or POST), specify the URL, and indicate that the call should be asynchronous. For example:

Prompt
var xhr = new ActiveXObject('Microsoft.XMLHTTP');</p> <p>xhr.open('POST', 'https://example.com/Service/GetInfo', true);</p> <p>xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');</p>

Notice the true flag passed to open. That flag tells the browser to treat the request asynchronously. If you omit it or pass false, the browser will block until the server responds - a bad idea for anything beyond the simplest operations.

Once the connection is set up, you attach an event handler to onreadystatechange. This function runs every time the internal state of the XMLHTTP object changes. When the state reaches and the HTTP status code is , the response is ready to process.

Prompt
xhr.onreadystatechange = function() {</p> <p> if (xhr.readyState === 4 && xhr.status === 200) {</p> <p> var xmlDoc = xhr.responseXML;</p> <p> updateDataIsland(xmlDoc);</p> <p> }</p> <p>};</p>

Because the request is asynchronous, the rest of your script continues to execute while the browser waits for the server. This means you can safely update other parts of the page, such as showing a loading spinner, without freezing the UI.

When you’re building a web service that returns XML, keep the response simple. Instead of a complex SOAP envelope, send a plain XML document that mirrors the structure of your Data Island. This eliminates the need for manual SOAP message construction and reduces the chance of errors. A minimal service might look like:

Prompt
<UserInfo></p> <p> <UserName>JohnDoe</UserName></p> <p> <Email>john.doe@example.com</Email></p> <p></UserInfo></p>

In the client, after parsing responseXML, you can traverse the nodes with standard DOM methods. For instance, to set a Data Island named #UserIsland, you could write:

Prompt
function updateDataIsland(xmlDoc) {</p> <p> var userName = xmlDoc.getElementsByTagName('UserName')[0].textContent;</p> <p> var email = xmlDoc.getElementsByTagName('Email')[0].textContent;</p> <p> // Assume we have a Data Island with these fields</p> <p> var island = document.getElementById('UserIsland');</p> <p> island.setAttribute('data', 'userName=' + userName + '&email=' + email);</p> <p>}</p>

Because the Data Island is bound to form fields or table cells, updating its attributes triggers an automatic refresh of the bound controls. The user sees the new information immediately, with no need to refresh the page.

There are a few pitfalls to watch out for. If the web service fails - perhaps due to a network outage or server error - the onreadystatechange handler still runs, but the status code will differ from . Always include error handling logic to alert the user or retry the request. A simple pattern is:

Prompt
if (xhr.readyState === 4) {</p> <p> if (xhr.status === 200) {</p> <p> // Process success</p> <p> } else {</p> <p> // Handle error</p> <p> alert('Error fetching data: ' + xhr.status);</p> <p> }</p> <p>}</p>

When you’re working with larger data sets, consider using XMLHttpRequest.responseText and parsing it manually if you need to stream or process parts of the response incrementally. For most scenarios, responseXML suffices, especially when the XML is well‑formed.

Finally, remember that asynchronous calls don’t guarantee order of execution. If you need to make multiple requests in a specific sequence, chain them by initiating the next call inside the success handler of the previous one. This pattern keeps your code readable and ensures that dependent data is available before you try to bind it.

Binding Data Islands to Forms and Tables

Data binding is the process of linking UI elements - such as input fields, spans, or table cells - to a data source so that changes flow automatically in both directions. In the context of Data Islands, binding is done through the datasrc and datafld attributes. The datasrc points to a Data Island, while datafld identifies a specific field within that island.

When you bind a single Data Island to a form, you can place the datasrc attribute on the <form> tag itself. All child controls that specify a datafld will inherit that source. This approach keeps the markup clean, but it means that every control on the form is tied to the same Data Island. If you need a more granular binding - perhaps one control needs to read from a different island or you want to avoid accidental data coupling - you can place datasrc on individual controls instead.

Prompt
<form id="userForm"></p> <p> <input type="text" datasrc="#UserIsland" datafld="UserName" placeholder="User Name"></p> <p> <input type="email" datasrc="#UserIsland" datafld="Email" placeholder="Email"></p> <p></form></p>

In the example above, the two inputs pull directly from #UserIsland. When the island’s attributes change, the inputs update automatically. Conversely, if a user edits the fields, the underlying Data Island updates as well - thanks to the two‑way binding nature of Data Islands. This feature reduces the need for explicit event listeners on each input.

Binding to a table follows a similar logic but adds a twist: the Data Island can contain multiple nodes that represent rows. When you set datasrc on a <table> element, the table engine loops through the node list, creating a row for each node. Within each row, datafld attributes on <span> or <td> elements map to child nodes. For example:

Prompt
<table datasrc="#Products"></p> <p> <tr></p> <p> <td><span datafld="ProductName"></span></td></p> <p> <td><span datafld="Price"></span></td></p> <p> </tr></p> <p></table></p>

Assuming #Products is a Data Island structured like:

Prompt
<Products></p> <p> <Product><ProductName>Laptop</ProductName><Price>999</Price></Product></p> <p> <Product><ProductName>Phone</ProductName><Price>599</Price></Product></p> <p></Products></p>

The table will automatically generate two rows, each populated with the corresponding product name and price. If the Data Island is updated - say the price changes - the table refreshes instantly. This makes Data Islands ideal for dashboards or reports that need to stay in sync with the server.

There are subtle nuances to keep in mind. Data Islands are static once loaded, so if you need to add or remove nodes, you must do so via JavaScript or by re‑fetching the island from the server. Additionally, not all browsers support Data Islands natively. In modern environments, you may need to rely on alternative techniques, such as JavaScript objects or frameworks that emulate binding. Nevertheless, for developers targeting legacy browsers or those who prefer a straightforward, declarative approach, Data Islands remain a powerful tool.

When combining data binding with XMLHTTP, the workflow becomes seamless: 1) fetch fresh XML from the server; 2) populate a Data Island with the response; 3) let the bound controls update automatically. This eliminates boilerplate code and keeps the UI logic declarative. Developers can focus on business logic rather than DOM manipulation loops.

Because binding is declarative, you can also apply CSS styling to placeholders, such as using :empty or custom classes to indicate loading states. For instance, you might hide the table until the Data Island contains at least one node, preventing an empty table from flashing on the screen. Simple JavaScript can toggle a class when the island updates.

In practice, many applications use this pattern for inventory screens, customer dashboards, or live data feeds. The key advantage is the low coupling between the UI and data source - changing the data model on the server side requires only a change to the web service response, not the client code.

Download the Sample Code and Run It Yourself

To see these concepts in action, a complete example has been assembled. The package includes:

  • An HTML page that defines two Data Islands: one for user information and another for a list of products.
  • A simple web service stub that returns XML responses mimicking a real backend.
  • JavaScript that sets up asynchronous XMLHTTP calls, parses the responses, and updates the Data Islands.
  • Binding markup that demonstrates both single‑row forms and multi‑row tables.
  • Minimal CSS to keep the interface tidy.

    The source files are bundled in a ZIP archive that you can download and extract locally. After unpacking, open the index.html file in Internet Explorer (or any browser that supports ActiveX) and click the “Refresh Data” button. The page will send an asynchronous request to the mock service, receive fresh XML, update the Data Islands, and the UI will reflect the new data instantly.

    Feel free to modify the web service to return different XML structures or to add more fields to the Data Islands. Play around with the binding attributes - move datasrc from the form to individual inputs, or adjust the table structure to display additional columns. The more you experiment, the clearer the power of live data integration becomes.

    For further exploration, consider extending the example to handle error states gracefully. Implement a retry mechanism that attempts the request a few times before showing an error message. Or add a loading indicator that appears while the XMLHTTP call is pending, enhancing the user experience.

    By studying this sample, you’ll grasp how to weave together XMLHTTP, asynchronous communication, and Data Islands to create responsive, data‑driven web applications. Once you master these building blocks, the possibilities for dynamic client‑side interfaces expand dramatically.

Suggest a Correction

Found an error or have a suggestion? Let us know and we'll review it.

Share this article

Comments (0)

Please sign in to leave a comment.

No comments yet. Be the first to comment!

Related Articles