YUI Library Home

Site Search (YDN & YUIBlog):

# YUI Library Examples: DataSource Utility: Extracting data from an HTML table

# DataSource Utility: Extracting data from an HTML table

DataSource supports using a table in markup as its source of truth.

This example illustrates how to create a "pass-thru" DataSource instance to leverage the DOM walking and parsing routines inside in order to extract the table's data into a JavaScript array structure.

View example in new window.

Total Amount Due: (click the Extract button)

Table in markup with data in it
Due Date | Account Number | Quantity | Amount Due
--- | --- | --- | ---
1/23/1999 | 29e8548592d8c82 | 12 | $150.00
5/19/1999 | 83849 | 8 | $60.00
8/9/1999 | 11348 | 1 | -$34.99
1/23/2000 | 29e8548592d8c82 | 10 | -$1.00
4/28/2000 | 37892857482836437378273 | 123 | $33.32
1/23/2001 | 83849 | 5 | -$15.00
9/30/2001 | 224747 | 14 | $56.78

## What we have and what we'll get

In this example, a table rendered in the page's markup will be parsed into an array, and stored in `YAHOO.example.data`.

The markup looks like this:

<table id="accounts"> <caption>Table in markup with data in it</caption> <thead> <tr> <th>Due Date</th> <th>Account Number</th> <th>Quantity</th> <th>Amount Due</th> </tr> </thead> <tbody> <tr> <td>1/23/1999</td> <td>29e8548592d8c82</td> <td>12</td> <td>$150.00</td> </tr> <tr> <td>5/19/1999</td> <td>83849</td> <td>8</td> <td>$60.00</td> </tr> ... </tbody> </table>

The resulting data will look like this:

[ { due : (Date instance), account : '29e8548592d8c82', quantity: 12, amount : 150 }, { due : (Date instance), account : '83849', quantity: 8, amount : 60 }, ... ]

## Create a DataSource instance

The first step is to create the DataSource instance, seeding it with the `<table>` element, which we get via `YAHOO.util.Dom.get`. Configure the `responseType` and `responseSchema` to identify the mapping between columns and data key names (first column will be called "due").

We'll take advantage of the often-ignored second constructor parameter to configure the DataSource inline.

