Book Image

HTML5 Data and Services Cookbook

Book Image

HTML5 Data and Services Cookbook

Overview of this book

HTML5 is everywhere. From PCs to tablets to smartphones and even TVs, the web is the most ubiquitous application platform and information medium bar. Its becoming a first class citizen in established operating systems such as Microsoft Windows 8 as well as the primary platform of new operating systems such as Google Chrome OS. "HTML5 Data and Services Cookbook" contains over 100 recipes explaining how to utilize modern features and techniques when building websites or web applications. This book will help you to explore the full power of HTML5 - from number rounding to advanced graphics to real-time data binding. "HTML5 Data and Services Cookbook" starts with the display of text and related data. Then you will be guided through graphs and animated visualizations followed by input and input controls. Data serialization, validation and communication with the server as well as modern frameworks with advanced features like automatic data binding and server communication will also be covered in detail.This book covers a fast track into new libraries and features that are part of HTML5!
Table of Contents (21 chapters)
HTML5 Data and Services Cookbook
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface
Index

Creating a sortable paginated table


One of the most common tasks we encounter when creating websites is displaying lists and tables. Most techniques focus on server-side sorting, paging, and the rendering of data. Our solution will be completely on the client side, suitable for small to medium amounts of data. The main benefit of a client-side solution is speed; sorting and switching pages will be nearly instantaneous.

In this recipe, we're going to create a client-side, sortable paginated table.

Getting ready

We assume that a service provides the data in a JSON object, containing a data property that is an array of arrays:

{data:[["object1col1", "object1col2"], ["object2col1", "object2col2"],  …]}

In our example, we're going to display a list of people near us. Every person in the table will have their own ID number, name, age, distance from us, and transportation method.

We're going to display the distance in km, and would like to be able to sort the list of people by their last names.

As table display problems quickly grow beyond the original simple problem, we're not going to build our own solution. Instead, we're going to use the excellent jQuery DataTables plugin available at http://datatables.net/.

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

How to do it...

