Сортировка таблицы без перезагрузки

Когда перед разработчиком возникает задача сортировки строк в таблице с данными, то как правило, используется сортировка на стороне сервера и выдается готовая таблица пользователю. Здесь вам предлагается универсальная система сортировки строк таблицы, работающая в W3C DOM-совместимых браузерах.

Я взял модифицированную версию с htmlcoder.visions.ru и заменил использование картинок со стрелками на символы стрелки: ↓(↓), ↑(↑).

Вот, что мы получаем в итоге (нажмите на заголовок, чтобы отсортировать по текущей колонке):

ID Имя Фамилия Сайт Переключалка стилей
1 Александр Шуркаев htmlcoder.visions.ru Не-а
123 Пол Соуден idontsmoke.co.uk Угу
3 Джеффри Зельдман zeldman.com Угу
44 Аарон Будман youngpup.net Не-а
11 Глен Мерфи glenmurphy.com Не-а
15 Даниель Боган waferbaby.com Не-а
33 Ден Бенджамин hivelogic.com Угу
Исходный код этого примера:
<style>
/* наша HTML таблица */
table.sort{
	border-spacing:0.1em;
	margin-bottom:1em;
	margin-top:1em
}
/* ячейки таблицы */
table.sort td{
	border:1px solid #CCCCCC;
	padding:0.3em 1em
}
/* заголовки таблицы */
table.sort thead td{
	cursor:pointer;
	font-weight:bold;
	text-align:center;
	vertical-align:middle
}
/* заголовок отсортированного столбца */
table.sort thead td.curcol{
	background-color:#999999;
	color:#FFFFFF
}
</style>

<script>
/*
originally written by paul sowden <paul@idontsmoke.co.uk> | http://idontsmoke.co.uk
modified and localized by alexander shurkayev <alshur@narod.ru> | http://htmlcoder.visions.ru
last modification 06.12.2009 by KDG http://htmlweb.ru/
*/

