Book Image

Instant jQuery 2.0 Table Manipulation How-to

By : Charlie Griefer
Book Image

Instant jQuery 2.0 Table Manipulation How-to

By: Charlie Griefer

Overview of this book

When jQuery was introduced, it took the JavaScript world by storm. Years later, it shows no sign of slowing down. Its powerful yet concise syntax helps to simplify tasks that might otherwise be difficult or complex. Whether you're a JavaScript novice or an expert, jQuery is a valuable addition to your toolbox.Instant jQuery 2.0 Table Manipulation How-to shows you how to quickly and easily add style and functionality to your HTML tables. You'll be amazed to see how easy it is. Just don't let your customers know!HTML tables can be boring. Sure, we can make them more stylish with CSS, but users want interactivity. They want to be able to sort columns, see totals, filter data, and page through information in easily digestible chunks. Starting off with a plain HTML table, and an ID and a few class attributes, you will see the transformations occur with just a few lines of jQuery. Instant jQuery 2.0 Table Manipulation How-to progresses to showing you how to highlight specific table cells and filter table data, and even sort columns or page through data. Regardless of your skill level with JavaScript or jQuery, this book will walk you through the deceptively simple steps needed to add functionality and interactivity to your HTML tables.
Table of Contents (7 chapters)

Pagination – client side (Should know)


Pressed for space? Don't want to overwhelm your users with too much data at once? Paginate.

Getting ready

For this recipe, we're back to a relatively simple HTML table. No special classes are needed for the purpose of this exercise, as we're going to be focused exclusively on an array of rows within the table. Specifically, rows within the table body.

