Full version: jsB@nk » Form » Sortable and Lockable Sheet
URL: https://www.javascriptbank.com/sortable-and-lockable-sheet.html
One 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
<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]-->
<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>
<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>
/javascript/form/Sort_and_Lock_Table/asc.gif/javascript/form/Sort_and_Lock_Table/desc.gif/javascript/form/Sort_and_Lock_Table/none.gif