initial_sort_id = 0; // номер начального отсортированного столбца, начиная с нуля
initial_sort_up = 1; // 0 - сортировка вниз, 1 - вверх
var sort_case_sensitive = false; // чуствительновть к регистру при сотрировке
function _sort(a, b) {
	var a = a[0];
	var b = b[0];
	var _a = (a + '').replace(/,/, '.');
	var _b = (b + '').replace(/,/, '.');
	if (parseInt(_a) && parseInt(_b)) return sort_numbers(parseInt(_a), parseInt(_b));
	else if (!sort_case_sensitive) return sort_insensitive(a, b);
	else return sort_sensitive(a, b);
}
function sort_numbers(a, b) {
	return a - b;
}
function sort_insensitive(a, b) {
	var anew = a.toLowerCase();
	var bnew = b.toLowerCase();
	if (anew < bnew) return -1;
	if (anew > bnew) return 1;
	return 0;
}
function sort_sensitive(a, b) {
	if (a < b) return -1;
	if (a > b) return 1;
	return 0;
}
function getConcatenedTextContent(node) {
	var _result = "";
	if (node == null) {
		return _result;
	}
	var childrens = node.childNodes;
	var i = 0;
	while (i < childrens.length) {
		var child = childrens.item(i);
		switch (child.nodeType) {
			case 1: // ELEMENT_NODE
			case 5: // ENTITY_REFERENCE_NODE
				_result += getConcatenedTextContent(child);
				break;
			case 3: // TEXT_NODE
			case 2: // ATTRIBUTE_NODE
			case 4: // CDATA_SECTION_NODE
				_result += child.nodeValue;
				break;
			case 6: // ENTITY_NODE
			case 7: // PROCESSING_INSTRUCTION_NODE
			case 8: // COMMENT_NODE
			case 9: // DOCUMENT_NODE
			case 10: // DOCUMENT_TYPE_NODE
			case 11: // DOCUMENT_FRAGMENT_NODE
			case 12: // NOTATION_NODE
			// skip
			break;
		}
		i++;
	}
	return _result;
}
function sort(e) {
	var el = window.event ? window.event.srcElement : e.currentTarget;

	while (el.tagName.toLowerCase() != "td") el = el.parentNode;

	var a = new Array();
	var name = el.lastChild.nodeValue;
	var dad = el.parentNode;
	var table = dad.parentNode.parentNode;
	var up = table.up; // no set/getAttribute!

	var node, arrow, curcol;
	for (var i = 0; (node = dad.getElementsByTagName("td").item(i)); i++) {
		if (node.lastChild.nodeValue == name){
			curcol = i;
			if (node.className == "curcol"){
				arrow = node.firstChild;
				table.up = Number(!up);
			}else{
				node.className = "curcol";
				arrow = node.insertBefore(document.createElement("span"),node.firstChild);
			        arrow.appendChild(document.createTextNode(""));
				table.up = 0;
			}
			arrow.innerHTML=((table.up==0)?"&#8595;":"&#8593;")+"&nbsp;";
		}else{
			if (node.className == "curcol"){
				node.className = "";
				if (node.firstChild) node.removeChild(node.firstChild);
			}
		}
	}
	var tbody = table.getElementsByTagName("tbody").item(0);
	for (var i = 0; (node = tbody.getElementsByTagName("tr").item(i)); i++) {
		a[i] = new Array();
		a[i][0] = getConcatenedTextContent(node.getElementsByTagName("td").item(curcol));
		a[i][1] = getConcatenedTextContent(node.getElementsByTagName("td").item(1));
		a[i][2] = getConcatenedTextContent(node.getElementsByTagName("td").item(0));
		a[i][3] = node;
	}
	a.sort(_sort);
	if (table.up) a.reverse();
	for (var i = 0; i < a.length; i++) {
		tbody.appendChild(a[i][3]);
	}
}
function init(e) {
	if (!document.getElementsByTagName) return;

	if (document.createEvent) function click_elem(elem){
		var evt = document.createEvent("MouseEvents");
		evt.initMouseEvent("click", false, false, window, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, elem);
		elem.dispatchEvent(evt);
	}

	for (var j = 0; (thead = document.getElementsByTagName("thead").item(j)); j++) {
		var node;
		for (var i = 0; (node = thead.getElementsByTagName("td").item(i)); i++) {
			if (node.addEventListener) node.addEventListener("click", sort, false);
			else if (node.attachEvent) node.attachEvent("onclick", sort);
			node.title = "Нажмите на заголовок, чтобы отсортировать колонку";
		}
		thead.parentNode.up = 0;

		if (typeof(initial_sort_id) != "undefined"){
			td_for_event = thead.getElementsByTagName("td").item(initial_sort_id);
			if (td_for_event.dispatchEvent) click_elem(td_for_event);
			else if (td_for_event.fireEvent) td_for_event.fireEvent("onclick");
			if (typeof(initial_sort_up) != "undefined" && initial_sort_up){
				if (td_for_event.dispatchEvent) click_elem(td_for_event);
				else if (td_for_event.fireEvent) td_for_event.fireEvent("onclick");
			}
		}
	}
}
var root = window.addEventListener || window.attachEvent ? window : document.addEventListener ? document : null;
if (root){
	if (root.addEventListener) root.addEventListener("load", init, false);
	else if (root.attachEvent) root.attachEvent("onload", init);
}
</script>

<!-- В заголовках всех сортрируемых таблиц нужно указать class="sort"
кроме этого необходимо заголовок таблицы заключить в <thead>, тело в <tbody> -->
<table class="sort">
<thead>
<tr>
<td>ID</td>
<td>Имя</td>
<td>Фамилия</td>
<td>Сайт</td>
<td>Переключалка стилей</td>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Александр</td>
<td>Шуркаев</td>
<td><a href="#">htmlcoder.visions.ru</a></td>
<td>Не-а</td>
</tr>
<tr>
<td>123</td>
<td>Пол</td>
<td>Соуден</td>
<td><a href="#">idontsmoke.co.uk</a></td>
<td>Угу</td>
</tr>
<tr>
<td>3</td>
<td>Джеффри</td>
<td>Зельдман</td>
<td><a href="#">zeldman.com</a></td>
<td>Угу</td>
</tr>
<tr>
<td>44</td>
<td>Аарон</td>
<td>Будман</td>
<td><a href="#">youngpup.net</a></td>
<td>Не-а</td>
</tr>
<tr>
<td>11</td>
<td>Глен</td>
<td>Мерфи</td>
<td><a href="#">glenmurphy.com</a></td>
<td>Не-а</td>
</tr>
<tr>
<td>15</td>
<td>Даниель</td>
<td>Боган</td>
<td><a href="#">waferbaby.com</a></td>
<td>Не-а</td>
</tr>
<tr>
<td>33</td>
<td>Ден</td>
<td>Бенджамин</td>
<td><a href="#">hivelogic.com</a></td>
<td>Угу</td>
</tr>
</tbody>
</table>

.