Что лучше: посылать к базе данных запрос «вслепую», или фильтровать видимые данные прямо на HTML-странице (как на листе Excel)? При наличии инструмента «визуальной» фильтрации HTML, можно найти «золотую середину»

Javascript фильтрация данных

Сортировать HTML-таблицу мы уже научились. Вторая после сортировки задача базы данных – выборка строк из таблицы по определённому критерию. Например, чтобы поле город заканчивалось на -тск. Эту вторую задачу разумнее, конечно, решать на сервере: сначала выбрать данные, а потом вывести их на HTML-страницу. А не наоборот – выложить всю таблицу из БД пользователю, а он потом пусть как хочет сортирует и фильтрует этот многомегабайтный файл.

Проблема в том, что пользователь не всегда точно знает, что ищет (как наилучшим образом сформулировать запрос для БД). Например, вы хотите найти «выпадающее меню» в Яндексе. Ну, нашли сколько-то тысяч миллионов. Полистали ссылки, оказалось, что надо всё-таки «многоуровневое меню». А потом ещё одно уточнение: «выезжающее» (а не «выпадающее»). Увидели, что с этим связано слово «слайд» (или slide) – и опять новый запрос, в котором половина первоначальных данных по меню теряется... Всё это вы ищете приблизительно на первых десяти страницах. И можно не набирать каждый раз новый запрос для поиска, а вывести, например, первых 100 результатов (или хотя бы 50) по «приблизительному» запросу, а потом дополнительные слова искать в браузере обыкновенным Ctrl+f. При поиске с помощью Ctrl+f современные версии браузеров обычно подсвечивают все найденные результаты на странице.

Если данные выводятся в HTML в виде таблицы, можно эту таблицу скопировать в Excel и там сортировать и фильтровать, гибко отбирать нужные данные. Всё дело в этом – в гибкости визуальных (как в Excel) табличных фильтров. При запросе к серверной БД вы заранее не видите, из чего выбирать, и невольно возникает скрытое пожелание: «Огласите весь список!». У кого-то, конечно, возникает, а у кого-то и нет. Узнать мы об этом наверняка не можем, потому что для визуальных фильтров, для отбора данных прямо на HTML-странице просто не существует широко используемых инструментов. У себя на сайтах мы начинаем понемногу такие инструменты внедрять.

Пример – список рубрик для доски объявлений http://irkutsk.ir2.ru/. В правом фрейме мы выводим весь список рубрик (что-то вроде таблицы из одной колонки), а над списком – поле ввода для поиска. При вводе букв в поле поиска список немедленно изменяется:

Это лучше, чем подсвечивание браузера по Ctrl+f; потому что при подсвечивании все ненужные строки остаются на странице, и среди них бывает довольно сложно найти высвеченное слово. Применение фильтра же предполагает, что на странице остаются только строки с искомым значением.

