Click here to Skip to main content
16,007,885 members
Articles / Web Development / HTML
Article

HTML Table Filter ala Excel

Rate me:
Please Sign up or sign in to vote.
4.75/5 (37 votes)
3 Aug 2005CPOL1 min read 228K   2.3K   56   71
A way to filter a large table in a simple manner.

Demo

<script language="javascript"></script>

<input id="chk" önclick="enableFilter();" type="checkbox" name="chk" />Enable Filter

Col1Col2
1string
1string2
2String
2STRING2
3
1string
1string2
2String
2STRING2
3

Introduction

When I was writing a web application, I needed a way to filter a large table in a simple manner. The users of the application are used to the auto filtering in MS Excel, so I wanted my filter to have the same look and feel.

Features

  • Once a column is filtered, the dropdown boxes for the rest of the columns are adapted to the changes. Just like the auto filter in Excel works!
  • If a row has the class noFilter, the row will not be touched by the filter.

Using the code

Using the code is very simple. Just include the script to the page:

HTML
<script language="javascript" src="tablefilter.js"></script>

And activate the filter in the OnLoad:

HTML
<body onload="attachFilter(document.getElementById('tbl'), 1)">

attachFilter expects two parameters:

  1. The table object to attach the filter to.
  2. The row number at which the filter row should be inserted.

Browser Compatibility

The script was initially written for IE. I did test it successfully on Firefox, but I do not know if the script works for Netscape browsers.

History

  • 2005/07/27: First version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
AnswerRe: One filter for 3 columns: it´s possible? Pin
WoutL14-Jan-07 21:00
WoutL14-Jan-07 21:00 
GeneralRe: One filter for 3 columns: it´s possible? Pin
OdaScatolini15-Jan-07 5:00
OdaScatolini15-Jan-07 5:00 
Generalhelp please! Pin
OdaScatolini10-Jan-07 7:24
OdaScatolini10-Jan-07 7:24 
GeneralRe: help please! Pin
WoutL10-Jan-07 20:37
WoutL10-Jan-07 20:37 
Questionno filter for one column Pin
devzo31-Oct-06 1:28
devzo31-Oct-06 1:28 
AnswerRe: no filter for one column Pin
WoutL31-Oct-06 21:01
WoutL31-Oct-06 21:01 
AnswerRe: no filter for one column Pin
dribagnac22-Jan-07 2:23
dribagnac22-Jan-07 2:23 
AnswerRe: no filter for one column Pin
dribagnac22-Jan-07 2:33
dribagnac22-Jan-07 2:33 
This is my whole script, it is better to give full code Smile | :)


---------------
/*
http://www.codeproject.com/jscript/filter.asp
Using the code is very simple. Just include the script to the page:


And activate the filter in the OnLoad:


attachFilter expects two parameters:

The table object to attach the filter to.
The row number at which the filter row should be inserted.

within thead to avoid filtering
*/
// Attach the filter to a table. filterRow specifies the rownumber at which the filter should be inserted.
function attachFilter(table, filterRow)
{
table.filterRow = filterRow;
// Check if the table has any rows. If not, do nothing
if(table.rows.length > 0)
{
// Insert the filterrow on header and add cells whith drowdowns.
var filterRow = table.tHead.insertRow(table.filterRow);
for(var i = 0; i < table.rows[table.filterRow + 1].cells.length; i++)
{
var c = document.createElement("TH");
//table.rows[table.filterRow].appendChild(c);

filterRow.appendChild(c);
if (table.tHead.rows[0].cells[i].className != "noFilter") {
var opt = document.createElement("select");
opt.onchange = filter;

c.appendChild(opt);
}
}
// Set the functions
table.fillFilters = fillFilters;
table.inFilter = inFilter;
table.buildFilter = buildFilter;
table.showAll = showAll;
table.alternateRowColorTable = alternateRowColorTable;
table.detachFilter = detachFilter;
table.filterElements = new Array();

// Fill the filters
table.fillFilters();
table.filterEnabled = true;
}
}

function detachFilter()
{
if(this.filterEnabled)
{
// Remove the filter
this.showAll();
this.deleteRow(this.filterRow);
this.filterEnabled = false;
}
}

// Checks if a column is filtered
function inFilter(col)
{
for(var i = 0; i < this.filterElements.length; i++)
{
if(this.filterElements[i].index == col)
return true;
}
return false;
}

// Fills the filters for columns which are not fiiltered
function fillFilters()
{
for(var col = 0; col < this.rows[this.filterRow].cells.length; col++)
{
if(!this.inFilter(col))
{
//alert(col.className)
//alert(this.tHead.rows[0].cells[col].className)
if (this.tHead.rows[0].cells[col].className != "noFilter") {
this.buildFilter(col, "(all)");
}
}
}
}

