Solved

Stardardista Table Sorting - need Counter column to remain static

Posted on 2016-07-23
4
29 Views
Last Modified: 2016-08-27
I have a report generated from a MSAccess DB. I am using the Standardista Table Sorting script.
The first column is a COUNTER for numbering the rows. I need this column to remain static when the other
columns are sorted. There are 3 other columns sorting correctly.

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 12.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title><%=title%></title>
  
	<link rel=stylesheet type="text/css"
	href="/CodeReuse/style.css">

	<!-- The following code allows for a client side sort option -->
	<script type="text/javascript" src="/CodeReuse/common.js"></script>
	<script type='text/javascript' src=/CodeReuse/css.js'></script>
	<script type='text/javascript' src=/CodeReuse/standardista-table-sorting.js'></script>


</head>

<body>


<%
'Create recordset
 Dim sql, objRS, counter
 counter = 0

sql = "SELECT gen.City, gen.State, jls.Title, jls.cost " & _
 "from ( " & _
  	"select ChartID, J1Title as Title, J1Cost as cost from tblJournals union all " & _
 	"select ChartID, J2Title as Title, J2Cost as cost from tblJournals union all " & _
 	"select ChartID, J3Title as Title, J3Cost as cost from tblJournals union all " & _
 	"select ChartID, J4Title as Title, J4Cost as cost from tblJournals union all " & _
 	"select ChartID, J5Title as Title, J5Cost as cost from tblJournals union all " & _
 	"select ChartID, J6Title as Title, J6Cost as cost from tblJournals union all " & _
 	"select ChartID, J7Title as Title, J7Cost as cost from tblJournals union all " & _
 	"select ChartID, J8Title as Title, J8Cost as cost from tblJournals union all " & _
 	"select ChartID, J9Title as Title, J9Cost as cost from tblJournals union all " & _
 	"select ChartID, J10Title as Title, J10Cost as cost from tblJournals union all " & _
 	"select ChartID, J11Title as Title, J11Cost as cost from tblJournals union all " & _
 	"select ChartID, J12Title as Title, J12Cost as cost from tblJournals union all " & _
 	"select ChartID, J13Title as Title, J13Cost as cost from tblJournals union all " & _
 	"select ChartID, J14Title as Title, J14Cost as cost from tblJournals union all " & _
 	"select ChartID, J15Title as Title, J15Cost as cost from tblJournals union all " & _
 	"select ChartID, J16Title as Title, J16Cost as cost from tblJournals union all " & _
 	"select ChartID, J17Title as Title, J17Cost as cost from tblJournals union all " & _
 	"select ChartID, J18Title as Title, J18Cost as cost from tblJournals union all " & _
 	"select ChartID, J19Title as Title, J19Cost as cost from tblJournals union all " & _
 	"select ChartID, J20Title as Title, J20Cost as cost from tblJournals union all " & _
 	"select ChartID, J21Title as Title, J21Cost as cost from tblJournals union all " & _
 	"select ChartID, J22Title as Title, J22Cost as cost from tblJournals union all " & _
 	"select ChartID, J23Title as Title, J23Cost as cost from tblJournals union all " & _
 	"select ChartID, J24Title as Title, J24Cost as cost from tblJournals union all " & _
 	"select ChartID, J25Title as Title, J25Cost as cost from tblJournals " & _
 	
 	") jls " & _
	"INNER JOIN tblGeneral as gen " & _
	"on gen.ChartID=jls.ChartID " & _
	"WHERE LEN(Title) > 3 "

 		If Request.querystring("sort") = "" then
 			sql = sql & "ORDER BY Title,City"
 		Else
  			sql = sql & "ORDER BY " & Request.querystring("sort")
  		End If			
	
	Set objRS = Server.CreateObject("ADODB.Recordset")
	objRS.Open sql, objConn
%>


<h2><%=PageTitle%></h2>

<table class='sortable' cellspacing='0' width='650px' border='1' cellpadding='1' background 'CAE4FF'>

<thead>
	<tr>
		<th scope='col' width='50px'>&nbsp;&nbsp;</th>
		<th class='sortable' scope='col' width='250px'>Title</th>
		<th class='sortable' scope='col' width='100px'>Cost</th>
		<th class='sortable' scope='col' width='250px'>Location</th>
	</tr>
</thead>

<tbody>


<%