Следующий шаг – создание фильтра для таблицы из нескольких колонок. Фильтры обычно используют вместе с сортировкой, поэтому Javascript функцию фильтрации строк мы не стали помещать в отдельный проект, а просто добавили к скрипту Simple Table Sorter и присвоили ему номер версии 2.0 (файл http://ir2.ru/static/tabsort2.js); примеры работы: http://ir2.ru/static/tabsort3.htm, http://ir2.ru/static/limit1000.htm (260 Кб, 1000 строк – для оценки производительности).

Подключение

Функция фильтрации подключается к скрипту-сортировщику так.

1. Во-первых, надо подключить сам скрипт сортировки, для этого в элемент head страницы нужно поместить три следующие строчки:

(ну, и, соответственно, поместить на сайт три файла: http://ir2.ru/static/ir2.js, http://ir2.ru/static/tabsort2.js, http://ir2.ru/static/tabsort.css). Для того, чтобы таблица обрабатывалась сортировщиком (и функцией фильтрации), в HTML-коде таблицы следует указать <table class="sortable">

2. Сам модуль фильтров по значениям колонок таблицы можно подключить двумя способами: только к заголовкам с явно указанным типом сортировки (<th axis="num">, <th axis="str">) или ко всем заголовкам подряд.

Для подключения фильтров к заголовкам с явно указанным типом сортировки нужно в секции скрипта tabsort2.js "Настройки" назначить use_inputs = true.

Для подключения модуля фильтров ко всем заголовкам сортируемых таблиц без разбора в секции "Настройки" назначить use_inputs = true; inputs_force = true.

Особенности работы

Подключенный модуль фильтров во время подготовки таблиц к сортировке (функция preptabs()) добавляет к каждому (если inputs_force = true) полю заголовка таблицы элементы input: если тип сортировки задан явно и равен "num" (<th axis="num">), добавляется два поля ввода input с подсказками впереди (>= и <=); если ввести число в верхнее поле ввода (>=), будет производиться отбор строк, данный столбец которых содержит числа большие или равные введённому пользователем значению; елси ввести число в нижнее поле – наоборот; таким образом, можно отфильтровать диапазон чисел по данному столбцу.

Во всех остальных случаях (<th axis="str">, другие значения, не равные "num" или вообще отсутствие axis) функция preptabs() добавляет к полю заголовка один элемент input; при вводе в него символов производится поиск значений по данному столбцу – ищутся совпадения с введённой пользователем строкой от начала строк; если первым символом в поле поиска пользователь введёт пробел, будут искаться совпадения в любой части строки (не только от начала).

Количество найденных строк отображается в отдельном элементе span с красной рамкой, который позиционируется на 100 пикселов выше поля поиска. Оформление этого элемента можно изменить в правилах CSS для класса .abstopleft в файле tabsort.css. Для удаления сообщения с количеством результатов следует нажать Escape. При последующих отборах строк с помощью полей поиска сообщение будет появляться заново.

Производительность

Скорость фильтрации строк (как и сортировки) с помощью наших Javascript функций невелика. Её, разумеется, нельзя сравнивать со скоростью фильтрации на стороне сервера. Так, в нашем примере из 1000 строк (файл http://ir2.ru/static/limit1000.htm, 260 Кб) отбор после введённого значения для поиска длится 3-4 секунды (AMD Athlon 999МГц, 512 МБ ОЗУ, Windows XP, Firefox 3). В Гугл Хроме, разумеется, в полтора-два раза быстрее. Ну, и скорость работы нашего Simple Table Sorter'а в любом случае выше скорости работы всех известных нам аналогов типа сортировщика для jQuery: наши алгоритмы - и сортировки, и фильтрации данных - ориентированы прежде всего именно на скорость работы (за счёт чего, конечно, в какой-то степени пострадал интерфейс).

Функция фильтрации строк, работающая на этой странице:

D.M., admin

Комментарии

Павел 30.04.2014 18:28:46

444. Михаил -> попробывал твой код, краснеет надпись в поле если совпадений нет, но поля не изчезают, в чем косяк???

Михаил 10.02.2014 22:07:51

Спасибо за статейку, прочитал разобрался и сделал свой вариант на jQuery Вот мой вариант фильтрации, может кому пригодиться: <stylesheet type="text/css"> .hid {display: none;} </stylesheet> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> <script type="text/javascript"> function pick(obj) { var val=obj.value.toUpperCase(); if(obj.value=="") { $("#catalog_source li").toggleClass('hid', false); } if($("#catalog_source li").text().toUpperCase().indexOf(val)==-1){ $("#catalog_source li").toggleClass('hid', false); $('input[name="filtr_g"]').css('color', 'red'); }else{ if(obj.value.length>0) { $('input[name="filtr_g"]').css('color', 'black'); } if(obj.value.length>0){ $("#catalog_source li").each(function(){$(this).toggleClass('hid', $(this).text().toUpperCase().indexOf(val)==-1); }); } } } </script>

<html> <input name="filtr_g" type="text" onkeyup="pick(this);" onClick="this.value='';pick(this);" title="Начинайте вводить название группы что бы снять фильтр достаточно щелкнуть мышкой в поле ввода."> <ul id="catalog_source"> <li><a href="static/?m=1">Машины</a></li> <li><a href="static/?m=2">Самолеты</a></li> <li><a href="static/?m=3">Танки</a></li> <li><a href="static/?m=4">Корабли</a></li> </ul> </html>

Дилетант 16.10.2013 14:23:05

Олег,

а какая разница, картинка в колонке или дата? Картинка в html-таблице – это точно такой же текст, состоящий из букв и угловых скобок: <img src="asdf" alt="моя картинка 1">, значит, вы точно так же сможете искать в нём слова "моя картинка".

Положение и размер элемента input можно определить с помощью правил css. Назначьте элементу при генерации какой-то класс, а потом создайте правила для этого класса (селектора) в css-файле.

Олег 03.10.2013 01:01:05

А как изменить положение инпута и размер его??

Олег 28.09.2013 22:10:27

Добрый день! Извиняюсь за свой глупый вопрос. Подскажите, с помощью скрипта есть возможность сделать поиск (выборку) по таблице, в которой есть колонка с картинкой (фотографией)?

Спасибо!

Дилетант 21.09.2013 00:10:30

Nikita, к сожалению, весь код на этой странице сильно устарел, я уже не могу себе позволить заниматься его поддержкой.

По вашим вопросам видно, что вы многого не знаете. Вам лучше почитать учебник, статьи на сайте javascript.ru – очень полезно и понятно всё изложено.

Nikita 11.09.2013 19:59:12

А можно модуль который выполняет только фильтрацию и ничего более? Ну как на этой странице? Тот код, который указали внизу вообще не ясен

Nikita 11.09.2013 02:38:09

У меня не работает в хроме поиск – в чем может быть дело?. В эскплорере работает. И еще хотел спросить после сортировки как сбросить её?

Дилетант 14.05.2013 02:58:48

Иван, внутри скрипта результаты фильтрации хранятся именно в виде массива. Он называется то ли rarr, то ли sarr, не помню.

Дилетант 14.05.2013 02:55:00

Севак Спартакович, в этой версии скрипта я уже не буду ничего менять, она сильно устарела. Со мной можно связаться через дизайн-бюро Модерн: dbmodern@mail.ru (Михаил)

Роман Дмитриенко 24.04.2013 08:49:16

Как создать такую таблицу с выбором. http://support.google.com/drive/bin/static.py?hl=ru&topic=25273&page=table.cs

Севак Спартакович 21.04.2013 07:01:08

А можно в поиске по части значения избавиться от необходимости ставить пробел перед фразой? Как можно с Вами связаться ? У меня есть предложение к вам.

Иван 19.04.2013 00:53:17

Подскажите, как и какими средствами можно сохранить результаты фильтрации, например, в файл или в массив для дальнейшей его обработки?

лесник 23.10.2012 18:50:42

AndreyT,

скрипт tabsort2.js – первый мой опыт в фильтрации данных. Более корректный скрипт позже был переименован в BigTableSorter (http://ir2.ru/static/sorters/BigTableSorter1.zip). Рабочий пример: http://ir2.ru/static/sort1/table2000_1.htm

AndreyT 10.10.2012 03:01:29

Код криво встал. Вот картинка с кодом http://photo.qip.ru/users/interwert9/151180363/175836295/

AndreyT 10.10.2012 02:54:32

Никак не могу справится с этим сортировшиком в браузере Хром и Опера (в фоксе не пробовал). Фильтр работает правильно без проблем. А вот сортировка не коректная както перемешивает все криво. Это картинка сортировка по большему: [url]http://photo.qip.ru/users/interwert9/151180363/175836157/[/url] Это от меньшего к большему: [URL=http://photo.qip.ru/users/interwert9/151180363/175836156/][IMG]http://photo.qip.ru/photo/interwert9/151180363/small/175836156.jpg[/IMG][/URL] Сортирует както очень криво.Хотя в томже хроме ваши таблицы сортируются правильно.

Вот код создания таблицы, она формируется из MySQL.

[quote] <?php // ввод данных для доступа к базе, хост, логин, пароль.. $con = mysql_connect("192.168.2.200","login","password");

if (!$con) { die('Could not connect: ' . mysql_error()); } mysql_select_db("dbase", $con); mysql_query("set names utf8"); $result = mysql_query("SELECT * FROM zayavki WHERE TO_DAYS(now()) – TO_DAYS(d_sozdania) <= '40'"); // формирование самой таблицы

echo "<table background='images/oformlenie_tablicy_zayavok.jpg', class='sortable', id='t' > <thead> <tr > <th axis='num::desc' >ID</th> <th axis='daten'>Дата заказа</th> <th axis='str'>Менаджер</th> <th axis='str'>Статус</th> </tr> </thead>";

// цыкл масива по заполнению таблицы echo "<tbody >"; while($row = mysql_fetch_array($result)) { echo '<tr '; if ( $row['flag']=='Сделано' )$color = '#99fFcC'; elseif ($row['flag']=='Невозможно') $color = '#ffc0cb'; elseif ($row['flag']=='Принято') $color = '#FFDFAA'; elseif ($row['flag']=='Частично') $color = '#CCCCCC'; else $color = '#ffffff'; echo 'bgcolor="' . $color . '" > <td>' . $row['id'] . '</td>'; echo '<td >' . $row['d_sozdania'] . '</td>'; echo '<td>' . $row['manager'] . '</td>'; echo '<td>' . $row['flag'] . '</td>'; echo '</tr>'; } echo "</tbody>"; echo "</table>";

mysql_close($con); ?> [/quote]

Подскажите в чом ошибку допустил, никак не разобраться.

лесник 18.11.2011 04:46:37

asmman,

можно. Сам уже отказался на рабочих сайтах от идеи ставить впереди пробелы. Только скажите, в каком скрипте это сделать (а то версий много, я уже сам в них запутался). Напишите здесь ссылку на дистрибутив или вышлите файл js на адрес stopkran@inbox.ru, я исправлю.

asmman 17.11.2011 20:11:43

А можно в поиске по части значения избавиться от необходимости ставить пробел перед фразой? А то пользователям разяснения необходимо писать а они их вряд ли читать будут.

лесник 09.10.2011 03:27:04

Добавлено поле "Общий поиск:" над таблицей; при вводе букв в это поле производится поиск значений по всем столбцам. Пример: http://ir2.ru/static/sort1/table1000.htm (это скрипт Big Table Sorter v 1.01 )

лесник 04.10.2011 01:32:49

Alexey,

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

Alexey 02.10.2011 11:40:01

Хорошая у Вас получилась фильтрация. А как сделать и возможно ли это чтоб поля для ввода значения поиска было не над каждым столбцом, а всего одно на всех. т.е. введенное в него значение осуществляло поиск по всей таблице во всех колонках.

лесник 27.02.2011 22:20:25

Da Boogie Woogie, подходит. Но проблема в том, что и "такая" и "сякая" зебры очень хорошо и безусловно подходят ко всем браузерам, кроме ИЕ. В ИЕ я перепробовал, кажется, все способы зебр, и каждая из них при некоторых условиях работы начинает сильно тормозить. Я давно исключил из своих скриптов все эти критичные условия, но "осадок остался"...

Da Boogie Woogie 24.02.2011 23:12:42

а вот такая зебра: tr:nth-child(2n+1) { background:#ddd; } не подходит?

player0 21.01.2011 07:11:38

Эх жаль, что в новой зебры нет. А с большой версией связываться не хочу. PS: комментарии тут добавляются через раз :(

лесник 20.01.2011 16:34:28

Здравствуйте, Player0! Не, к старой версии я уже возвращаться не могу. Сейчас скрипт существует в двух видах:

1) маленький (без зебры) – http://ir2.ru/static/sorters/SimpleTableSorter.zip;

2) для больших таблиц (зебра есть) – http://ir2.ru/static/sorters/BigTableSorter1.zip. Пример в работе: http://irk09.ru/ (только там очень внимательно подключать надо – по инструкции на стр. tabsort1.aspx – раздел «Дистрибутив и использование»).

Вот по этим версиям приму любые замечания и всё постараюсь исправить (или дополнить).

Player0 18.01.2011 10:42:01

Здравствуйте. Пользуюсь вашим скриптом. Версия старенькая (1.2 http://front-mission.org/skripts/tabsort.js), но зато меня в ней всё устраивало. Сменил тут DOCTYPE на XHTML 1.0 Transitional и скрипт стал некорректно работать – а именно, перестала работать "зебра" в файрфоксе и хроме. При первой же сортировке всё смешивается. В опере работает нормально :) Попробовал самую новую версию – там тоже самое. В чём может быть дело?

лесник 26.08.2010 14:47:46

Готов скрипт сортировки и фильтрации данных, версия 2.1: tabsort2.1.js. Изменение в способе подключения:

  1. Не нужна библиотека ir2.js (все необходимые функции есть внутри самого скрипта).
  2. Вместе со скриптом tabsort2.1.js необходимо подключать к HTML-странице файл стилей tabsort.css (так как CSS-правил стало слишком много).

Пример работы: limit202.htm

тест 26.08.2010 14:45:05

Во-от. Сказано же в форме добавления статей: в имени файла только латинские буквы! А я решил выпендриться, добавил подчёркивания (js_data_filter), думал, это просто так про только латинские буквы написано. Вот комментарии и перестали добавляться. Теперь исправлено.

лесник 24.10.2010 20:43:43

Система отбора и сортировки данных пополнилась разбиением таблицы на страницы (paginate) и стала такой сложной, что пришлось собрать все необходимые для работы файлы в архив BigTableSorter.zip.

Примеры работы: test-tracker/limit1003.htm – таблица в 1000 строк; test-tracker/tracker2.php.htm – таблица в 500 строк (из-за объёма работает медленнее, чем в 1000 строк); test-tracker/tracker.php.htm – на движке jquery.tablesorter.js (для сравнения с нашим);

test-tracker/limit3000.htm – таблица в 3000 строк.