// Fills the columns dropdown box.
// setValue is the value which the dropdownbox should have one filled.
// If the value is not suplied, the first item is selected
function buildFilter(col, setValue)
{
// Get a reference to the dropdownbox.
var opt = this.rows[this.filterRow].cells[col].firstChild;

// remove all existing items
while(opt.length > 0)
opt.remove(0);

var values = new Array();

// put all relevant strings in the values array.
for(var i = this.filterRow + 1; i < this.rows.length; i++)
{
var row = this.rows[i];
if(row.style.display != "none" && row.className != "noFilter")
{
values.push(row.cells[col].innerHTML.toLowerCase());
}
}
values.sort();

//add each unique string to the dopdownbox
var value;
for(var i = 0; i < values.length; i++)
{
if(values[i].toLowerCase() != value)
{
value = values[i].toLowerCase();
opt.options.add(new Option(values[i], value));
}
}

opt.options.add(new Option("(all)", "(all)"), 0);

if(setValue != undefined)
opt.value = setValue;
else
opt.options[0].selected = true;
}

// This function is called when a dropdown box changes
function filter()
{
var table = this; // 'this' is a reference to the dropdownbox which changed
while(table.tagName.toUpperCase() != "TABLE")
table = table.parentNode;

var filterIndex = this.parentNode.cellIndex; // The column number of the column which should be filtered
var filterText = table.rows[table.filterRow].cells[filterIndex].firstChild.value;

// First check if the column is allready in the filter.
var bFound = false;

for(var i = 0; i < table.filterElements.length; i++)
{
if(table.filterElements[i].index == filterIndex)
{
bFound = true;
// If the new value is '(all') this column is removed from the filter.
if(filterText == "(all)")
{
table.filterElements.splice(i, 1);
}
else
{
table.filterElements[i].filter = filterText;
}
break;
}
}
if(!bFound)
{
// the column is added to the filter
var obj = new Object();
obj.filter = filterText;
obj.index = filterIndex;
table.filterElements.push(obj);
}

// first set all rows to be displayed
table.showAll();

// the filter ou the right rows.
for(var i = 0; i < table.filterElements.length; i++)
{
// First fill the dropdown box for this column
table.buildFilter(table.filterElements[i].index, table.filterElements[i].filter);
// Apply the filter
for(var j = table.filterRow + 1; j < table.rows.length; j++)
{
var row = table.rows[j];

if(table.style.display != "none" && row.className != "noFilter")
{
if(table.filterElements[i].filter != row.cells[table.filterElements[i].index].innerHTML.toLowerCase())
{
row.style.display = "none";
}
}
}
}
// Fill the dropdownboxes for the remaining columns.
table.fillFilters();
table.alternateRowColorTable();
}

function showAll()
{
for(var i = this.filterRow + 1; i < this.rows.length; i++)
{
this.rows[i].style.display = "";
}
}

function alternateRowColorTable() {
if(document.getElementsByTagName){
var rows = this.getElementsByTagName("tr");
var j=0;

for(i = 0; i < rows.length; i++){
//manipulate rows if row is displayed
if (rows[i].style.display != "none") {
if(j % 2 == 0){
rows[i].className = "even";
}else{
rows[i].className = "odd";
}

j++;
}
}
}
}
GeneralNew Features Pin
justinkelly23-Jul-06 20:30
justinkelly23-Jul-06 20:30 
GeneralChanging the font/color of the cell Pin
ahooja28-Jun-06 11:40
ahooja28-Jun-06 11:40 
GeneralRe: Changing the font/color of the cell Pin
WoutL28-Jun-06 20:55
WoutL28-Jun-06 20:55 
GeneralEnable/Disable filter question Pin
ahooja27-Jun-06 7:03
ahooja27-Jun-06 7:03 
GeneralRe: Enable/Disable filter question Pin
WoutL27-Jun-06 20:37
WoutL27-Jun-06 20:37 
GeneralRe: Enable/Disable filter question Pin
dribagnac22-Jan-07 2:21
dribagnac22-Jan-07 2:21 
GeneralRealmente bueno el código.... Pin
Juan Melgar20-Apr-06 14:52
Juan Melgar20-Apr-06 14:52 
GeneralQuick question Pin
pcockey15-Feb-06 13:58
pcockey15-Feb-06 13:58 
GeneralRe: Quick question Pin
WoutL16-Feb-06 0:15
WoutL16-Feb-06 0:15 
GeneralRe: Quick question Pin
pcockey16-Feb-06 10:08
pcockey16-Feb-06 10:08 
GeneralGreat Job Pin
henk jansen11-Oct-05 3:27
henk jansen11-Oct-05 3:27 
GeneralRe: Great Job Pin
WoutL11-Oct-05 3:34
WoutL11-Oct-05 3:34 
QuestionAdditional Function Pin
klmohr7-Oct-05 15:21
klmohr7-Oct-05 15:21 
AnswerRe: Additional Function Pin
WoutL11-Oct-05 21:08
WoutL11-Oct-05 21:08 
GeneralRe: Additional Function Pin
klmohr12-Oct-05 15:15
klmohr12-Oct-05 15:15 
GeneralSome Html/css resources. Pin
Anonymous14-Aug-05 2:56
Anonymous14-Aug-05 2:56 
GeneralNice! Works for Opera 8.02! Pin
Denis Chekhlov11-Aug-05 23:50
Denis Chekhlov11-Aug-05 23:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.