How to do it...

  1. As always, create a table with a unique ID. Also for this recipe create a style block to add some formatting as follows:

    <style type="text/css">
      table, a.paginate { font: normal 75% "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif; }
      th.ranking { width: 50px; }
      th.title { width: 150px; }
      th.year { width: 100px; }
    </style> 
    
    <table border="1" id="pagetable">
    <thead>
      <tr>
        <th class="ranking">Ranking</th>
        <th class="title">Movie</th>
        <th class="year">Release Year</th>
      </tr>
    </thead>
  2. Next add some rows in the tbody tag:

    <tbody>
      <tr>
        <td>1</td>
        <td>Citizen Kane</td>
        <td>1941</td>
      </tr>
      <tr>
        <td>2</td>
        <td>The Godfather</td>
        <td>1972</td>
      </tr>
      …
      <tr>
        <td>15</td>
        <td>2001: A Space Odyssey</td>
        <td>1968</td>
      </tr>
    </tbody>
  3. Pagination wouldn't be worth much without Previous and Next links. Create a div underneath the table to hold each link. Give both links a class of paginate, but give each a unique ID as follows:

    <div>
      <a href="#" class="paginate" id="previous">Previous</a> | 
      <a href="#" class="paginate" id="next">Next</a>
    </div>
  4. All that's left is to set up the script. For now page four records at a time:

    <script type="text/javascript">
    $( document ).ready( function() {
      var firstRecord = 0;
      var pageSize = 4;
    
      var tableRows = $( "#movies tbody tr" ); 
      $( "a.paginate" ).click( function( e ) {
        e.preventDefault();
        
        if ( $( this ).attr( "id" ) == "next" ) {
          if ( firstRecord + pageSize <= tableRows.length ) {
            firstRecord += pageSize;
          }
        } else {
          if ( firstRecord != 0 ) {
            firstRecord -= pageSize;
          }
        }
        
        paginate( firstRecord, pageSize );
      });
    
      var paginate = function( startAt, pageSize ) {
        var endAt = startAt + pageSize – 1;
    
        $( tableRows ).each( function( index ) {
          if ( index >= startAt && index <= endAt ) {
            $( this ).show();
          } else {
            $( this ).hide();
          }
        });
      }
    
      paginate (firstRecord, pageSize );
    });
    </script>
  5. The table is now less overwhelming, and allows the user to page through via Previous and Next links, as shown in the following screenshot:

How it works...

There's quite a lot happening here. Start off by defining three variables as follows:

  • firstRecord: All of the table rows will be stored in an array. This variable holds the value, or the array index position, of the row that's currently being displayed at the first position.

  • pageSize: How many records do we want to display per page? This value is referred to several times in the code, so assigning it to a variable makes it easier to change down the road, should the need arise.

  • tableRows: A collection of all of the rows in the table. The selector syntax used to select the rows should be familiar by now.

    $( "#pagetable tbody tr" )

Next, listen for a click event that occurs on an <a> element with a class of paginate. This would be both the Previous and Next links.

$( "a.paginate" ).click( function( e )

Make sure the browser doesn't try to reload the page or follow the link by preventing the default behavior from occurring. You did this in the Show/hide rows (Must know) recipe.

e.preventDefault();

The next bit of code conditionally checks to see which link was clicked, the Previous link or the Next link. This is done by checking the id attribute. Remember, while each link has the same class name, each link has a unique ID.

if ( $( this ).attr( "id" ) == "next" )

The first condition fires if the Next link is clicked. The else obviously fires if the Previous link is clicked.

Regardless of which link is clicked, calculate a new value for the firstRecord variable. To start, firstRecord variable's value is 0. Guard conditions within each of the Previous and Next conditions ensure that the value of firstRecord can neither fall below 0, nor exceed the number of records in the collection.

The guard condition around the Next link is as follows:

if ( firstRecord + pageSize <= tableRows.length ) {
  firstRecord += pageSize;
}

The value of firstRecord should never exceed the number of records in the collection. In order to check that clicking on Next will not result in that happening, add the value of pageSize (currently set to 4) to the value of firstRecord (initially 0). As long as that condition is met, a new value can be set for firstRecord.

The guard condition around Previous is a bit more straightforward:

if ( firstRecord != 0 ) {
  firstRecord -= pageSize;
}

As long as the user is not on the first page, where the value of firstRecord is 0, "activate" the Previous link by setting the value of firstRecord to be firstRecord minus the value of pageSize.

If either condition is not met, the existing value of firstRecord simply remains unchanged.

With the value of firstRecord now properly calculated (either to reflect moving forward or backwards, or staying the same in the case that upper/lower boundaries are exceeded), call a named function, passing in both the calculated value for firstRecord as well as pageSize.

paginate( firstRecord, pageSize );

Let's look at that the function a little more closely:

var paginate = function( startAt, pageSize ) {
  var endAt = startAt + pageSize - 1;

  $( tableRows ).each( function( index ) {
    if ( index >= startAt && index <= endAt ) {
      $( this).show();
    } else {
      $( this ).hide();
    }  
  });
}

paginate() knows which record to start with, as that value is passed in as an argument to the function. Within the function, the first line calculates the record to end with.

The script has determined which rows to display. It will either be rows 0-3, 4-7, 8-11, or 12-14. Remember that JavaScript is a zero-based system, and the records are being paged four at a time. All of the rows are stored in our tableRows variable. You're already familiar with jQuery's each() function, as it was used in the Sum columns (Must know) and Highlighting cells (Must know) recipes. Loop over the table rows and use jQuery's built-in show() and hide() methods as needed.

$( tableRows ).each( function( index ) {
  if ( index >= startAt && index <= endAt ) {
    $( this).show();
  } else {
    $( this ).hide();
  }
});

You've used each() before, but you haven't yet made use of the index variable. index simply holds the value of the current iteration of the loop. You're free to name it anything you'd like.

For each iteration of the loop, a conditional runs to determine whether or not the index value of the current element in the collection (the table row) falls in between the startAt and endAt values.

If the current value of index is within the specified range, display the table row by applying jQuery's .show() function.

Otherwise, hide the table row by applying jQuery's .hide() function.

Both show() and hide() are built-in jQuery methods that manipulate an element's display property.

The final line of the script block kicks off the pagination by explicitly calling paginate() with a startAt value of 0.

There's more...

This is a fairly simple/straightforward demonstration of client-side pagination. However, it's not particularly user friendly.

For example, it might be nice to disable the Previous and Next links if the user is at the first or last page within the set.

It also might be nice to display a div above and/or below the table that shows a message, "Now displaying n-m of x records".

But now that we've done the basics, try making the interface a bit more user friendly on your own for extra credit.