By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,605 Members | 2,012 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

Resizable, sortable, findable and scrollable HTML table

P: 14
I figured I would post my solution to the following.

Resizable column tables.
Search and replace values in a table. (IE only)
Scrollable tables.
Sortable tables.

It is based on a lot examples I found on the web. Works in IE and mozilla.

http://www.imaputz.com/cssStuff/bigFourVersion.html
http://www.thescripts.com/forum/thre...resizable.html
http://www.kryogenix.org/code/browser/sorttable/

Todo.
Resize table.
Search and replace values in Mozilla.

Any suggestions or examples on the todo list would be greatly appreciated.

find.html
--------------------------------------
Expand|Select|Wrap|Line Numbers
  1. <HTML>
  2.     <HEAD>
  3. <TITLE>Find/Replace</TITLE>
  4. <script type="text/javascript">
  5. <!--
Expand|Select|Wrap|Line Numbers
  1. var inputTags = null;
  2. var found = false;
  3. var currentInputIdx = 0;
  4. var currentTextRange = null;
  5. var currentSearchVal = null;
  6.  
  7. function initFind(){
  8.    inputTags = new Array();
  9.    var tags = opener.document.getElementsByTagName("input");
  10.    if(tags != null){
  11.       for(i = 0; i < tags.length;++i){
  12.           if(tags[i].type == "text"){
  13.             inputTags[inputTags.length] = tags[i];
  14.           }
  15.       }
  16.    }
  17.  
  18.    tags = opener.document.getElementsByTagName("textarea");
  19.    if(tags != null){
  20.       for(i = 0; i < tags.length;++i){
  21.           inputTags[inputTags.length] = tags[i];
  22.       }
  23.    }
  24. }
  25.  
  26. // returns a calculated value for matching case and
  27. // matching whole words
  28. function searchType(){
  29.   var retval = 0;
  30.   var matchcase = 0;
  31.   var matchword = 0;
  32.   if (document.forms[0]['blnMatchCase'].checked) matchcase = 4;
  33.   if (document.forms[0]['blnMatchWord'].checked) matchword = 2;
  34.   retval = matchcase + matchword;
  35.   return(retval);
  36. }
  37.  
  38. function replaceText(){
  39.  
  40.    // if no current tag then find one
  41.    if(currentTextRange == null) {
  42.       findText();
  43.    }
  44.    // if we have one then replace 
  45.    else if(currentTextRange != null){
  46.       var beforeBookmark = currentTextRange.getBookmark();
  47.       var replaceStr = document.forms[0]['replaceStr'].value;
  48.       currentTextRange.text=replaceStr;
  49.       pushUndoNew(currentTextRange, beforeBookmark, currentSearchStr, replaceStr);
  50.       currentTextRange.collapse(false);
  51.       findText();
  52.    }
  53. }
  54.  
  55. function replaceAllText(){
  56.    found = false;
  57.    if(currentTextRange == null) findText();
  58.  
  59.    while(currentTextRange != null){
  60.        replaceText();
  61.    }
  62. }
  63.  
  64. function findText(){
  65.    if(inputTags == null) initFind();
  66.  
  67.    if (document.forms[0]['searchStr'].value.length < 1) {
  68.      alert("Please enter text in the \"Find what:\" field.");
  69.      return;
  70.    }
  71.  
  72.    if(inputTags.length == 0){
  73.       alert("No input field(s) found on page");
  74.       return;
  75.    }
  76.  
  77.    var searchVal = currentSearchStr = document.forms[0]['searchStr'].value;
  78.  
  79.    var useRegex = document.forms[0]['blnRegex'].checked;
  80.  
  81.    if( currentTextRange == null) {
  82.       currentTextRange = inputTags[currentInputIdx].createTextRange();
  83.       if(useRegex) currentText = currentTextRange.text;
  84.    }
  85.    else {
  86.        currentTextRange.collapse(false);
  87.       // get the remaining search range for regex
  88.        if(useRegex){
  89.            var rng = currentTextRange.duplicate();
  90.            rng.collapse(false);
  91.            rng.moveEnd("textedit");
  92.            currentText = rng.text;
  93.        }
  94.  
  95.    }
  96.  
  97.    var match = true;
  98.  
  99.    if(useRegex){
  100.       try{
  101.          var matches = currentText.match(new RegExp(searchVal));
  102.          if(matches){
  103.              currentSearchStr = matches[0];
  104.          }
  105.          else {
  106.              match = false;
  107.          }
  108.       }
  109.       catch(e){
  110.           alert("Illegal Regex: '" + searchVal + "'");
  111.           return;
  112.       }
  113.    }
  114.  
  115.    var type = searchType();
  116.  
  117.    // found a match within the current text field 
  118.    if( match && currentTextRange.findText(currentSearchStr, 10000, type)){
  119.        currentTextRange.select();
  120.        inputTags[currentInputIdx].scrollIntoView(false);
  121.        currentTextRange.scrollIntoView();
  122.        found = true;
  123.    }
  124.    // no match found and end of the document
  125.    else if( currentInputIdx >= inputTags.length-1 ){
  126.       currentTextRange = null;
  127.       currentInputIdx = 0;
  128.       if(found) alert("Done!");
  129.       else alert("Can not find '" +searchVal +"'");
  130.       found = false;
  131.    }
  132.    // no match found in the current text, look at the next text field 
  133.    else{
  134.       currentTextRange = null;
  135.       ++currentInputIdx;
  136.       findText();
  137.    }
  138. }
  139.  
  140. // BEGIN UNDO BUFFER CODE
  141. // buffer global variables
  142. var undoStack = new Array();
  143.  
  144. // UndoState Object
  145. function UndoState(textRange,searchStr,inputIdx,beforeBookmark, afterBookmark){
  146.    this.textRange = textRange;
  147.    this.searchStr = searchStr;
  148.    this.inputIdx = inputIdx;
  149.    /* two bookmarks are necessary to get back to the before and after state */
  150.    this.afterBookmark = afterBookmark;
  151.    this.beforeBookmark = beforeBookmark;
  152. }
  153.  
  154. // store original search string and bookmarks of each replaced range
  155. function pushUndoNew(rng, beforeBookmark,searchStr, replaceStr) {
  156.     currentTextRange.moveStart("character", -replaceStr.length);
  157.     undoStack[undoStack.length] = new UndoState( currentTextRange,searchStr,currentInputIdx,beforeBookmark,currentTextRange.getBookmark() );
  158. }
  159.  
  160. // perform the undo
  161. function undoReplace() {
  162.     if (undoStack.length) {
  163.         var newLength = undoStack.length-1;
  164.         currentTextRange = undoStack[newLength].textRange;
  165.         currentTextRange.moveToBookmark( undoStack[newLength].afterBookmark );
  166.  
  167.         currentTextRange.text = undoStack[newLength].searchStr;
  168.         currentTextRange.moveToBookmark( undoStack[newLength].beforeBookmark );
  169.  
  170.         // reselect the undo
  171.         currentTextRange.findText(undoStack[newLength].searchStr, 10000);
  172.         currentTextRange.select();
  173.         currentTextRange.scrollIntoView();
  174.  
  175.         currentInputIdx = undoStack[newLength].inputIdx;
  176.         undoStack.length=newLength;
  177.     }
  178. }
  179.  
  180. //-->
