Pull to refresh

Javascript. Сортировка таблицы

Reading time3 min
Views41K
Доброго времени суток, Хабровчане.

Может для большинства здешних обитателей моя статья покажется слишком скучной и «и так понятно», но думаю новичкам будет в чем-то полезной.
Стояла передо мной как-то задача сделать сортировку таблицы по разным колонкам. Данный брались из базы, каждый раз их вытаскивать — накладно, решил задействовать JavaScript.
Были небольшие трудности из-за использования различной стилистики строк в таблице, а именно был разный цвет фона, в зависимости от данных самой таблицы.
Стилистику нарушать было нельзя. Кого заинтересовало, прошу под кат.


Подсветка фона выбрана так:
1) если время < 2012 год — подсветка красным
2) если расстояние > 9000 — подсветка желтым.
*) остальное чередование белого с серым.

Данные талицы берутся из БД, рисуется php, последняя колонка скрыта, это время в UNIX-формате, по ней сортировать колонку «Время» проще.

Подключаем такой класс:

var TableSort = function (idTbl, defSortCol, firstRow, classes) {
	// номер колонки, по которой выполнена текущая сортировка, считаем с 0
	var curSortCol = defSortCol;
	// номер колонки, у которой отрисовать картинку, показывающая направление сортировки, считаем с 0
	var curImgCol = defSortCol;
	// направление сортировки вверх
	var curSortUp = true;
	// id таблицы, в которой производим сортировку
	var curIdTbl = idTbl;

	// номер строки, с которой идут данные, считаем с 0
	var numColTr = (firstRow == null) ? 1 : firstRow;

	// нужно ли учитывать классы для строк
	if (classes == null) {	
		var style = false;
	} else {
		var style = true;
		// список классов, которые нужно сохранить
		var needClasses = classes[0];	
		// список классов, которые чередуются
		var listClasses = classes[1];
	}

    var tbl = document.getElementById(curIdTbl);
    var allImgs = new Array(); // all imgs-arrow
	allThs = tbl.getElementsByTagName('tr').item(0).getElementsByTagName('th');
	for (i=0; i<allThs.length; i++){
		if (allThs.item(i).getElementsByTagName('img') != null) {
			allImgs[i] = allThs.item(i).getElementsByTagName('img').item(0);
		} else {
			allImgs[i] = null;
		}
	}

	var tblData = new Array(); // current data in table

	// начинаем сортировку по колонке newCol, картинку рисуем у колонки imgCol
	this.initSort = function (newCol, imgCol) {
		if (newCol == curSortCol) {
			// кликнули на отсортированную колонку, меняем сортировку на обратную
			curSortUp = !curSortUp;
		} else {
			// сортируем по новой колонке
			curSortCol = newCol;
			curImgCol = (imgCol == null) ? newCol : imgCol;
			curSortUp = true;
		}
		showArrow();
		getDataTable();
		showSortTable();
		if (style) {
			doStyle();
		}
		
	};

	// show/change arrow
	function showArrow(){
		for (i=0; i<allImgs.length; i++){
			if (allImgs[i] != null) {
				if (i == curImgCol) {
					allImgs[i].style.visibility = "visible";
					if (curSortUp) {
						allImgs[i].src = "./img/up.png";
					} else {
						allImgs[i].src = "./img/down.png";
					}
				} else {
					allImgs[i].style.visibility = "hidden";
				}
			}
		}
	}

	// get new data from table
	function getDataTable() {
		allTrs = tbl.getElementsByTagName('tr');
		for (i=numColTr; i<allTrs.length; i++){
			tblData[i-numColTr] = new Array();
			for (j=0; j<allTrs[i].getElementsByTagName('td').length; j++) {
				tblData[i-numColTr][j] = allTrs[i].getElementsByTagName('td').item(j).innerHTML;
			}
			if (style) {
				tblData[i-numColTr][allTrs[i].getElementsByTagName('td').length]=allTrs[i].className;
			}
		}
		tblData.sort(_sort);
		if (!curSortUp) {
			tblData.reverse();
		}
	}

	// rules for sorting
	function _sort(a1, b1) {
		var a = a1[curSortCol];
		var b = b1[curSortCol];
		if (parseFloat(a) && parseFloat(b)) {
			return parseFloat(a) - parseFloat(b);
		} else {
			if (a.toLowerCase() < b.toLowerCase()) {
				return -1;
			} else if (a.toLowerCase() > b.toLowerCase()) {
				return 1;
			} else {
				return 0;
			}
		}
	}

	function showSortTable() {
		allTrs = tbl.getElementsByTagName('tr');
		for (i=numColTr; i<allTrs.length; i++){
			for (j=0; j<allTrs[i].getElementsByTagName('td').length; j++) {
				allTrs[i].getElementsByTagName('td').item(j).innerHTML = tblData[i-numColTr][j];
			}
			if (style) {
				allTrs[i].className=tblData[i-numColTr][allTrs[i].getElementsByTagName('td').length];
			}
		}
	}
	function doStyle(){
		allTrs = tbl.getElementsByTagName('tr');
		for (i=numColTr; i<allTrs.length; i++){
			if (allTrs[i] == null) {
				continue;
			}
			if(needClasses.indexOf(allTrs[i].className) != -1) {
				continue;
			}
			allTrs[i].className = listClasses[(i % listClasses.length)];
		}
	}

}

Создаем объект так:
var infoTblSort = new TableSort("idTbl", 0, 1, [['add', 'edd'],['odd', '']] );

Для работы в заголовке нужной колонки дописываем что-то похожее на:
onclick="infoTblSort.initSort(4,3);"

В этом примере передается 2 параметра, первый — по которому будет идти сортировка (в данном случае — это скрытая колонка UNIX-время), вторая — колонка, у которой будет стоять картинка, указывающая направление текста.

Пример тут.

На этом все, надеюсь мой опыт будет кому-то полезен. Прошу пощения за несколько сумбурный рассказ, впервые пишу статью.
Спасибо за внимание.
Tags:
Hubs:
Total votes 25: ↑14 and ↓11+3
Comments17

Articles