Let's write the HTML page, CSS style, and JavaScript code.

  1. First, we're going to create an HTML page containing an empty table. We're also going to add some CSS to import a basic DataTables style for the table. The stylesheets are normally available with the DataTables distribution. Our index.html file is as follows:

    <!DOCTYPE HTML>
    <html>
        <head>
            <title>Sortable paged table</title>
            <style type="text/css">
                @import "http://live.datatables.net/media/css/demo_page.css";
                @import "http://live.datatables.net/media/css/demo_table.css";
                #demo, #container {
                    width:700px;
                }
                #demo td {
                    padding: 0.2em 2em;
                }
                #demo_info {
                    width:690px;
                    height:auto;
                }
            </style>
        </head>
        <body>
            <div id="container">
                <table id="demo">
                    <thead>
                        <tr>
                            <th>Id</th><th>Name</th><th>Age</th><th>Distance</th><th>Transportation</th>
                        </tr>
                    </thead>
                    <tbody>
                    </tbody>
                </table>
            </div>
            <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
            <script type="text/javascript" src="http://datatables.net/download/build/jquery.dataTables.min.js"></script>
            <script type="text/javascript" src="example.js"></script>
        </body>
    </html>

    The example includes a link to the minified version of DataTables hosted on the official website.

    The DataTables plugin appends the pager and info elements below the table. Because of this, we need to wrap our table inside a container element.

  2. And the example.js file is as follows:

    (function() {
        $.extend($.fn.dataTableExt.oSort, {
            "lastname-sort-pre": function (a) {
                return a.split(' ').reverse().join(' ');
            },
            "lastname-sort-asc": function(a, b) { return a < b ? -1 : a > b ? 1 : 0; },
            "lastname-sort-desc": function(a, b) { return a > b ? -1 : a < b ? 1 : 0; },
            "unitnumber-pre": function(a) { return new Number(a.split(' ')[0]); },
            "unitnumber-asc": function(a, b) { return a - b; },
            "unitnumber-desc": function(a, b) { return b - a; }
        } )
        var fetchData = function(callback) {
            var data = [
                [1,'Louis Garland', 12, 32, 'Walking'],
                [2,'Misty Lamar',32, 42, 'Bus'],
                [3,'Steve Ernest',32, 12, 'Cycling'],
                [4,'Marcia Reinhart',42, 180, 'Bus'],
                [5,'Lydia Rouse',35, 31, 'Driving'],
                [6,'Sean Kasten',80,42, 'Driving'],
                [7,'Patrick Sharkey',65,43, 'Cycling'],
                [8,'Becky Rashid',63, 51, 'Bus'],
                [9,'Michael Fort',34, 23, 'Walking'],
                [10,'Genevieve Blaine',55, 11, 'Walking'],
                [11,'Victoria Fry',58, 14, 'Walking'],
                [12,'Donald Mcgary',34, 15, 'Cycling'],
                [13,'Daniel Dreher',16, 23, 'Walking'],
                [14,'Valerie Santacruz',43, 35, 'Driving'],
                [15,'Jodi Bee',23, 13, 'Walking'],
                [16,'Jo Montana',14, 31, 'Cycling'],
                [17,'Stephanie Keegan',53, 24, 'Driving'],
                [18,'Philip Dewey',12, 29, 'Cycling'],
                [19,'Jack Clemons',11, 44, 'Walking'],
                [20,'Steve Serna',14, 60, 'Cycling']
            ];
            callback({data:data});
        };
        window.myTable = {};
        var table = window.myTable.table = $("#demo").dataTable({
            'bLengthChange': false, 'bFilter': false,
            'iDisplayLength': 10,
            'aoColumnDefs':[{
            aTargets: [3], // distance
                mRender: function(data) { return data + ' km'; },
                sType: 'unitnumber'
            }, {
                aTargets: [1],
                sType: 'lastname-sort'
            }]
        });
        var setData = window.myTable.setData = function(data) {
            table.fnClearTable();
            table.fnAddData(data);
            table.fnDraw();
        };
    
        fetchData(function(result) {
            window.myTable.data = result.data;
            setData(result.data);
        });
    
    }());

    The implementation of fetchData in the example provides hardcoded example data. You can easily replace it with a request to your service. The setData function is a convenient function to change the table data—we're going to use the same script, which will call this function to set its own data, for multiple recipes. Finally, the rest of the code is specific to DataTables and will be explained in the next section.

How it works...

The following image shows the resulting table:

To initialize the table we use the dataTable initialization function. We can pass multiple options to the function. For example, we can specify that we want 10 items per page by setting the value of the iDisplayLength property to 10.

Because we're going to render the Distance column (column 3) slightly differently than just displaying it, we add an item to the aoColumnDefs option for target column 3 that sets a custom rendering function for that column. This is a function that simply appends the km string to our number; but we could also use a more elaborate function (involving custom date formatting, unit conversions, and so on).

Paging works automatically with DataTables—the plugin appends a pager control that provides access to the previous/next page. Sorting also mostly works automatically. However, in our particular example, we need special sorting for the Name column (by last name) even though it's displayed in the format "firstname lastname". To do this, we specify a custom sort type for that column called lastname-sort. We also specify a special sort type for the Distance column called unitnumber.

DataTables allows us to define custom sort types as plugins. Custom sorters have the following properties:

  • A preprocessing function that pre-processes the column value before passing it to the sorter

  • An ascending sorting function that returns a value depending on the value of the two arguments that are passed: -1 if the first value is smaller, 0 if they are equal, or 1 if the first value is larger

  • A descending order sorting function that works similarly to the ascending sorting function

These properties allow us to implement sorting by last name for the Name column, as well as by number for the Distance column.

There's more...

Here is a simple Ajax replacement of the fetchData function, sending an Ajax request to a request handler hosted on the same domain at the path /people to retrieve the array data:

function fetchData(cb) {
    $.get('/people/').success(cb);
}

Note that this solution doesn't work very well for large datasets. While modern clients have the performance to manipulate a lot of data, bandwidth is also a consideration. A careful consideration of bandwidth requirements and the target clients (desktop or mobile) should be exercised before using this solution.