Dynamic Table Manipulation Using jQuery

By Rob Gravelle

Shortly after my article on Working with Tables Using jQuery was posted, I received questions from readers about how to accomplish other operations on HTML tables. Rather than attempt to answer everyone individually, I incorporated the answers into a new library. In today's article, I'll go over some of the functions, including how to insert rows and columns in a table at a given index.

Inserting a Row

In the Working with Tables Using jQuery article, we learned how to append a new row to the end of the table. One reader asked how we could modify the appendTableRow() function to insert the row at a given index instead, such as the first row after the headers. To do that, we need to find the row in question using the .eq() selector of the jQuery DOM collection object. It accepts a 0-based index argument that it utilizes to fetch the item from the collection at the given index. Once we've got the correct row, it's just a matter of inserting the new row after it:

function insertTableRow(table, rowData, index) {
  var newRow = $('<tr/>').insertAfter( table.find('tr').eq(index) );
  $(rowData).each(function(colIndex) {  
      newRow.append($('<td/>').text(this));
  });
   
  return newRow;
}

Hence, the following call to the above function inserts a new three-column row immediately after the headers:

insertTableRow(table, ["Calgary", "Ottawa", "Yellowknife"], 0);

Updating the appendTableRow() Function

The appendTableRow() function's size can be greatly reduced by delegating to our new function. An interesting thing about the .eq() selector is that it accepts negative numbers. That causes it to select items going backwards from the last one in the collection. Therefore, passing an index of -1 to our insertTableRow() function inserts the new row after the last existing one in the table.

function appendTableRow(table, rowData) {
  //table.find('tr:last').index() also works
  return insertTableRow( table, rowData, -1 );
}

Inserting a New Column

Columns are a little more challenging to work with because there is no column element per se. Rather, a column is made up of a collection of TD elements, each contained within a different TR. Therefore, looping over each TR works well for this purpose.

Insofar as inserting the TD elements, neither insertBefore() or insertAfter() work every time, because there may not be a TD before or after the insert position. For that reason, appendTo() is employed if the index is larger than the number of existing columns:

function insertTableColumn(table, columnData, index) {
  var newColumn = [], 
      colsCount = table.find('tr > td:last').index();

  table.find("tr").each( function(rowIndex) {
    var cell = $("<t"+(rowIndex == 0 ?  "h" : "d")+"/>").text(columnData[rowIndex]);
    newColumn.push( 
      index > colsCount
            ? cell.appendTo(this)
            : cell.insertBefore( $(this).children().eq(index) )
    );
  });

  return newColumn;
}

Appending a New Column

The insertTableColumn() can be utilized to append a new column to the right side of a table, but calculating the index is more difficult that it was with rows. We essentially want to supply the function with the number of columns plus one. Any row may be used as the reference, but I chose to go with the table headers (TR). The "tr > td" selector gets us the all of the columns. To obtain the last one, we can use the ":last" jQuery extension selector. From there, we can call the index() function to obtain its index. Hence, if the table header contains four cells, table.find('tr > td:last').index() returns a value of 3.

appendTableColumn = function(table, data) {
  return insertTableColumn(table, data, table.find('tr > td:last').index() + 1 );
};

The jquery-tables Library

I got so carried away with the demo for this article that I wound up creating a whole script to help with the dynamic creation and management of HTML tables. I christened it the "jquery-tables" library. To use it, simply extract this zip archive to your device and open the jquery-table-demo.html file in your favorite browser. The demo references a hosted jquery script, so you'll need Internet access for the demo to work. The demo showcases a few of the library's functions, such as makeTable(), appendRow(), appendColumn(), updateData(), as well as the $TBL() wrapper. The latter accepts a selector string and behaves exactly like the jQuery $() function, except that it iterates over the matched elements and adds the table functions to tables so that they may be invoked as instance methods, i.e.:

//fetch every table in the page
var tables = $TBL('table');
tables.each(function() {
  //print the contents of every table to the console
  //getDataAt() is a member of the table element
  console.log( this.getDataAt(0,0) );
});

Full instructions on using the script are included at the top of the jquery-tables.js file.

Rob Gravelle

Rob Gravelle resides in Ottawa, Canada, and is the founder of GravelleWebDesign.com. Rob has built systems for Intelligence-related organizations such as Canada Border Services, CSIS as well as for numerous commercial businesses.

In his spare time, Rob has become an accomplished guitar player, and has released several CDs. His band, Ivory Knight, was rated as one of Canada's top hard rock and metal groups by Brave Words magazine (issue #92) and reached the #1 spot in the National Heavy Metal charts on Reverb Nation.



Make a Comment

Loading Comments...

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
  •  
  •  
  •  
Thanks for your registration, follow us on our social networks to keep up-to-date