While Not objRS.EOF
counter = counter + 1
%>
	
	<tr>
		<td scope='row' width='50px'><%Response.Write Counter%></td>
		<td class='sortable' scope='row' width='250px'>&nbsp;<%Response.Write objRS("Title")%></TD>
		<td class='sortable' scope='row' width='100px' align='right'>$
			<%Response.Write objRS("Cost")%>&nbsp;&nbsp;&nbsp;</TD>		
		<td class='sortable' scope='row' width='250px' align='left'>&nbsp;&nbsp;
			<%Response.Write objRS("City") & ",&nbsp;" & objRS("State")%>&nbsp;&nbsp;&nbsp;</TD>		
		
		
<%
objRS.MoveNext
Wend

objRS.Close
Set objRS = Nothing

Response.Write "</TABLE></div>" & vbCrLf


%>

Open in new window

0
Comment
Question by:Malloy1446
  • 3
4 Comments
 
LVL 52

Accepted Solution

by:
Scott Fell,  EE MVE earned 500 total points
ID: 41726103
The reason it is it should and not as expected is because your asp code runs first, on the server. Then iis throws that generated code to the browser after which your javascript code runs.  

That  means whatever you have as row 2 to start with, will always be row 2 no matter how javascript sorts because the js is running after that data is sent to the screen.

To get what you want, you need to use javascript.  You can do this in pure js, but here it is using jquery as a simple example that uses one column.   This sample only demonstrates how jquery can add the row numbers for you.  You should find that your other script, once it sorts, should keep the numbering as expected.

http://jsbin.com/jucuqovuwu/edit?html,output
<!DOCTYPE html>
<html>

<head>
    <script src="https://code.jquery.com/jquery-2.0.3.js"></script>
    <script>
        $(function() {
            $('td.rowcounter').each(function(tCounter) {
                $(this).html(tCounter + 1);
            });
        });
    </script>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
</head>

<body>
    <table id="sorttable">

        <thead>
            <tr>
                <th>test</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td class="rowcounter" scope='row' width='50px'></td>
            </tr>
            <tr>
                <td class="rowcounter" scope='row' width='50px'></td>
            </tr>
            <tr>
                <td class="rowcounter" scope='row' width='50px'></td>
            </tr>


            </tr>
        </tbody>
    </table>
</body>

Open in new window


You will see this experiment adds our row numbers using javascript.

The problem still exists if we add this as is to your other script running, it will still have the same problem because your sort script thinks that column is hard coded.  So first, lets switch up how we access the jquery above by using a separate function.
 $(function() {
    rowCounter();
           
   });
function rowCounter(){
      $('td.rowcounter').each(function(tCounter) {
          $(this).html(tCounter + 1);
       });
      
}

Open in new window

The code abobe creates a function called rowCounter that will add our rows when called.  By placing the first call inside the function like below will just run it when the page loads.
$(function() {
    rowCounter();
           
   });

Open in new window

The next part is to run this function each time the table is re-sorted.  You will need to modify your script called       standardista-table-sorting.js.  