Expand|Select|Wrap|Line Numbers
  1. </script>
  2. </HEAD>
  3. <BODY bgcolor="#EAF4F3">
  4.   <FORM NAME="frmSearch" method="post" action="">
  5.   <table CELLSPACING="0" cellpadding="5" border="0">
  6.   <tr><td VALIGN="top" align="left" nowrap 
  7.               style="font-family:Arial; font-size:11px;">
  8.     <label for="searchStr" accesskey="n"><u>F</u>ind what:</label><br>
  9.     <INPUT TYPE="TEXT" SIZE=40 NAME="searchStr"
  10.            id="searchStr" style="width:280px;"><br>
  11.     <label for="replaceStr" accesskey="n"><u>R</u>eplace with:</label><br>
  12.     <INPUT TYPE="TEXT" SIZE=40 NAME="replaceStr"
  13.            id="replaceStr" style="width:280px;"><br>
  14.  
  15.     <INPUT TYPE="Checkbox" NAME="blnMatchCase" id="blnMatchCase">
  16.     <label for="blnMatchCase">Match case</label><br>
  17.  
  18.     <INPUT TYPE="Checkbox" NAME="blnMatchWord" ID="blnMatchWord">
  19.     <label for="blnMatchWord">Match whole word only</label>
  20.  
  21.     <INPUT TYPE="Checkbox" NAME="blnRegex" ID="blnRegex">
  22.     <label for="blnRegex">Use regular expression</label>
  23.  
  24.    </td>
  25.   <td rowspan="2" valign="top">
  26.     <button name="btnFind" accesskey="f" onClick="findText();"
  27.         style="width:75px; height:22px; font-family:Tahoma; 
  28.                font-size:11px; margin-top:15px"><u>F</u>ind Next</button><br>
  29.  
  30.     <button name="btnReplace" accesskey="r" onClick="replaceText();"
  31.         style="width:75px; height:22px; font-family:Tahoma; 
  32.                font-size:11px; margin-top:15px"><u>R</u>eplace</button>&nbsp;
  33.  
  34.     <button name="btnReplaceAll" accesskey="a" onClick="replaceAllText();"
  35.         style="width:75px; height:22px; font-family:Tahoma; 
  36.                font-size:11px; margin-top:15px">Replace <u>A</u>ll</button><br>
  37.  
  38.     <button name="btnUndo" onClick="undoReplace();"
  39.         style="width:75px; height:22px; font-family:Tahoma; 
  40.                font-size:11px; margin-top:15px">Undo</button><br>
  41.  
  42.     <button name="btnCancel" onClick="window.close();"
  43.         style="width:75px; height:22px; font-family:Tahoma; 
  44.                font-size:11px; margin-top:7px">Close</button><br>
  45.   </td></tr>
  46. </table>
  47. </FORM>
  48. </BODY>
  49. </HTML>
  50.  
main page.
------------------------------------
Expand|Select|Wrap|Line Numbers
  1. <HTML>
  2. <HEAD>
  3. <style>
Expand|Select|Wrap|Line Numbers
  1. h1, h2{
  2. font-family:Verdana, Arial, Helvetica, sans-serif;
  3.  font-size:13px;
  4.  
  5. }
  6.  
  7. </style>
  8.       <!--[if IE]>
  9.       <style type="text/css">
  10.          div.scrollable {
  11.                /* shrink the window */
  12.               height:expression( this.getElementsByTagName('TABLE')[0].clientHeight >= parseInt(this.getElementsByTagName('TBODY')[0].style.height)  && parseInt(this.getElementsByTagName('TBODY')[0].style.height) >  0 ? this.getElementsByTagName('TBODY')[0].style.height : "auto" );  
  13.               overflow-x: visible;
  14.               overflow-y: auto;
  15.           width: expression(this.getElementsByTagName('TABLE')[0].offsetWidth);
  16.          }
  17.  
  18.          /* set the table row */
  19.          div.scrollable table thead tr {
  20.          position: relative;
  21.            /* this fixes IE header jumping bug, adjust for the table border */
  22.            top: expression( (this.parentNode.parentNode.parentNode.scrollTop - 2)+ 'px' );   
  23.          }
  24.  
  25.          /* needed for IE if tbody.height is set */
  26.          div.scrollable tr{
  27.             height:auto;
  28.          }
  29.  
  30.       </style>
  31.       <![endif]-->
  32.  
  33.       <style type="text/css">
  34.          /* if mozilla */
  35.          html>body div.scrollable tbody {
  36.             overflow: auto;
  37.          }
  38.  
  39.          table.resizable th{
  40.             text-align:center;
  41.             overflow: hidden;
  42.          }
  43.  
  44.          /* if mozilla, add 10 for the scrollbar */
  45.          html>body th.scrollbarCol {
  46.             width:10px;
  47.          }
  48.  
  49.          table.resizable td{
  50.             overflow: hidden;
  51.          }
  52.  
  53.          table.resizable{
  54.             table-layout:fixed;
  55.          }
  56.  
  57.          table.resizable input{
  58.             width:100%;
  59.          }
  60.  
  61.          table.resizable textarea{
  62.             width:100%;
  63.          }
  64.  
  65.          .nowrap {
  66.              white-space:nowrap;
  67.          }
  68.  
  69.          /* needed for IE */
  70.          table.tabular th.scrollbarCol {
  71.             background-color:transparent; 
  72.          }
  73.  
  74.          table.tabular {
  75.             FONT-SIZE: 13px;
  76.             FONT-FAMILY: 'Verdana, Arial, Helvetica, sans-serif';
  77.             COLOR: #336699;
  78.          }
  79.  
  80.          table.tabular thead {
  81.              COLOR: #ffffff;
  82.              FONT-WEIGHT: bold;
  83.          }
  84.  
  85.          table.tabular th{
  86.             background-color:#c0c0c0; 
  87.             padding: 4px;
  88.          }
  89.  
  90.          table.tabular td {
  91.             background-color:#EAF4F3;
  92.             padding: 2px;
  93.          }
Expand|Select|Wrap|Line Numbers
  1.       </style>
  2.  
  3. <script type="text/javascript" src="http://www.kryogenix.org/code/browser/sorttable/sorttable.js" >    
  4. </script>
  5.  
  6. <SCRIPT type="text/javascript">
Expand|Select|Wrap|Line Numbers
  1. var ob;
  2. var over = false;
  3. var iEdgeThreshold = 10;
  4.  
  5. function findPos(obj) {
  6.   var curleft = curtop = 0;
  7.   if (obj.offsetParent) {
  8.       curleft = obj.offsetLeft;
  9.       curtop = obj.offsetTop;
  10.       while (obj = obj.offsetParent) {
  11.          curleft += obj.offsetLeft;
  12.          curtop += obj.offsetTop;
  13.       }
  14.    }
  15.    return [curleft,curtop];
  16. }
  17.  
  18. /* Function that tells me if on the border or not */
  19. function isOnBorderRight(objTable,objTh,event){
  20.   var width = objTh.offsetWidth;
  21.   var left = objTh.offsetLeft;
  22.   var pos = findPos(objTable);
  23.   var absRight = pos[0] + left + width;
  24.  
  25.   if( event.clientX > (absRight - iEdgeThreshold) ){
  26.       return true;
  27.   }
  28.  
  29.   return false;
  30. }
  31.  
  32. function getNodeName(objReference,nodeName){
  33.    var oElement = objReference;
  34.    while (oElement != null && oElement.tagName != null && oElement.tagName != "BODY") {
  35.       if (oElement.tagName.toUpperCase() == nodeName) {
  36.          return oElement;
  37.       }
  38.       oElement = oElement.parentNode;
  39.    }
  40.    return null;
  41. }
  42.  
  43. function doResize(objTh,event){
  44.     if(!event) event = window.event;
  45.     var objTable = getNodeName(objTh,"TABLE");
  46.     if( isOnBorderRight(objTable,objTh,event)){ 
  47.        over=true;
  48.        objTh.style.cursor="e-resize";
  49.     }
  50.     else{
  51.        over=false;
  52.        objTh.style.cursor="";
  53.     }
  54.     return over;
  55. }
  56.  
  57. function doneResizing(){
  58.    over=false;
  59. }
  60.  
  61. function MD(event) {
  62.    if(!event) event = window.event;
  63.  
  64.    MOUSTSTART_X=event.clientX;
  65.    MOUSTSTART_Y=event.clientY;
  66.  
  67.    if (over){      
  68.        if(event.srcElement)ob = event.srcElement;
  69.        else if(event.target)ob = event.target;
  70.        else return;
  71.  
  72.        ob = getNodeName(ob,"TH");
  73.        if(ob == null) return;
  74.        ob2 = getNodeName(ob,"TABLE");
  75.        obwidth=parseInt(ob.style.width);
  76.        obwidth2=parseInt(ob2.offsetWidth);
  77.    }        
  78. }
  79.  
  80. function MM(event) {
  81.     if(!event) event = window.event;
  82.  
  83.     if (ob) {
  84.         st=event.clientX-MOUSTSTART_X+obwidth;
  85.         st2=event.clientX-MOUSTSTART_X+obwidth2;
  86.  
  87.         if(st>=10){
  88.             ob.style.width=st;
  89.             ob2.style.width=st2;
  90.         }
  91.         if(document.selection) document.selection.empty();
  92.         else if(window.getSelection)window.getSelection().removeAllRanges();
  93.     }
  94. }
  95.  
  96. function MU(event) {
  97.     if(!event) event = window.event;
  98.     if(ob){
  99.         if(document.selection) document.selection.empty();
  100.         else if(window.getSelection)window.getSelection().removeAllRanges();
  101.         ob = null;
  102.     }
  103. }
  104.  
  105. document.onmousedown = MD;
  106. document.onmousemove = MM;
  107. document.onmouseup = MU;
Expand|Select|Wrap|Line Numbers
  1. </script>
  2.  
  3.  
  4. <SCRIPT type="text/javascript">
  5. <!--
  6. function createFindWindow(){
  7.     // FIXME: we need to do a mozilla implementation
  8.     //mozilla
  9.     if(window.find){
  10.        window.find();
  11.     }
  12.     // IE
  13.     else {
  14.        window.open( "find.html", "test","status=yes,width=500,height=250" );   
  15.     }
  16.  }
  17. //-->
  18. </script>
  19.  
  20.  
  21. </HEAD>
  22.  
  23. <BODY>
  24. <!-- 
  25. YOU MUST HAVE TO DEFINE WIDTH ON STYLE TAB.. if you leave NULL
  26. IT RETURNS .. ERROR..
  27. -->
  28. <H1>RESIZABLE TABLE COLUMN</H1>
  29. <form>
  30. <a href="javascript:createFindWindow()">Find</a>
  31.  
  32. <div class="scrollable" >
  33. <TABLE  id="mytable" style="width:510px" class="sortable resizable tabular">
  34.  
  35. <THEAD>
  36.  
  37. <TR>
  38.  
  39. <TH onmousemove="doResize(this,event)"  onmouseover="doResize(this,event)" onmouseout='doneResizing()' style='width:60px'>Index</TH>
  40.  
  41. <TH onmousemove="doResize(this,event)"  onmouseover="doResize(this,event)" onmouseout='doneResizing()' style='width:170px'><span class="nowrap">Parameter Name</span></TH>
  42.  
  43. <TH onmousemove="doResize(this,event)"  onmouseover="doResize(this,event)" onmouseout='doneResizing()' style='width:170px'><span class="nowrap">Parameter Value</span></TH>
  44.  
  45. <TH onmousemove="doResize(this,event)"  onmouseover="doResize(this,event)" onmouseout='doneResizing()' style='width:110px'><span class="nowrap">Page Name</span></TH>
  46.  
  47. <TH class="sorttable_nosort scrollbarCol"></TH>
  48.  
  49. </TR>
  50. </THEAD> 
  51. <TBODY style="height:200px">
  52. <TR>
  53.  
  54. <TD>0</TD>
  55.  
  56. <TD>1_2</TD>
  57.  
  58. <TD><input type="text" value="this is a very long text string, this is a very long text string"></TD>
  59.  
  60. <TD>1_3</TD>
  61.  
  62. </TR>
  63.  
  64. <TR>
  65.  
  66. <TD>0</TD>
  67.  
  68. <TD>1_2</TD>
  69.  
  70. <TD><input type="text" value="this is a very long text string, this is a very long text string"></TD>
  71.  
  72. <TD>1_3</TD>
  73.  
  74. </TR>
  75.  
  76. <TR>
  77.  
  78. <TD>0</TD>
  79.  
  80. <TD>1_2</TD>
  81.  
  82. <TD><input type="text" value="this is a very long text string, this is a very long text string"></TD>
  83.  
  84. <TD>1_3</TD>
  85.  
  86. </TR>
  87. <TR>
  88.  
  89. <TD>0</TD>
  90.  
  91. <TD>1_2</TD>
  92.  
  93. <TD><input type="text" value="this is a very long text string, this is a very long text string"></TD>
  94.  
  95. <TD>1_3</TD>
  96.  
  97. </TR>
  98. <TR>
  99.  
  100. <TD>0</TD>
  101.  
  102. <TD>1_2</TD>
  103.  
  104. <TD><input type="text" value="this is a very long text string, this is a very long text string"></TD>
  105.  
  106. <TD>1_3</TD>
  107.  
  108. </TR>
  109. <TR>
  110.  
  111. <TD>0</TD>
  112.  
  113. <TD>1_2</TD>
  114.  
  115. <TD><input type="text" value="this is a very long text string, this is a very long text string"></TD>
  116.  
  117. <TD>1_3</TD>
  118.  
  119. </TR>
  120. <TR>
  121.  
  122. <TD>0</TD>
  123.  
  124. <TD>1_2</TD>
  125.  
  126. <TD><input type="text" value="this is a very long text string, this is a very long text string"></TD>
  127.  
  128. <TD>1_3</TD>
  129.  
  130. </TR>
  131. <TR>
  132.  
  133. <TD>0</TD>
  134.  
  135. <TD>1_2</TD>
  136.  
  137. <TD><input type="text" value="this is a very long text string, this is a very long text string"></TD>
  138.  
  139. <TD>1_3</TD>
  140.  
  141. </TR>
  142.  
  143. <TR>
  144.  
  145. <TD>1</TD>
  146.  
  147. <TD><span class="nowrap">this is a very long paramter name</span></TD> 
  148.  
  149. <TD>2_2</TD>
  150.  
  151.  
  152. <TD>2_3</TD>
  153.  
  154.  
  155. </TR>
  156.  
  157.  
  158. <TR>
  159.  
  160. <TD>3_0</TD>
  161. <TD>3_2</TD>
  162.  
  163. <TD><textarea> 
  164. this is a test of
  165. this is a test of
  166. </textarea></TD>
  167.  
  168. <TD>3_3</TD>
  169.  
  170.  
  171. </TR>
  172.  
  173.  
  174. <TR>
  175.  
  176. <TD>4_0</TD>
  177.  
  178.  
  179. <TD>4_1</TD>
  180.  
  181.  
  182. <TD>4_2</TD>
  183.  
  184. <TD>4_3</TD>
  185.  
  186. </TR>
  187.  
  188. </TBODY>
  189. </table>
Expand|Select|Wrap|Line Numbers
  1. <!-- needed for mozilla to shrink the window -->
  2. <script type="text/javascript">
  3.   <!--
  4.   if(window.navigator && window.navigator.userAgent.indexOf("ecko") != -1  ){
  5.       var tbody=document.getElementById('mytable').getElementsByTagName('tbody')[0];
  6.       if(tbody.scrollHeight<=parseInt(tbody.style.height)) tbody.style.height="auto";
  7.   }
  8.   //-->
Expand|Select|Wrap|Line Numbers
  1. </script>
  2. </div>
  3. </form>
  4. </BODY>
  5. </HTML>
  6.  
  7.  
Nov 15 '07 #1
Share this Article
Share on Google+
1 Comment


P: 5
Please help me out. Your script is not working in Mozilla but good in IE.The problem is with DOCTYPE in mozilla.If i remove the doctype from the page it is working but making my page layout weird.But no problem with IE8 even if i keep DOCTYPE.
Dec 16 '09 #2