469,655 Members | 1,852 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Share your developer knowledge by writing an article on Bytes.

Table with filtering to the content

Greetings again everyone
Recently i´ve been asked to develop a script to allow filtering in the content of the table, with dinamic options based on the own content. Example: a table with the name of some students and their respective numbers, and then you wanna show only studentes called "Joao", or students with number "5", or even only students called "joao" with number "5".

The structure we are going to use is a basic html table, like:

Expand|Select|Wrap|Line Numbers
  1. <table>
  2.  <thead>
  3.   <tr>
  4.    <th>Header</th>
  5.   </tr>
  6.  </thead>
  7.  <tbody>
  8.   <tr>
  9.    <td>Content</td>
  10.   </tr>
  11.  </tbody>
  12. </table>
  13.  
And here comes the css/js, and after that a simple sample.

JS: filter:js
Expand|Select|Wrap|Line Numbers
  1. ///////////////////////////////////////////////
  2. // Created by: Romulo do Nascimento Ferreira //
  3. // Email: romulo.nf@gmail.com                //
  4. ///////////////////////////////////////////////
  5. //
  6. // Parameters
  7. // tableID = id of the table to allow the filtering
  8. // numRows = max number of rows to show (more will create a scrollbar)
  9. //
  10.  
  11. function createFilter(tableID,numRows) {
  12. this.table = document.getElementById(tableID)
  13. this.table.className = "filter"
  14. this.header = this.table.tHead
  15. this.mainBody = this.table.tBodies[0]
  16. this.numCol = this.header.rows[0].cells.length
  17. this.maxRows = numRows
  18. this.selectArray = new Array(this.numCol)
  19. this.optionArray = new Array(this.numCol)
  20.  
  21. // create an extra tr beneath the header
  22. this.newTr = document.createElement("tr")
  23. this.header.appendChild(this.newTr)
  24.  
  25.     for (x=0; x<this.numCol; x++) {
  26.     // loop to create the th's
  27.     tempTh = document.createElement("th")
  28.     this.newTr.appendChild(tempTh)
  29.  
  30.     // create one select box to each th
  31.     tempSelect = document.createElement("select")
  32.     tempSelect.style.width = this.header.rows[0].cells[x].offsetWidth - 10 + "px"
  33.     tempSelect.ativado = false
  34.     tempSelect.filtro = this
  35.     tempSelect.onchange = function() { this.filtro.applyFilter(this) }
  36.     this.selectArray[x] = tempSelect
  37.     tempTh.appendChild(tempSelect)
  38.     }
  39.  
  40.     for (x=0; x<this.header.rows.length; x++) {
  41.     // create an extra th to allow the scrolling
  42.     tempTh = document.createElement("th")
  43.     tempTh.className = "scrollBar"
  44.     this.header.rows[x].appendChild(tempTh)
  45.     }
  46.  
  47.     // change the table normal structure to allow the scroll
  48.     tempTr = document.createElement("tr")
  49.     tempTd = document.createElement("td")
  50.     divHolder = document.createElement("div")
  51.     tempTable = document.createElement("table")
  52.     this.newBody = document.createElement("tbody")
  53.  
  54.     for (x=this.mainBody.rows.length-1; x>=0; x--) {
  55.     this.newBody.appendChild(this.mainBody.rows[x])
  56.     }
  57.  
  58.     tempTd.colSpan = this.numCol + 1
  59.     divHolder.className = "holder"
  60.  
  61.     this.mainBody.appendChild(tempTr)
  62.     tempTr.appendChild(tempTd)
  63.     tempTd.appendChild(divHolder)
  64.     divHolder.appendChild(tempTable)
  65.     tempTable.appendChild(this.newBody)
  66.     divHolder.style.height = numRows * this.newBody.rows[0].cells[0].offsetHeight + "px"
  67.  
  68.     this.populateFilters()
  69. }
  70.  
  71. createFilter.prototype.populateFilters = function() {
  72.  
  73.     for (x=0; x<this.numCol; x++) {
  74.  
  75.     tempOptionArray = new Array()
  76.     count = 0
  77.  
  78.     // clear all the options from the selects
  79.         if (this.selectArray[x].options.length > 0) {
  80.             for (y=this.selectArray[x].options.length-1; y>=0; y--) {
  81.             this.selectArray[x].remove(y)
  82.             }
  83.         }
  84.  
  85.         // search through all visible rows and populate an array with all the possibilities
  86.         for (y=0; y<this.newBody.rows.length; y++) {
  87.             if (this.newBody.rows[y].style.display !="none") {
  88.             tempOptionArray[count] = this.newBody.rows[y].cells[x].innerHTML
  89.             count = count + 1
  90.             }
  91.         }
  92.  
  93.         // sort this array
  94.         tempOptionArray.sort()
  95.  
  96.         // remove all repeated entries
  97.         for (y=tempOptionArray.length-1; y>=1; y--) {
  98.             if (tempOptionArray[y] == tempOptionArray[y-1]) {
  99.             tempOptionArray.splice(y,1)
  100.             }
  101.         }
  102.  
  103.         // create a blank option to remove the filter
  104.         blankOption = document.createElement("option")
  105.         blankOption.innerHTML = ""
  106.         blankOption.value = ""
  107.         this.selectArray[x].appendChild(blankOption)
  108.  
  109.         // loop the array and populate the select box
  110.         for (y=0; y<tempOptionArray.length; y++) {
  111.         newOption = document.createElement("option")
  112.         newOption.innerHTML = tempOptionArray[y]
  113.         newOption.value = tempOptionArray[y]
  114.         this.selectArray[x].appendChild(newOption)
  115.             if (this.selectArray[x].ativado) {
  116.             this.selectArray[x].options[1].selected = "selected"                
  117.             }
  118.         }
  119.     }
  120.  
  121.     this.zebraRows()
  122. }
  123.  
  124. createFilter.prototype.applyFilter = function(filtro) {
  125. cellIndex = filtro.parentNode.cellIndex
  126. appliedFilter = filtro.value
  127.  
  128. appliedFilter != "" ? filtro.ativado = true : filtro.ativado = false
  129.  
  130.     // loop all rows and compare the innerHTML from the tds with the filter
  131.     // hide the tds that dont match the filter
  132.     for (x=0; x<this.newBody.rows.length; x++) {
  133.         this.newBody.rows[x].flag = false
  134.         for (y=0; y<this.numCol; y++) {
  135.             if (this.newBody.rows[x].cells[y].innerHTML != this.selectArray[y].value && this.selectArray[y].value !="") {
  136.             this.newBody.rows[x].flag = true
  137.             }
  138.         }
  139.         this.newBody.rows[x].flag ? this.newBody.rows[x].style.display = "none" : this.newBody.rows[x].style.display = ""
  140.     }
  141.  
  142.     this.populateFilters()
  143. }
  144.  
  145. createFilter.prototype.zebraRows = function() {
  146. this.nextClass = "odd"
  147.  
  148.     for (x=0; x<this.newBody.rows.length; x++) {
  149.         if (this.newBody.rows[x].style.display != "none") {
  150.         this.newBody.rows[x].className = this.nextClass
  151.         this.nextClass == "odd" ? this.nextClass = "even" : this.nextClass = "odd"
  152.         }
  153.     }
  154. }
  155.  