YAHOO.util.Event.onDOMReady(function () { // Create some shortcuts var DataSource = YAHOO.util.DataSource, Event = YAHOO.util.Event, Dom = YAHOO.util.Dom; // this is where the data will go YAHOO.example.data = null; // Pass a configuration object as the second parameter var myDataSource = new DataSource(Dom.get('accounts'), { responseType : DataSource.TYPE_HTMLTABLE, responseSchema : { fields : [ { key : 'due' }, { key : 'account' }, { key : 'quantity' }, { key : 'amount' } ] } }); ... });

## Parsing the data into correct data types

By default, DataSource will treat all table cell data as strings. We can add `parser`s to the field declarations to identify how the data should be stored. DataSource comes with a few parsers out of the box, but you can add your own custom parser by supplying a function as the `parser` in the field definition.

Another way to create a parser common across all DataSource instances is to add your parse function to the `YAHOO.util.DataSource.Parser` object. The property name you use can then be referenced as a string in the field's `parser` configuration.

We'll do this for the Amount column, since DataSource doesn't have a parser that can handle currency figures.

... // this is where the data will go YAHOO.example.data = null; // Add a new parser to DataSource to parse numbers that are prefixed with // currency symbols (or any other non-numeric characters) DataSource.Parser.currency = function (cur) { if (YAHOO.lang.isString(cur)) { var neg = !cur.indexOf('-'); cur = (neg?-1:1) * cur.slice(neg).replace(/^[^0-9.]+|,/g,''); } else if (!YAHOO.lang.isNumber(cur)) { return 0; } return cur; }; var myDataSource = new DataSource(Dom.get('accounts'), { responseType : DataSource.TYPE_HTMLTABLE, responseSchema : { fields : [ { key : 'due', parser : 'date' }, { key : 'account' }, { key : 'quantity', parser : 'number' }, { key : 'amount', parser : 'currency' } // use our new parser ] } }); ...

## Capture the data in the `sendRequest` callback

The next and final step is to issue a `sendRequest`, providing a simple success handler to assign the parsed response's `results` array to our desired destination.

// DataSource ignores the first parameter for HTML table instances myDataSource.sendRequest(null,{ success : function (req,res) { YAHOO.example.data = res.results; } });

At this point the data is available in `YAHOO.example.data`.

## Change into a pass-thru

Since the DataSource is only needed for this one operation, and only one method is being executed, we don't even need to store the instance in a variable. Just call `sendRequest` on the result of the DataSource constructor.

// No need to store the DataSource new DataSource(Dom.get('accounts'), { responseType : DataSource.TYPE_HTMLTABLE, responseSchema : { // Describe the object keys each record will have and what type // of data to parse into the respective values fields : [ { key: 'due', parser: 'date' }, { key: 'account' }, { key: 'quantity', parser: 'number' }, { key: 'amount', parser: 'currency' } // use our new parser ] } }).sendRequest(null,{ success : function (req,res) { YAHOO.example.data = res.results; } });

## Full Code Listing

Below is a full code listing for this example, including the code for the buttons, making use of the extracted data.

### JavaScript YAHOO.util.Event.onDOMReady(function () { // Shortcuts var DataSource = YAHOO.util.DataSource, Event = YAHOO.util.Event, Dom = YAHOO.util.Dom; YAHOO.example.data = null; // this is where the data will go // Add a new parser to DataSource to parse numbers that are prefixed with // currency symbols (or any other non-numeric characters) DataSource.Parser.currency = function (cur) { if (YAHOO.lang.isString(cur)) { var neg = !cur.indexOf('-'); cur = (neg?-1:1) * cur.slice(neg).replace(/^[^0-9.]+|,/g,''); } else if (!YAHOO.lang.isNumber(cur)) { return 0; } return cur; }; Event.on('demo_load','click',function (e) { // Here's the pass-thru DataSource. Instantiate and immediately call // sendRequest, passing a simple assignment function as the callback's // success handler new DataSource(Dom.get('accounts'), { responseType : DataSource.TYPE_HTMLTABLE, responseSchema : { // Describe the object keys each record will have and what type // of data to parse into the respective values fields : [ { key: 'due', parser: 'date' }, { key: 'account' }, { key: 'quantity', parser: 'number' }, { key: 'amount', parser: 'currency' } // use our new parser ] } }).sendRequest(null,{ success : function (req,res) { YAHOO.example.data = res.results; } }); YAHOO.log(YAHOO.lang.dump(YAHOO.example.data), "info", "example"); // The work is done and data is populated. Update the UI to allow for // referencing the data structure. Dom.get('demo_load').disabled = true; Dom.get('demo_go').disabled = false; Dom.get('report').innerHTML = "Table data loaded. Click <em>Get Total Amount Due</em>."; }); Event.on('demo_go','click', function (e) { var data = YAHOO.example.data || [], total = 0, i; // Proof that we have a populated data object for (i = data.length - 1; i >= 0; --i) { total += data[i].amount; } Dom.get('report').innerHTML = '$' + total.toFixed(2); }); });

### HTML

<div id="demo"> <button type="button" id="demo_load">Extract the table data</button> <button type="button" id="demo_go" disabled="disabled">Get Total Amount Due</button> <p>Total Amount Due: <em id="report">(click the Extract button)</em></p> <table id="accounts"> <caption>Table in markup with data in it</caption> <thead> <tr> <th>Due Date</th> <th>Account Number</th> <th>Quantity</th> <th>Amount Due</th> </tr> </thead> <tbody> <tr> <td>1/23/1999</td> <td>29e8548592d8c82</td> <td>12</td> <td>$150.00</td> </tr> <tr> <td>5/19/1999</td> <td>83849</td> <td>8</td> <td>$60.00</td> </tr> <tr> <td>8/9/1999</td> <td>11348</td> <td>1</td> <td>-$34.99</td> </tr> <tr> <td>1/23/2000</td> <td>29e8548592d8c82</td> <td>10</td> <td>-$1.00</td> </tr> <tr> <td>4/28/2000</td> <td>37892857482836437378273</td> <td>123</td> <td>$33.32</td> </tr> <tr> <td>1/23/2001</td> <td>83849</td> <td>5</td> <td>-$15.00</td> </tr> <tr> <td>9/30/2001</td> <td>224747</td> <td>14</td> <td>$56.78</td> </tr> </tbody> </table> </div>

## Configuration for This Example

You can load the necessary JavaScript and CSS for this example from Yahoo's servers. Click here to load the YUI Dependency Configurator with all of this example's dependencies preconfigured.

### YUI Logger Output:

### DataSource Utility Examples:

- Extracting data from an HTML table
- YQLDataSource
- Basic Local Data (included with examples for AutoComplete Control)
- Basic Remote Data (included with examples for AutoComplete Control)
- Custom Formatting, with a Proxyless Remote DataSource (included with examples for AutoComplete Control)
- Customizing Remote Requests (included with examples for AutoComplete Control)
- Datatable with Autocomplete (included with examples for DataTable Control)
- Find Photos on Flickr (included with examples for AutoComplete Control)
- FunctionDataSource to Search Multiple Fields of an Address Book at Runtime (included with examples for AutoComplete Control)
- Inline Cell Editing (included with examples for DataTable Control)
- Integrating Browser History Manager with Server-side Pagination and Sorting (included with examples for DataTable Control)
- JSON Data Over XHR (included with examples for DataTable Control)
- Polling the DataSource (included with examples for DataTable Control)
- Progressive Enhancement (included with examples for DataTable Control)
- Screenreader Accessibility (included with examples for AutoComplete Control)
- Server-side Pagination and Sorting for Dynamic Data (included with examples for DataTable Control)
- Textual Data Over XHR (included with examples for DataTable Control)
- XML Data Over XHR With POST (included with examples for DataTable Control)
- XML Data with XPath (included with examples for DataTable Control)

### More DataSource Utility Resources:

- User's Guide (external)
- API Documentation

Copyright © 2009 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings