»
EnglishFrenchVietnamese

Print - Sortable and Lockable Sheet - JavaScriptBank.com

Full version: jsB@nk » Form » Sortable and Lockable Sheet
URL: https://www.javascriptbank.com/sortable-and-lockable-sheet.html

Sortable and Lockable Sheet © JavaScriptBank.comOne more JavaScript effect quites powerful to make arrangement on spreadsheet data. In order to sort, users simply click on the label which want to be conducted. Effects can make the arrangements for the type of data such as number, text, currency, percentage values, date,...Also you can try the JavaScript codes similar as: Sort table data, Sort data

Full version: jsB@nk » Form » Sortable and Lockable Sheet
URL: https://www.javascriptbank.com/sortable-and-lockable-sheet.html



CSS
<style type="text/css"><!--/* Scrollable Content Height */.scrollContent { height:100px; overflow-x:hidden; overflow-y:auto;}.scrollContent tr { height: auto; white-space: nowrap;}/* Prevent Mozilla scrollbar from hiding right-most cell content */.scrollContent tr td:last-child { padding-right: 20px;}/* Fixed Header Height */.fixedHeader tr { position: relative; height: auto;}/* Put border around entire table */div.TableContainer { border: 1px solid #7DA87D;}/* Table Header formatting */.headerFormat { background-color: white; color: #FFFFFF; margin: 3px; padding: 1px; white-space: nowrap; font-family: Helvetica; font-size: 16px; text-decoration: none; font-weight: bold;}.headerFormat tr td { border: 1px solid #000000; background-color: #7DA87D;}/* Table Body (Scrollable Content) formatting */.bodyFormat tr td {color: #000000;margin: 3px;padding: 1px;border: 0px none;font-family: Helvetica;font-size: 12px;}/* Use to set different color for alternating rows */.alternateRow {  background-color: #E0F1E0;}/* Styles used for SORTING */.point { cursor:pointer;}td.sortedColumn {  background-color: #E0F1E0;}tr.alternateRow td.sortedColumn {  background-color: #c5e5c5;}.total {background-color: #FED362;color: #000000;white-space: nowrap;font-size: 12px;text-decoration: none;}--></style><!--[if IE]><style type="text/css">/* IE Specific Style addition to constrain table   from automatically growing in height */div.TableContainer { height: 121px; overflow-x:hidden; overflow-y:auto;}</style><![endif]-->


JavaScript
<script type="text/javascript" name="sortTable.js.js">// Created by: Stan Slaughter :: http://www.stansight.com//* ======================================================Generic Table SortBasic Concept: A table can be sorted by clicking on the title of anycolumn in the table, toggling between ascending and descending sorts.Assumptions:* The first row of the table contains column titles that are "clicked"  to sort the table* The images 'desc.gif','asc.gif','none.gif','sorting.gif' exist* The img tag is in each column of the the title row to represent the  sort graphic.* The CSS classes 'alternateRow' and 'sortedColumn' exist so we can  have alternating colors for each row and a highlight the sorted  column.  Something like the <style> definition below, but with the  background colors set to whatever you want.   <style>   tr.alternateRow {     background-color: #E0F1E0;   }   td.sortedColumn {     background-color: #E0F1E0;   }   tr.alternateRow td.sortedColumn {     background-color: #c5e5c5;   }   </style>====================================================== */function sortTable(td_element,ignoreLastLines) {  // If the optional ignoreLastLines parameter (number of lines *not* to sort at end of table)  // was not passed then make it 0  ignoreLastLines = (typeof(ignoreLastLines)=='undefined') ? 0 : ignoreLastLines;  var sortImages =['desc.gif','asc.gif','none.gif','sorting.gif'];  // Get the image used in the first row of the current column  var sortColImage = td_element.getElementsByTagName('img')[0];  // If current image is 'asc.gif' or 'none.gif' (elements 1 and 2 of sortImages array) then this will  // be a descending sort else it will be ascending - get new sort image icon and set sort order flag  var sortAscending = false;  var newSortColImage = "";  if (sortColImage.getAttribute('src').indexOf(sortImages[1])>-1 ||    sortColImage.getAttribute('src').indexOf(sortImages[2])>-1) {    newSortColImage = sortImages[0];    sortAscending = false;  } else {    newSortColImage = sortImages[1];    sortAscending = true;  }  // Assign "SORTING" image icon (element 3 of sortImages array)) to current column title  // (will replace with newSortColImage when sort completes)  sortColImage.setAttribute('src',sortImages[3]);  // Find which column was clicked by getting it's column position  var indexCol = td_element.cellIndex;  // Get the table element from the td element that was passed as a parameter to this function  var table_element = td_element.parentNode;  while (table_element.nodeName != "TABLE") {    table_element = table_element.parentNode;  }  // Get all "tr" elements from the table and assign then to the Array "tr_elements"  var tr_elements = table_element.getElementsByTagName('tr');  // Get all the images used in the first row then set them to 'none.gif'  // (element 2 or sortImages array) except for the current column (all ready been changed)  var allImg = tr_elements[0].getElementsByTagName('img');    for(var i=0;i<allImg.length;i++){    if(allImg[i]!=sortColImage){allImg[i].setAttribute('src',sortImages[2])}  }  // Some explantion of the basic concept of the following code before we  // actually start.  Essentially we are going to copy the current columns information  // into an array to be sorted. We'll sort the column array then go back and use the information  // we saved about the original row positions to re-order the entire table.  // We are never really sorting more than a columns worth of data, which should keep the sorting fast.  // Create a new array for holding row information  var clonedRows = new Array()  // Create a new array to store just the selected column values, not the whole row  var originalCol = new Array();  // Now loop through all the data row elements  // NOTE: Starting at row 1 because row 0 contains the column titles  for (var i=1; i<tr_elements.length - ignoreLastLines; i++) {   // "Clone" the tr element i.e. save a copy all of its attributes and values   clonedRows[i]=tr_elements[i].cloneNode(true);   // Text value of the selected column on this row   var valueCol = getTextValue(tr_elements[i].cells[indexCol]);   // Format text value for sorting depending on its type, ie Date, Currency, number, etc..   valueCol = FormatForType(valueCol);   // Assign the column value AND the row number it was originally on in the table   originalCol[i]=[valueCol,tr_elements[i].rowIndex];  }  // Get rid of element "0" from this array.  A value was never assigned to it because the first row  // in the table just contained the column titles, which we did not bother to assign.  originalCol.shift();  // Sort the column array returning the value of a sort into a new array  sortCol = originalCol.sort(sortCompare);  // If it was supposed to be an Ascending sort then reverse the order  if (sortAscending) { sortCol.reverse(); }  // Now take the values from the sorted column array and use that information to re-arrange  // the order of the tr_elements in the table  for (var i=1; i < tr_elements.length - ignoreLastLines; i++) {    var old_row = sortCol[i-1][1];    var new_row = i;    tr_elements[i].parentNode.replaceChild(clonedRows[old_row],tr_elements[new_row]);  }   // Format the table, making the rows alternating colors and highlight the sorted column   makePretty(table_element,indexCol,ignoreLastLines);  // Assign correct sort image icon to current column title  sortColImage.setAttribute('src',newSortColImage);}// Function used by the sort routine to compare the current value in the array with the next onefunction sortCompare (currValue, nextValue) { // Since the elements of this array are actually arrays themselves, just sort // on the first element which contiains the value, not the second which contains // the original row position  if ( currValue[0] == nextValue[0] ) return 0;  if ( currValue[0] < nextValue[0] ) return -1;  if ( currValue[0] > nextValue[0] ) return 1;}//-----------------------------------------------------------------------------// Functions to get and compare values during a sort.//-----------------------------------------------------------------------------// This code is necessary for browsers that don't reflect the DOM constants// (like IE).if (document.ELEMENT_NODE == null) {   document.ELEMENT_NODE = 1;   document.TEXT_NODE = 3;}function getTextValue(el) {  var i;  var s;  // Find and concatenate the values of all text nodes contained within the  // element.  s = "";  for (i = 0; i < el.childNodes.length; i++)    if (el.childNodes[i].nodeType == document.TEXT_NODE)      s += el.childNodes[i].nodeValue;    else if (el.childNodes[i].nodeType == document.ELEMENT_NODE &&             el.childNodes[i].tagName == "BR")      s += " ";    else      // Use recursion to get text within sub-elements.      s += getTextValue(el.childNodes[i]);  return normalizeString(s);}// Regular expressions for normalizing white space.var whtSpEnds = new RegExp("^\s*|\s*$", "g");var whtSpMult = new RegExp("\s\s+", "g");function normalizeString(s) {  s = s.replace(whtSpMult, " ");  // Collapse any multiple whites space.  s = s.replace(whtSpEnds, "");   // Remove leading or trailing white space.  return s;}// Function used to modify values to make then sortable depending on the type of informationfunction FormatForType(itm) {  var sortValue = itm.toLowerCase();  // If the item matches a date pattern (MM/DD/YYYY or MM/DD/YY or M/DD/YYYY)  if (itm.match(/^dd[/-]dd[/-]dddd$/) ||      itm.match(/^dd[/-]dd[/-]dd$/) ||  itm.match(/^d[/-]dd[/-]dddd$/) ) {    // Convert date to YYYYMMDD format for sort comparison purposes    // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX    var yr = -1;    if (itm.length == 10) {      sortValue = itm.substr(6,4)+itm.substr(0,2)+itm.substr(3,2); } else if (itm.length == 9) {      sortValue = itm.substr(5,4)+"0" + itm.substr(0,1)+itm.substr(2,2); } else {      yr = itm.substr(6,2);      if (parseInt(yr) < 50) {        yr = '20'+yr;      } else {        yr = '19'+yr;      }        sortValue = yr+itm.substr(3,2)+itm.substr(0,2);    }  }  // If the item matches a Percent patten (contains a percent sign)  if (itm.match(/%/)) {   // Replace anything that is not part of a number (decimal pt, neg sign, or 0 through 9) with an empty string.   sortValue = itm.replace(/[^0-9.-]/g,'');   sortValue = parseFloat(sortValue);  }  // If item starts with a "(" and ends with a ")" then remove them and put a negative sign in front  if (itm.substr(0,1) == "(" & itm.substr(itm.length - 1,1) == ")") {   itm = "-" + itm.substr(1,itm.length - 2);  }// If the item matches a currency pattern (starts with a dollar or negative dollar sign)  if (itm.match(/^[£$]|(^-)/)) {   // Replace anything that is not part of a number (decimal pt, neg sign, or 0 through 9) with an empty string.   sortValue = itm.replace(/[^0-9.-]/g,'');   if (isNaN(sortValue)) {     sortValue = 0;   } else {     sortValue = parseFloat(sortValue);   }}  // If the item matches a numeric pattern  if (itm.match(/(d*,d*$)|(^-?dd*.d*$)|(^-?dd*$)|(^-?.dd*$)/)) {   // Replace anything that is not part of a number (decimal pt, neg sign, or 0 through 9) with an empty string.   sortValue = itm.replace(/[^0-9.-]/g,''); //  sortValue = sortValue.replace(/,/g,'');   if (isNaN(sortValue)) {     sortValue = 0;   } else {     sortValue = parseFloat(sortValue);   }  }  return sortValue;}//-----------------------------------------------------------------------------// Functions to update the table appearance after a sort.//-----------------------------------------------------------------------------// Style class names.var rowClsNm = "alternateRow";var colClsNm = "sortedColumn";// Regular expressions for setting class names.var rowTest = new RegExp(rowClsNm, "gi");var colTest = new RegExp(colClsNm, "gi");function makePretty(tblEl, col, ignoreLastLines) {  var i, j;  var rowEl, cellEl;  // Set style classes on each row to alternate their appearance.  for (i = 1; i < tblEl.rows.length - ignoreLastLines; i++) {   rowEl = tblEl.rows[i];   rowEl.className = rowEl.className.replace(rowTest, "");    if (i % 2 != 0)      rowEl.className += " " + rowClsNm;    rowEl.className = normalizeString(rowEl.className);    // Set style classes on each column (other than the name column) to    // highlight the one that was sorted.    for (j = 0; j < tblEl.rows[i].cells.length; j++) {      cellEl = rowEl.cells[j];      cellEl.className = cellEl.className.replace(colTest, "");      if (j == col)        cellEl.className += " " + colClsNm;      cellEl.className = normalizeString(cellEl.className);    }  }}// END Generic Table sort.// =================================================// Function to scroll to top before sorting to fix an IE bug// Which repositions the header off the top of the screen// if you try to sort while scrolled to bottom.function GoTop() { document.getElementById('TableContainer').scrollTop = 0;}</script>


HTML
<table cellpadding="0" cellspacing="0" border="0"><tr><td><div id="TableContainer" class="TableContainer" style="height:230px;"><table class="scrollTable"> <thead class="fixedHeader headerFormat">  <tr>   <td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort"><b>NAME</b> <img src="none.gif" border="0"></td>   <td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort" align="right"><b>Amt</b> <img src="none.gif" border="0"></td>   <td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort" align="right"><b>Lvl</b> <img src="none.gif" border="0"></td>   <td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort" align="right"><b>Rank</b> <img src="none.gif" border="0"></td>   <td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort" align="right"><b>Position</b> <img src="none.gif" border="0"></td>   <td class="point" onclick="GoTop(); sortTable(this,1);" title="Sort" align="right"><b>Date</b> <img src="none.gif" border="0"></td>  </tr> </thead> <tbody class="scrollContent bodyFormat" style="height:200px;">   <tr class="alternateRow">    <td>Maha</td>    <td align="right">$19,923.19</td>    <td align="right">100</td>    <td align="right">100</td>    <td>Owner</td>    <td align="right">01/02/2001</td>   </tr>   <tr>    <td>Thrawl</td>    <td align="right">$9,550</td>    <td align="right">159</td>    <td align="right">100%</td>    <td>Co-Owner</td>    <td align="right">11/07/2003</td>   </tr>   <tr class="alternateRow">    <td>Marhanen</td>    <td align="right">$223.04</td>    <td align="right">83</td>    <td align="right">99%</td>    <td>Banker</td>    <td align="right">06/27/2006</td>   </tr>   <tr>    <td>Peter</td>    <td align="right">$121</td>    <td align="right">567</td>    <td align="right">23423%</td>    <td>FishHead</td>    <td align="right">06/06/2006</td>   </tr>   <tr class="alternateRow">    <td>Jones</td>    <td align="right">$15</td>    <td align="right">11</td>    <td align="right">15%</td>    <td>Bubba</td>    <td align="right">10/27/2005</td>   </tr>   <tr>    <td>Supa-De-Dupa</td>    <td align="right">$145</td>    <td align="right">91</td>    <td align="right">32%</td>    <td>momma</td>    <td align="right">12/15/1996</td>   </tr>   <tr class="alternateRow">    <td>ClickClock</td>    <td align="right">$1,213</td>    <td align="right">23</td>    <td align="right">1%</td>    <td>Dada</td>    <td align="right">1/30/1998</td>   </tr>   <tr>    <td>Mrs. Robinson</td>    <td align="right">$99</td>    <td align="right">99</td>    <td align="right">99%</td>    <td>Wife</td>    <td align="right">07/04/1963</td>   </tr>   <tr class="alternateRow">    <td>Maha</td>    <td align="right">$19,923.19</td>    <td align="right">100</td>    <td align="right">100%</td>    <td>Owner</td>    <td align="right">01/02/2001</td>   </tr>   <tr>    <td>Thrawl</td>    <td align="right">$9,550</td>    <td align="right">159</td>    <td align="right">100%</td>    <td>Co-Owner</td>    <td align="right">11/07/2003</td>   </tr>   <tr class="alternateRow">    <td>Marhanen</td>    <td align="right">$223.04</td>    <td align="right">83</td>    <td align="right">59%</td>    <td>Banker</td>    <td align="right">06/27/2006</td>   </tr>   <tr>    <td>Peter</td>    <td align="right">$121</td>    <td align="right">567</td>    <td align="right">534.23%</td>    <td>FishHead</td>    <td align="right">06/06/2006</td>   </tr>   <tr class="alternateRow">    <td>Jones</td>    <td align="right">$15</td>    <td align="right">11</td>    <td align="right">15%</td>    <td>Bubba</td>    <td align="right">10/27/2005</td>   </tr>   <tr>    <td>Supa-De-Dupa</td>    <td align="right">$145</td>    <td align="right">91</td>    <td align="right">42%</td>    <td>momma</td>    <td align="right">12/15/1996</td>   </tr>   <tr class="alternateRow">    <td>ClickClock</td>    <td align="right">$1,213</td>    <td align="right">23</td>    <td align="right">2%</td>    <td>Dada</td>    <td align="right">1/30/1998</td>   </tr>   <tr>    <td>Mrs. Robinson</td>    <td align="right">$99</td>    <td align="right">99</td>    <td align="right">(-10.42%)</td>    <td>Wife</td>    <td align="right">07/04/1963</td>   </tr>   <tr class="alternateRow">    <td>Maha</td>    <td align="right">-$19,923.19</td>    <td align="right">100</td>    <td align="right">(-10.01%)</td>    <td>Owner</td>    <td align="right">01/02/2001</td>   </tr>   <tr>    <td>Thrawl</td>    <td align="right">$9,550</td>    <td align="right">159</td>    <td align="right">-10.20%</td>    <td>Co-Owner</td>    <td align="right">11/07/2003</td>   </tr>   <tr class="total">    <td><strong>TOTAL</strong>:</td>    <td align="right"><strong>999999</strong></td>    <td align="right"><strong>9999999</strong></td>    <td align="right"><strong>99</strong></td>    <td > </td>    <td align="right"> </td>   </tr> </tbody></table></div></td></tr></table>


Files
/javascript/form/Sort_and_Lock_Table/asc.gif/javascript/form/Sort_and_Lock_Table/desc.gif/javascript/form/Sort_and_Lock_Table/none.gif