CSS: filter.css
Expand|Select|Wrap|Line Numbers
  1. .filter {border-collapse:collapse; table-layout:fixed; width:500px}
  2. .filter th {text-align:center; background:#eee; border:1px dotted #777; font:bold 11px verdana; line-height:16px; padding:1px}
  3. .filter td {text-indent:5px; overflow:hidden; white-space:nowrap; font:normal 11px verdana}
  4. .filter th select {overflow:hidden; font:normal 11px verdana}
  5.  
  6. .even td {background:#fff}
  7. .odd td {background:#eee}
  8.  
  9. .filter table {width:480px; table-layout:fixed; border-collapse:collapse}
  10. .filter .holder {width:499px; overflow:auto;}
  11. .filter .scrollBar {border:0; background:transparent; width:13px;}
  12. * html .filter .scrollBar {width:16px}
  13.  
Sample: filter.html
Expand|Select|Wrap|Line Numbers
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  2.  
  3. <html>
  4. <head>
  5. <title>Filter</title>
  6. </head>
  7.  
  8. <script src="filter.js"></script>
  9. <link rel="stylesheet" href="filter.css" type="text/css">
  10.  
  11. <script>
  12. window.onload = function() {
  13. new createFilter("tabelaUm",10)
  14. }
  15. </script>
  16.  
  17. <body>
  18.  
  19. <h2>Filter</h2>
  20.  
  21. <script>
  22.  
  23. arrayNomes = ['Ricardo','Paulo','Maria','Joana','Rita','Fabiano']
  24. arrayNumeros = ['1','2','3','4','5','6','7','8','9']
  25. arrayTipo = ['Excellent','OK','Bad']
  26.  
  27. tabela = document.createElement("table")
  28. tabela.id = "tabelaUm"
  29.  
  30. thead = document.createElement("thead")
  31. tabela.appendChild(thead)
  32.  
  33. tr = document.createElement("tr")
  34.  
  35.     for (x=0; x<4; x++) {
  36.     th = document.createElement("th")
  37.     th.innerHTML = "Header " + (x+1)
  38.     tr.appendChild(th)
  39.     }
  40.  
  41. thead.appendChild(tr)
  42.  
  43. tbody = document.createElement("tbody")
  44.  
  45.     for (x=0; x<250; x++) {
  46.     tr = document.createElement("tr")
  47.  
  48.         td = document.createElement("td")
  49.         td.innerHTML = arrayNomes[Math.floor(Math.random()*6)]
  50.         tr.appendChild(td)
  51.  
  52.         td = document.createElement("td")
  53.         td.innerHTML = arrayNumeros[Math.floor(Math.random()*9)]
  54.         tr.appendChild(td)
  55.  
  56.         td = document.createElement("td")
  57.         td.innerHTML = arrayNumeros[Math.floor(Math.random()*9)]
  58.         tr.appendChild(td)
  59.  
  60.         td = document.createElement("td")
  61.         td.innerHTML = arrayTipo[Math.floor(Math.random()*3)]
  62.         tr.appendChild(td)        
  63.  
  64.     tbody.appendChild(tr)
  65.     }
  66.  
  67. tabela.appendChild(tbody)
  68. document.getElementsByTagName("body")[0].appendChild(tabela)
  69.  
  70. </script>
  71.  
  72. </body>
  73. </html>
  74.  
Thats basically it. Feel free to use the script anywhere.
If you find something needing some fix, send me an email.

Good luck!
Nov 1 '07 #1
0 5799

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

2 posts views Thread by Vector | last post: by
3 posts views Thread by serge calderara | last post: by
2 posts views Thread by Seth | last post: by
3 posts views Thread by Joachim Klassen | last post: by
2 posts views Thread by Konrad | last post: by
9 posts views Thread by shanevanle | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.