In that script, look for headingClicked: function(e) { and at the bottom of that function, you will see
td.appendChild(spanEl);

				return false;

Open in new window

Between those two lines of code, add our call to the counter function like this
td.appendChild(spanEl);
            rowCounter();
		return false;

Open in new window


I have a full working sample from their example http://jsbin.com/mesakexuyo/edit?html,output
0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
ID: 41726107
Just a note, for above, if you are not already using jquery, you will need to add it.  Add this to your head section
<script src="https://code.jquery.com/jquery-2.0.3.js"></script>

Open in new window

If you are still targeting older IE browsers you can use v 1.9
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>

Open in new window


There are newer version of jquery you can use as well https://jquery.com/download/


Also, a more modern javascript table with sorting https://datatables.net/
0
 
LVL 52

Assisted Solution

by:Scott Fell, EE MVE
Scott Fell,  EE MVE earned 500 total points
ID: 41726108
Full script that does not use external js other than jquery.  You are better off using the external js for the sorting like
	<link rel="stylesheet" href="style.css" type="text/css" />

		<script type='text/javascript' src='common.js'></script>
		<script type='text/javascript' src='css.js'></script>
		<script type='text/javascript' src='standardista-table-sorting.js'></script>

Open in new window



To make it easy to recreate, I am not using external js or css files below
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.0.3.js"></script>
<script>
/**
* COMMON JS
 * addEvent written by Dean Edwards, 2005
 * with input from Tino Zijdel
 *
 * http://dean.edwards.name/weblog/2005/10/add-event/
 **/
function addEvent(element, type, handler) {
	// assign each event handler a unique ID
	if (!handler.$$guid) handler.$$guid = addEvent.guid++;
	// create a hash table of event types for the element
	if (!element.events) element.events = {};
	// create a hash table of event handlers for each element/event pair
	var handlers = element.events[type];
	if (!handlers) {
		handlers = element.events[type] = {};
		// store the existing event handler (if there is one)
		if (element["on" + type]) {
			handlers[0] = element["on" + type];
		}
	}
	// store the event handler in the hash table
	handlers[handler.$$guid] = handler;
	// assign a global event handler to do all the work
	element["on" + type] = handleEvent;
};
// a counter used to create unique IDs
addEvent.guid = 1;

function removeEvent(element, type, handler) {
	// delete the event handler from the hash table
	if (element.events && element.events[type]) {
		delete element.events[type][handler.$$guid];
	}
};

function handleEvent(event) {
	var returnValue = true;
	// grab the event object (IE uses a global event object)
	event = event || fixEvent(window.event);
	// get a reference to the hash table of event handlers
	var handlers = this.events[event.type];
	// execute each event handler
	for (var i in handlers) {
		this.$$handleEvent = handlers[i];
		if (this.$$handleEvent(event) === false) {
			returnValue = false;
		}
	}
	return returnValue;
};

function fixEvent(event) {
	// add W3C standard event methods
	event.preventDefault = fixEvent.preventDefault;
	event.stopPropagation = fixEvent.stopPropagation;
	return event;
};
fixEvent.preventDefault = function() {
	this.returnValue = false;
};
fixEvent.stopPropagation = function() {
	this.cancelBubble = true;
};

// end from Dean Edwards


/**
 * Creates an Element for insertion into the DOM tree.
 * From http://simon.incutio.com/archive/2003/06/15/javascriptWithXML
 *
 * @param element the element type to be created.
 *				e.g. ul (no angle brackets)
 **/
function createElement(element) {
	if (typeof document.createElementNS != 'undefined') {
		return document.createElementNS('http://www.w3.org/1999/xhtml', element);
	}
	if (typeof document.createElement != 'undefined') {
		return document.createElement(element);
	}
	return false;
}

/**
 * "targ" is the element which caused this function to be called
 * from http://www.quirksmode.org/js/events_properties.html
 **/
function getEventTarget(e) {
	var targ;
	if (!e) {
		e = window.event;
	}
	if (e.target) {
		targ = e.target;
	} else if (e.srcElement) {
		targ = e.srcElement;
	}
	if (targ.nodeType == 3) { // defeat Safari bug
		targ = targ.parentNode;
	}

	return targ;
}

/**
* CSS  JS
 * Written by Neil Crosby. 
 * http://www.workingwith.me.uk/
 *
 * Use this wherever you want, but please keep this comment at the top of this file.
 *
 * Copyright (c) 2006 Neil Crosby
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy 
 * of this software and associated documentation files (the "Software"), to deal 
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 * copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 * SOFTWARE.
 **/
var css = {
	/**
	 * Returns an array containing references to all elements
	 * of a given tag type within a certain node which have a given class
	 *
	 * @param node		the node to start from 
	 *					(e.g. document, 
	 *						  getElementById('whateverStartpointYouWant')
	 *					)
	 * @param searchClass the class we're wanting
	 *					(e.g. 'some_class')
	 * @param tag		 the tag that the found elements are allowed to be
	 *					(e.g. '*', 'div', 'li')
	 **/
	getElementsByClass : function(node, searchClass, tag) {
		var classElements = new Array();
		var els = node.getElementsByTagName(tag);
		var elsLen = els.length;
		var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
		
		
		for (var i = 0, j = 0; i < elsLen; i++) {
			if (this.elementHasClass(els[i], searchClass) ) {
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	},


	/**
	 * PRIVATE.  Returns an array containing all the classes applied to this
	 * element.
	 *
	 * Used internally by elementHasClass(), addClassToElement() and 
	 * removeClassFromElement().
	 **/
	privateGetClassArray: function(el) {
		return el.className.split(' '); 
	},

	/**
	 * PRIVATE.  Creates a string from an array of class names which can be used 
	 * by the className function.
	 *
	 * Used internally by addClassToElement().
	 **/
	privateCreateClassString: function(classArray) {
		return classArray.join(' ');
	},

	/**
	 * Returns true if the given element has been assigned the given class.
	 **/
	elementHasClass: function(el, classString) {
		if (!el) {
			return false;
		}
		
		var regex = new RegExp('\\b'+classString+'\\b');
		if (el.className.match(regex)) {
			return true;
		}

		return false;
	},

	/**
	 * Adds classString to the classes assigned to the element with id equal to
	 * idString.
	 **/
	addClassToId: function(idString, classString) {
		this.addClassToElement(document.getElementById(idString), classString);
	},

	/**
	 * Adds classString to the classes assigned to the given element.
	 * If the element already has the class which was to be added, then
	 * it is not added again.
	 **/
	addClassToElement: function(el, classString) {
		var classArray = this.privateGetClassArray(el);

		if (this.elementHasClass(el, classString)) {
			return; // already has element so don't need to add it
		}

		classArray.push(classString);

		el.className = this.privateCreateClassString(classArray);
	},

	/**
	 * Removes the given classString from the list of classes assigned to the
	 * element with id equal to idString
	 **/
	removeClassFromId: function(idString, classString) {
		this.removeClassFromElement(document.getElementById(idString), classString);
	},

	/**
	 * Removes the given classString from the list of classes assigned to the
	 * given element.  If the element has the same class assigned to it twice, 
	 * then only the first instance of that class is removed.
	 **/
	removeClassFromElement: function(el, classString) {
		var classArray = this.privateGetClassArray(el);

		for (x in classArray) {
			if (classString == classArray[x]) {
				classArray[x] = '';
				break;
			}
		}

		el.className = this.privateCreateClassString(classArray);
	}
}



/**

* standardista-table-sorting.js
 * Written by Neil Crosby. 
 * http://www.workingwith.me.uk/articles/scripting/standardista_table_sorting
 *
 * This module is based on Stuart Langridge's "sorttable" code.  Specifically, 
 * the determineSortFunction, sortCaseInsensitive, sortDate, sortNumeric, and
 * sortCurrency functions are heavily based on his code.  This module would not
 * have been possible without Stuart's earlier outstanding work.
 *
 * Use this wherever you want, but please keep this comment at the top of this file.
 *
 * Copyright (c) 2006 Neil Crosby
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy 
 * of this software and associated documentation files (the "Software"), to deal 
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 * copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 * SOFTWARE.
 **/
var standardistaTableSorting = {

	that: false,
	isOdd: false,

	sortColumnIndex : -1,
	lastAssignedId : 0,
	newRows: -1,
	lastSortedTable: -1,

	/**
	 * Initialises the Standardista Table Sorting module
	 **/
	init : function() {
		// first, check whether this web browser is capable of running this script
		if (!document.getElementsByTagName) {
			return;
		}
		
		this.that = this;
		
		this.run();
       
		
	},
	
	/**
	 * Runs over each table in the document, making it sortable if it has a class
	 * assigned named "sortable" and an id assigned.
	 **/
	run : function() {
		var tables = document.getElementsByTagName("table");
		
		for (var i=0; i < tables.length; i++) {
			var thisTable = tables[i];
			
			if (css.elementHasClass(thisTable, 'sortable')) {
				this.makeSortable(thisTable);
			}
		}
	},
	
	/**
	 * Makes the given table sortable.
	 **/
	makeSortable : function(table) {
	
		// first, check if the table has an id.  if it doesn't, give it one
		if (!table.id) {
			table.id = 'sortableTable'+this.lastAssignedId++;
		}
		
		// if this table does not have a thead, we don't want to know about it
		if (!table.tHead || !table.tHead.rows || 0 == table.tHead.rows.length) {
			return;
		}
		
		// we'll assume that the last row of headings in the thead is the row that 
		// wants to become clickable
		var row = table.tHead.rows[table.tHead.rows.length - 1];
		
		for (var i=0; i < row.cells.length; i++) {
		
			// create a link with an onClick event which will 
			// control the sorting of the table
			var linkEl = createElement('a');
			linkEl.href = '#';
			linkEl.onclick = this.headingClicked;
			linkEl.setAttribute('columnId', i);
			linkEl.title = 'Click to sort';
			
			// move the current contents of the cell that we're 
			// hyperlinking into the hyperlink
			var innerEls = row.cells[i].childNodes;
			for (var j = 0; j < innerEls.length; j++) {
				linkEl.appendChild(innerEls[j]);
			}
			
			// and finally add the new link back into the cell
			row.cells[i].appendChild(linkEl);

			var spanEl = createElement('span');
			spanEl.className = 'tableSortArrow';
			spanEl.appendChild(document.createTextNode('\u00A0\u00A0'));
			row.cells[i].appendChild(spanEl);

		}
	
		if (css.elementHasClass(table, 'autostripe')) {
			this.isOdd = false;
			var rows = table.tBodies[0].rows;
		
			// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
			for (var i=0;i<rows.length;i++) { 
				this.doStripe(rows[i]);
			}
		}
	},
	
	headingClicked: function(e) {
		
		var that = standardistaTableSorting.that;
		
		// linkEl is the hyperlink that was clicked on which caused
		// this method to be called
		var linkEl = getEventTarget(e);
		
		// directly outside it is a td, tr, thead and table
		var td     = linkEl.parentNode;
		var tr     = td.parentNode;
		var thead  = tr.parentNode;
		var table  = thead.parentNode;
		
		// if the table we're looking at doesn't have any rows
		// (or only has one) then there's no point trying to sort it
		if (!table.tBodies || table.tBodies[0].rows.length <= 1) {
			return false;
		}

		// the column we want is indicated by td.cellIndex
		var column = linkEl.getAttribute('columnId') || td.cellIndex;
		//var column = td.cellIndex;
		
		// find out what the current sort order of this column is
		var arrows = css.getElementsByClass(td, 'tableSortArrow', 'span');
		var previousSortOrder = '';
		if (arrows.length > 0) {
			previousSortOrder = arrows[0].getAttribute('sortOrder');
		}
		
		// work out how we want to sort this column using the data in the first cell
		// but just getting the first cell is no good if it contains no data
		// so if the first cell just contains white space then we need to track
		// down until we find a cell which does contain some actual data
		var itm = ''
		var rowNum = 0;
		while ('' == itm && rowNum < table.tBodies[0].rows.length) {
			itm = that.getInnerText(table.tBodies[0].rows[rowNum].cells[column]);
			rowNum++;
		}
		var sortfn = that.determineSortFunction(itm);

		// if the last column that was sorted was this one, then all we need to 
		// do is reverse the sorting on this column
		if (table.id == that.lastSortedTable && column == that.sortColumnIndex) {
			newRows = that.newRows;
			newRows.reverse();
		// otherwise, we have to do the full sort
		} else {
			that.sortColumnIndex = column;
			var newRows = new Array();

			for (var j = 0; j < table.tBodies[0].rows.length; j++) { 
				newRows[j] = table.tBodies[0].rows[j]; 
			}

			newRows.sort(sortfn);
		}

		that.moveRows(table, newRows);
		that.newRows = newRows;
		that.lastSortedTable = table.id;
		
		// now, give the user some feedback about which way the column is sorted
		
		// first, get rid of any arrows in any heading cells
		var arrows = css.getElementsByClass(tr, 'tableSortArrow', 'span');
		for (var j = 0; j < arrows.length; j++) {
			var arrowParent = arrows[j].parentNode;
			arrowParent.removeChild(arrows[j]);

			if (arrowParent != td) {
				spanEl = createElement('span');
				spanEl.className = 'tableSortArrow';
				spanEl.appendChild(document.createTextNode('\u00A0\u00A0'));
				arrowParent.appendChild(spanEl);
			}
		}
		
		// now, add back in some feedback 
		var spanEl = createElement('span');
		spanEl.className = 'tableSortArrow';
		if (null == previousSortOrder || '' == previousSortOrder || 'DESC' == previousSortOrder) {
			spanEl.appendChild(document.createTextNode(' \u2191'));
			spanEl.setAttribute('sortOrder', 'ASC');
		} else {
			spanEl.appendChild(document.createTextNode(' \u2193'));
			spanEl.setAttribute('sortOrder', 'DESC');
		}
		
		td.appendChild(spanEl);
       rowCounter();
		
		return false;
	},

	getInnerText : function(el) {
		
		if ('string' == typeof el || 'undefined' == typeof el) {
			return el;
		}
		
		if (el.innerText) {
			return el.innerText;  // Not needed but it is faster
		}

		var str = el.getAttribute('standardistaTableSortingInnerText');
		if (null != str && '' != str) {
			return str;
		}
		str = '';

		var cs = el.childNodes;
		var l = cs.length;
		for (var i = 0; i < l; i++) {
			// 'if' is considerably quicker than a 'switch' statement, 
			// in Internet Explorer which translates up to a good time 
			// reduction since this is a very often called recursive function
			if (1 == cs[i].nodeType) { // ELEMENT NODE
				str += this.getInnerText(cs[i]);
				break;
			} else if (3 == cs[i].nodeType) { //TEXT_NODE
				str += cs[i].nodeValue;
				break;
			}
		}
		
		// set the innertext for this element directly on the element
		// so that it can be retrieved early next time the innertext
		// is requested
		el.setAttribute('standardistaTableSortingInnerText', str);
		
		return str;
	},

	determineSortFunction : function(itm) {
		
		var sortfn = this.sortCaseInsensitive;
		
		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) {
			sortfn = this.sortDate;
		}
		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) {
			sortfn = this.sortDate;
		}
		if (itm.match(/^[£$]/)) {
			sortfn = this.sortCurrency;
		}
		if (itm.match(/^\d?\.?\d+$/)) {
			sortfn = this.sortNumeric;
		}
		if (itm.match(/^[+-]?\d*\.?\d+([eE]-?\d+)?$/)) {
			sortfn = this.sortNumeric;
		}
    		if (itm.match(/^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$/)) {
        		sortfn = this.sortIP;
   		}

		return sortfn;
	},
	
	sortCaseInsensitive : function(a, b) {
		var that = standardistaTableSorting.that;
		
		var aa = that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase();
		var bb = that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase();
		if (aa==bb) {
			return 0;
		} else if (aa<bb) {
			return -1;
		} else {
			return 1;
		}
	},
	
	sortDate : function(a,b) {
		var that = standardistaTableSorting.that;

		// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
		var aa = that.getInnerText(a.cells[that.sortColumnIndex]);
		var bb = that.getInnerText(b.cells[that.sortColumnIndex]);
		
		var dt1, dt2, yr = -1;
		
		if (aa.length == 10) {
			dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
		} else {
			yr = aa.substr(6,2);
			if (parseInt(yr) < 50) { 
				yr = '20'+yr; 
			} else { 
				yr = '19'+yr; 
			}
			dt1 = yr+aa.substr(3,2)+aa.substr(0,2);
		}
		
		if (bb.length == 10) {
			dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
		} else {
			yr = bb.substr(6,2);
			if (parseInt(yr) < 50) { 
				yr = '20'+yr; 
			} else { 
				yr = '19'+yr; 
			}
			dt2 = yr+bb.substr(3,2)+bb.substr(0,2);
		}
		
		if (dt1==dt2) {
			return 0;
		} else if (dt1<dt2) {
			return -1;
		}
		return 1;
	},

	sortCurrency : function(a,b) { 
		var that = standardistaTableSorting.that;

		var aa = that.getInnerText(a.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');
		var bb = that.getInnerText(b.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');
		return parseFloat(aa) - parseFloat(bb);
	},

	sortNumeric : function(a,b) { 
		var that = standardistaTableSorting.that;

		var aa = parseFloat(that.getInnerText(a.cells[that.sortColumnIndex]));
		if (isNaN(aa)) { 
			aa = 0;
		}
		var bb = parseFloat(that.getInnerText(b.cells[that.sortColumnIndex])); 
		if (isNaN(bb)) { 
			bb = 0;
		}
		return aa-bb;
	},

	makeStandardIPAddress : function(val) {
		var vals = val.split('.');

		for (x in vals) {
			val = vals[x];

			while (3 > val.length) {
				val = '0'+val;
			}
			vals[x] = val;
		}

		val = vals.join('.');

		return val;
	},

	sortIP : function(a,b) { 
		var that = standardistaTableSorting.that;

		var aa = that.makeStandardIPAddress(that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase());
		var bb = that.makeStandardIPAddress(that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase());
		if (aa==bb) {
			return 0;
		} else if (aa<bb) {
			return -1;
		} else {
			return 1;
		}
	},

	moveRows : function(table, newRows) {
		this.isOdd = false;

		// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
		for (var i=0;i<newRows.length;i++) { 
			var rowItem = newRows[i];

			this.doStripe(rowItem);

			table.tBodies[0].appendChild(rowItem); 
		}
	},
	
	doStripe : function(rowItem) {
		if (this.isOdd) {
			css.addClassToElement(rowItem, 'odd');
		} else {
			css.removeClassFromElement(rowItem, 'odd');
		}
		
		this.isOdd = !this.isOdd;
	}

};

function standardistaTableSortingInit() {
	standardistaTableSorting.init();
  
}

addEvent(window, 'load', standardistaTableSortingInit);




 $(function() {
    rowCounter();
           
   });
function rowCounter(){
      $('td.rowcounter').each(function(tCounter) {
          $(this).html(tCounter + 1);
       });
      
}
</script>

<style>
table {
	width: 80%;
	margin: 1em auto;
	border-collapse: collapse;
}

thead th,
tfoot th {
	padding: 0.5em;
	text-align: left;
	border: 1px solid black;
	background-color: #AAF;
}

tfoot td {
	border-top: 1px solid black;
}

tbody td {
	padding: 0.5em;
	border-left: 1px solid black;
	border-right: 1px solid black;
}

tbody tr.odd {
	background-color: #DDF;
}

td.numeric,
th.numeric {
	text-align: right;
}
</style>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
		<table class='sortable'>
			<thead>
				<tr>
					<td></td>
                   <td></td>
					<th colspan='2'>Name</th>
					<td></td>
					<td></td>
					<td></td>
				</tr>
				<tr>
                    <th>Row</th>
					<th>Date</th>
					<th>Forename</th>
					<th>Surname</th>
					<th>Number</th>
					<th>Price</th>
					<th>IP Address</th>
					<th>Scientific</th>
				</tr>
			</thead>
			<tfoot>
				<tr>
					<td></td>
					<td></td>
					<td></td>
					<th class='numeric'>385</th>
					<th class='numeric'>$160.91</th>
					<td></td>
					<td></td>
				</tr>
			</tfoot>
			<tbody>
				<tr>
                  <td class="rowcounter" scope='row'></td>
					<td>21/01/2006</td>
					<td>Neil</td>
					<td>Crosby</td>
					<td class='numeric'>123</td>
					<td class='numeric'>$1.96</td>
					<td>192.168.1.1</td>
					<td>-12E2</td>
				</tr>
				<tr class='odd'>
                  <td class="rowcounter" scope='row'></td>
					<td>01/02/2006</td>
					<td>Becca</td>
					<td>Courtley</td>
					<td class='numeric'>122</td>
					<td class='numeric'>$23.95</td>
					<td>192.167.2.1</td>
					<td>12E2</td>
				</tr>
				<tr>
                  <td class="rowcounter" scope='row'></td>
					<td>17/11/2004</td>
					<td>David</td>
					<td>Freidman</td>
					<td class='numeric'>048</td>
					<td class='numeric'>$14.00</td>
					<td>192.168.2.1</td>
					<td>13e-2</td>
				</tr>
				<tr class='odd'>
                  <td class="rowcounter" scope='row'></td>
					<td>17/10/2004</td>
					<td>Sylvia</td>
					<td>Tyler</td>
					<td class='numeric'>43</td>
					<td class='numeric'>$104.00</td>
					<td>192.168.2.17</td>
					<td>12.1e2</td>
				</tr>
				<tr>
                  <td class="rowcounter" scope='row'></td>
					<td>17/11/2005</td>
					<td>Carl</td>
					<td>Conway</td>
					<td class='numeric'>49</td>
					<td class='numeric'>$17.00</td>
					<td>192.168.02.13</td>
					<td>12e3</td>
				</tr>
			</tbody>
		</table>
</body>
</html>

Open in new window

0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Ever needed a SQL 2008 Database replicated/mirrored/log shipped on another server but you can't take the downtime inflicted by initial snapshot or disconnect while T-logs are restored or mirror applied? You can use SQL Server Initialize from Backup…
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
This videos aims to give the viewer a basic demonstration of how a user can query current session information by using the SYS_CONTEXT function
Using examples as well as descriptions, and references to Books Online, show the documentation available for datatypes, explain the available data types and show how data can be passed into and out of variables.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now