Web-дизайн и web-программирование

Статьи | Скрипты | Книги | Программы | Шаблоны | Рассылки сайта | Юмор
Здравствуйте, уважаемые подписчики!

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

Автор: Александр Шуркаев
Источник: htmlcoder.visions.ru

Иногда перед разработчиком стоит задача обеспечить сортировку столбцов в таблице с данными. Классическим решением является использование какого-нибудь серверного ЯП, который бы сортировал данные по определённому столбцу и отдавал полученную страницу клиенту.

Я хочу вам предложить альтернативное решение, работающее в W3C DOM-совместимых браузерах: Internet Explorer 5+, Netscape Navigator 6+/Mozilla и Opera 7+.

Первым алгоритм сортировки предложил Пол Соуден (Paul Sowden), я же внёс в скрипт существенные коррективы: на странице может быть несколько таблиц, в которых должна происходить сортировка; возможны разные алгоритмы сортировки, что позволяет, например, корректно сортировать числа; можно задать начальный отсортированный столбец; были также добавлены некоторые украшательства (стрелочки) и т. д.

В других браузерах (например, Opera 6) таблица просто останется не отсортированная, в первозданном виде.

Теперь же о том, всё это дело реализуется. Буду объяснять по пунктам (изменения в плане HTML, CSS и JavaScript), чтобы легче было проследить логику.

HTML


Прежде всего, необходимо особым образом отформатировать таблицу, к которой вы собираетесь подключить возможность сортировки. Обратите внимание на код:

<table class="sort" align="center">
<
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="http://htmlcoder.visions.ru/">htmlcoder.visions.ru</a></td>
<
td>Не-а</td>
</
tr>

<tr>
<
td>33</td>
<
td>Ден</td>
<
td>Бенджамин</td>
<
td><a href="http://hivelogic.com/">hivelogic.com</a></td>
<
td>Угу</td>
</
tr>
</
tbody>
</
table>

Как вы видите, необходимо указать теги thead (шапка таблицы) и tbody (основная часть). Обычно их мало кто использует, но здесь эти теги весьма кстати.

Вам также нужно создать две картинки, которые бы указывали текущий вариант сортировки — 0.gif (картинка сортировки вниз) и 1.gif (картинка сортировки вверх). Положите их, например, в корневой директории в папку «i». Я обычно называю папки с картинками для сайта именно так, но ничто не мешает использовать для наших целей классическую папку «images». Дело хозяйское, просто тогда вам нужно будет поменять в программке переменную img_dir (см. ниже пункт JavaScript).

В моём случае стрелочки выглядят так (можете их спионерить, я не против :-):

CSS


Задаём следующие классы в таблице стилей:

/* наша 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;
cursor:hand;
font-weight:bold;
text-align:center;
vertical-align:middle
}

/* заголовок отсортированного столбца */
table.sort thead td.curcol{
background-color:#999999;
color:#FFFFFF
}

Затем не забудьте указать у HTML таблицы класс sort (<table class="sort" align="center">).

JavaScript


Итак, мы подошли к «начинке» всего этого дела. Пропишите на странице следующий фрагмент:

<script type="text/javascript">
<!--
/*
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
*/

var img_dir = "/i/"; // папка с картинками
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 (
parseFloat(_a) && parseFloat(_b)) return sort_numbers(parseFloat(_a), parseFloat(_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;
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("img"),node.firstChild);
table.up = 0;
}
arrow.src = img_dir + table.up + ".gif";
arrow.alt = "";
}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;

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 (
document.createEvent){
var
evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", false, false, window, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, td_for_event);
td_for_event.dispatchEvent(evt);
} 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) td_for_event.dispatchEvent(evt);
else if (
td_for_event.fireEvent) td_for_event.fireEvent("onclick");
}
}
}
}

// запускаем ф-цию init() при возникновении события load
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>

Единственное, что вам нужно поменять в скрипте, так это переменную img_dir. Она должна указывать на каталог, где у вас лежат файлы 0.gif (картинка сортировки вниз) и 1.gif (картинка сортировки вверх). Можете ещё поменять переменную sort_case_sensitive, но лучше оставьте её в значении false.

Я решил не разбирать детально сам скрипт. Кому интересно, как всё работает, думаю, сам сможет понять.

Засим откланиваюсь. До встречи!

P. S. Добавлена возможность указания начального отсортированного столбца. Для этого нужно определить переменные initial_sort_id (номер столбца, начиная с нуля) и initial_sort_up (0 или 1, сортировка вниз или вверх). Для таблицы в данной статье значения следующие:

<script type="text/javascript">
<!--
initial_sort_id = 0;
initial_sort_up = 1;
-->
</script>

Вверх

Вопрос в рассылку

В предыдущем выпуске рассылки был задан вопрос по поводу вывода данных сайта в результате запроса. Ответ прислал ksb:

Как формируются описания (сниппеты) одному богу (Яндексу) известно.

В вашем случае, все логически правильно. Первая строка описания – это по всей видимости кусок из названия документа, а второе – искомое вхождение поискового запроса. Поисковый запрос в выдаче выделен, что еще нужно?

Если хотите чтобы в выдаче стояло первое слово (запрос), то необходимо седлать его первым в title, description, и первым на странице в тексте (h1..h3, strong) - иными словами «заточить страницу под этот запрос». Необходимость данных действий определяются из важности данного запроса. Не думаю, что номер телефона – это так важно, важнее что там есть (к примеру «Окна ПХВ»), а уж если посетитель решит связаться, то телефон найдет (если Вы его укажете).

Вверх

Обновлние сайта

С момента последнего выпуска рассылки на сайт добалены статьи: Секреты FireFox, Голосование на PHP, книга Разгони свой сайт, скрипты: Двухуровневый список, Myxml (класс PHP для работы с XML), Дни жизни, а также пара шаблонов.

Вверх


Вот и закончился очередной выпуск нашей рассылки. Вашу критику, вопросы, пожелания вы можете отправить на мой e-mail. До новых встреч!
Ведущий рассылки Алексей Голубев.
Статьи | Скрипты | Книги | Программы | Шаблоны | Рассылки сайта | Юмор
Hosted by uCoz