Фильтрация и проверка данных PHP. Частые ошибки. Фильтр диапазона значений "ОТ" и "ДО"

Наконец, я нашел время и хочу представить вашему вниманию свой новый скрипт, который позволяет осуществить фильтрацию данных в html-таблицах.

Скрипт поддерживает следующие типы фильтров:

  • Текстовое поле
  • Выпадающий список
  • Радио-кнопки
  • Чекбоксы

Скрипт имеет малый размер и достаточно прост в подключении, а так же неплохо комбинируется со скриптом сортировщиком таблиц скачать его вместе с примерами подключения и настройки можно в моем репозитории: bitbucket.org

Фильтр таблицы демо: Символы Текст Цифры Цифры Текст
A B C --- 1 2 3 - 1 2 3
B Арбуз 2 3 Фанат
B Стрелок 1 2 Арба
C Фанат 3 1 Стрелок
C Стрелок 2 1 Фантомас
B Стрелок 1 2 Арбуз
C Фанат 3 3 Стрелок
A Арбуз 2 2 Арбуз
A Фанат 1 1 Стрелочник
C Фанат 3 3 Арбуз
B Фанат 2 3 Фантик
C Стрелок 1 1 Арбуз
C Фанат 3 2 Стрелка

Концептуально скрипт состоит из двух частей: объектов-фильтров filterTable.Filter и собственно из функции filterTable(...) , которая привязывает эти объекты-фильтры к html-таблице.

Объект-фильтр имеет следующий конструктор:

/** * Объект фильтр. * @param HTMLInputElement | HTMLSelect HTMLElementRef | - Ссылка, или массив ссылок * на html-элементы, служащие фильтрами. * @param Function callback - ф-ция обратного вызова. Вызывается когда скрипт * производит валидацию содержимого ячейки. Ф-ция вызывается для каждой строки таблицы, для * каждой ячейки столбца, для которого назначен фильтр. * Функции будут переданы 3 параметра: callback(value, filters, i) где: * String value - значение ячейки таблицы, проверяемой на момент вызова ф-ции * HTMLElements filters - массив HTML-элементов назначенных фильтрами для проверяемого столбца. * Number i - индекс элемента фильтра в массиве filters который является * валидатором для текущего вызова. Т.е. filters[i] внутри ф-ции * обратного вызова будет содержать элемент, с которым провзаимодействовал * пользователь, в результате чего был запущен процесс валидации. * @param String eventName - название события привязанного к фильтру, по которому будет * запускаться валидация (onkeyup | onclick | onblur | onchange и т.п.) * @constructor */ filterTable.Filter = function (HTMLElementRef, callback, eventName) Первый аргумент: HTMLElement HTMLElementRef

Второй аргумент: Function callback

Функция: callback(value, filters, i) где:
String value - значение ячейки таблицы, проверяемой на момент вызова ф-ции
HTMLElements filters - массив HTML-элементов назначенных фильтрами для проверяемого столбца.
Number i - индекс элемента фильтра в массиве filters который является валидатором для текущего вызова. Т.е. filters[i] внутри ф-ции обратного вызова будет содержать элемент, с которым провзаимодействовал пользователь, в результате чего был запущен процесс валидации. Функция должна возвращать true, или false в зависимости от того проходит фильтрацию пришедшее значение value при установленном значении фильтра filters[i] согласно вашей задумке, или нет.

Третий аргумент: String eventName

Название события привязанного к фильтру, по которому будет запускаться валидация (onkeyup | onclick | onblur | onchange и т.п.) onchange - значение по-умолчанию

Сама же функция filterTable имеет следующую сигнатуру:

таблицы * @param Object filters - объект-конфигурация фильтров: { N: FILTER[, N: FILTER] } * * Где: * NUM - это натуральное число - номер столбца таблицы, обслуживаемого * фильтром. Этот номер может принимать значения от 0 до кол-во * столбцов таблицы - 1. Номера можно задавать не по порядку. * * FILTER - это ссылка на HTML-элемент представляющий собой элемент * HTML-формы и имеющий атрибут value (select в том числе), либо * объект типа tableKit.Filter */ filterTable(HTMLTBodyRef, aFilters)

Выглядит достаточно запутанно, но давайте разберем на примере. Для начала нам необходим html - каркас таблицы. Заметьте, что фильтры - это просто элементы html-формы они кстати имеют уникальные атрибуты id по которым мы их будем выбирать для передачи в конструктор filterTable.Filter

Символы Текст Цифры Цифры Текст
A B C --- 1 2 3 - 1 2 3
BАрбуз23Фанат
BСтрелок12Арба
CФанат31Стрелок
CСтрелок21Фантомас
BСтрелок12Арбуз
CФанат33Стрелок
AАрбуз22Арбуз
AФанат11Стрелочник
CФанат33Арбуз
BФанат23Фантик
CСтрелок11Арбуз
CФанат32Стрелка
Стоит отметить, что такие типы фильтров, как текстовое поле, или выпадающий список - являются для скрипта "родными" и для того чтобы их реализовать не требуется даже прибегать к вызову filterTable.Filter - достаточно просто передать ссылку на сам html-элемент.

Итак, каркас у нас есть. Фильтры в нём есть. Осталось все это связать воедино. Но давайте для начала рассмотрим простейший вариант подключения, и разберем лишь фильтры для 2-го и 3-го столбцов, потому, как там используются текстовое поле и выпадающий список значений, которые скрипт-фильтр понимает "нативно" без нужды создания filterTable.Filter Я нарочно закомментировал элементы 0, 3, 4 и пока обозначил их реализацию как "..." что бы преждевременно не отпугнуть слабонервных:)

Обратите внимание, что второй аргумент ф-ции filterTable(..., {...} ) - это объект-конфигурация фильтров, у которого свойства имеют имена-цифры, начиная от 0 и до КОЛ-ВО_СТОЛБЦОВ_ТАБЛИЦЫ-1 Значением каждого такого свойства должен стать фильтр:

таблицы */ document.getElementById("target"), /* Объект-конфигурация фильтров: */ { /* Фильтр для первого столбца чекбоксы: 0: ..., */ /* Фильтр для второго столбца текстовое поле - только точное совпадение: */ 1: document.getElementById("text"), /* Фильтр для третьего столбца выпадающий список: */ 2: document.getElementById("digits"), /* Фильтр для четвертого столбца радио кнопки: 3: ... , /* Фильтр для пятого столбца Постепенный ввод слова: 4: ... */ });

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

Опять же обратите внимание, что для текстового поля и выпадающего списка достаточно просто передать ссылку на html-элемент. А так же обратите внимание на подключение последнего фильтра. Вы спросите почему - ведь в последнем столбце фильтр - это текстовое поле! Да это так, но если вы внимательно поработали с демо примером, то заметили, что первый фильтр - тестовое поле срабатывает только после того как вы ввели значение полностью и нажали кнопку "Enter", или кликнули в любое другое место страницы т.е. фильтр срабатывает по дефолтному событию "onchange"! А вот фильтр-текстовое- поле последнего столбца - срабатывает моментально как только вы вводите какой-либо символ. Вот для реализации этого поведения пришлось создавать фильтр по всем правилам с filterTable.Filter а так же понадобилось задавать callback функцию и плюс к этому необходимо было передать имя события "onkeyup" по которому будет инициироваться процесс фильтрации. Вот так. Надеюсь я вас не запутал окончательно.

FilterTable(/* Ссылка на элемент таблицы */ document.getElementById("target"), /* Объект-конфигурация фильтров: */ { /* Фильтр для первого столбца чекбоксы: */ 0: new filterTable.Filter([ /* Элементы фильтра */ document.getElementById("charA"), document.getElementById("charB"), document.getElementById("charC") ], /* Коллбэк ф-ция валидации */ function (value, filters, i) { /* Если чекбокс не отмечен - его значение не учавствует в валидации поэтому мы обязаны вернуть true */ if (false === filters[i].checked) return true; /* Далее, при проверке, мы должны одновременно проверять значения всех элементов набора при условии чекбокс отмечен */ return filters.checked && filters.value === value || filters.checked && filters.value === value || filters.checked && filters.value === value; }), /* Фильтр для второго столбца текстовое поле - только точное совпадение: */ 1: document.getElementById("text"), /* Фильтр для третьего столбца выпадающий список: */ 2: document.getElementById("digits"), /* Фильтр для четвертого столбца радио кнопки: */ 3: new filterTable.Filter(, /* Коллбэк ф-ция валидации */ function (value, filters, i) { /* В filters - у нас радио кнопка "Не выбрано", если она установлена фильтр не участвует в валидации и мы обязаны вернуть true */ if (true === filters.checked) return true; /* Если какая то радио-кнопка отмечена и содержимое проверяемой ячейки совпало то вернем true */ return filters.checked && filters.value === value || filters.checked && filters.value === value || filters.checked && filters.value === value; }), /* Фильтр для пятого столбца Постепенный ввод слова: */ 4: new filterTable.Filter(document.getElementById("regexp"), /* Коллбэк ф-ция валидации */ function (value, filters, i) { return value.indexOf(filters[i].value) === 0; }, /* Будем вызывать валидацию по событию onkeyup фильтра */ "onkeyup") });

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

/** * Привязать фильтры к таблице. * @param HTMLTableSectionElement HTMLTBodyRef - ссылка на элемент таблицы * @param Object filters - объект-конфигурация фильтров: { N: FILTER[, N: FILTER] } * * Где: * NUM - это натуральное число - номер столбца таблицы, обслуживаемого * фильтром. Этот номер может принимать значения от 0 до кол-во * столбцов таблицы - 1. Номера можно задавать не по порядку. * * FILTER - это ссылка на HTML-элемент представляющий собой элемент * HTML-формы и имеющий атрибут value (select в том числе), либо * объект типа tableKit.Filter */ var filterTable = function (HTMLTBodyRef, aFilters) { var rows = HTMLTBodyRef.getElementsByTagName("TR"), filters = {}, n, walkThrough = function (rows) { var tr, i, f; for (i = 0; i < rows.length; i += 1) { tr = rows.item(i); for(f in filters) { if (filters.hasOwnProperty(f)) { if (false === filters[f].validate(tr.children[f].innerText)) { tr.style.display = "none"; break; } else { tr.style.display = ""; } } } } }; for(n in aFilters) { if (aFilters.hasOwnProperty(n)) { if (aFilters[n] instanceof filterTable.Filter) { filters[n] = aFilters[n]; } else { filters[n] = new filterTable.Filter(aFilters[n]); } filters[n]._setAction("onchange", function () {walkThrough(rows);}); } } } /** * Объект фильтр. * @param HTMLInputElement | HTMLSelect HTMLElementRef | - Ссылка, или массив ссылок * на html-элементы, служащие фильтрами. * @param Function callback - ф-ция обратного вызова. Вызывается когда скрипт * производит валидацию содержимого ячейки. Ф-ция вызывается для каждой строки таблицы, для * каждой ячейки столбца, для которого назначен фильтр. * Функции будут переданы 3 параметра: callback(value, filters, i) где: * String value - значение ячейки таблицы, проверяемой на момент вызова ф-ции * HTMLElements filters - массив HTML-элементов назначенных фильтрами для проверяемого столбца. * Number i - индекс элемента фильтра в массиве filters который является * валидатором для текущего вызова. Т.е. filters[i] внутри ф-ции * обратного вызова будет содержать элемент, с которым провзаимодействовал * пользователь, в результате чего был запущен процесс валидации. * @param String eventName - название события привязанного к фильтру, по которому будет * запускаться валидация (onkeyup | onclick | onblur | onchange и т.п.) * @constructor */ filterTable.Filter = function (HTMLElementRef, callback, eventName) { /* Если ф-цию вызвали не как конструктор фиксим этот момент: */ if (!(this instanceof arguments.callee)) { return new arguments.callee(HTMLElementRef, callback, eventName); } /* Выравниваем пришедший аргумент к массиву */ this.filters = {}.toString.call(HTMLElementRef) == "" ? HTMLElementRef: ; /** * Шаблонный метод вызывается для каждой строки таблицы, для соответствующей * ячейки. Номер ячейки задается в объекте-конфигурации фильтров ф-ции * filterTable (См. параметр 2 ф-ции tableFilter) * @param String cellValue - строковое значение ячейки * @returns {boolean} */ this.validate = function (cellValue) { for (var i = 0; i < this.filters.length; i += 1) { if (false === this.__validate(cellValue, this.filters[i], i)) { return false; } } } this.__validate = function (cellValue, filter, i) { /* Если фильтр был создан явно и явно указана функция валидации: */ if (typeof callback !== "undefined") { return callback(cellValue, this.filters, i); } /* Если в фильтр напихали пробелов, или другой непечатной фигни - удаляем: */ filter.value = filter.value.replace(/^\s+$/g, ""); /* "Фильтр содержит значение и оно совпало со значением ячейки" */ return !filter.value || filter.value == cellValue; } this._setAction = function (anEventName, callback) { for (var i = 0; i < this.filters.length; i += 1) { this.filters[i] = callback; } } };

Фильтр диапазона значений "ОТ" и "ДО"

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

... ... ...
ОТ --- 1 2 3 ДО --- 1 2 3

А в вызове скрипта прописываем фильтр (для третьего столбца) для краткости я сократил листинг оставив только определение фильтра "от" и "до":

FilterTable(/* Ссылка на элемент таблицы */ document.getElementById("target"), /* Объект-конфигурация фильтров: */ { /* Фильтр для первого столбца чекбоксы: */ 0: ... , /* Фильтр для второго столбца текстовое поле - только точное совпадение: */ 1: ... , /* ФИЛЬТР диапазон значений ОТ и ДО */ 2: new filterTable.Filter([ document.getElementById("digits-from"), document.getElementById("digits-to") ], function (value, filters, i) { var accept = true; value = parseInt(value,10) if (filters.value) { accept = (value >= parseInt(filters.value,10)); } if (accept && filters.value) { accept = (value li.gap - работать в сочетании с текстом: justify; Свойство, примененное к.cd-gallery , чтобы создать сетку галереи. Вам нужно создать столько же элементов.gap , сколько и максимальное количество элементов в строке -1.


Content Filter






  • All

  • All

  • Color 1

  • Color 2









No results found




Block title





Close

Filters

Добавление стиля

Большая часть CSS касается стилей элементов формы и других базовых украшений. Интересно, как мы определили и использовали некоторые классы - в сочетании с jQuery - для изменения поведения некоторых элементов на основе определенных событий.

Например: на всех устройствах панель фильтров фиксируется, когда она достигает вершины области просмотра. Для достижения этого эффекта мы использовали класс.is-fixed , примененный к элементу main (.cd-main-content), чтобы мы могли ориентировать некоторые его дочерние элементы. В частности: .cd-tab-filter-wrapper находится в статическом положении, в то время как.cd-filter и.cd-filter-trigger находятся в абсолютном положении (относительно.cd-main-content). Когда мы применяем.is-fixed класс к.cd-main-content , мы переключаем положение всех этих элементов на Fixed.

Cd-tab-filter-wrapper { background-color: #ffffff; z-index: 1; } .cd-filter { position: absolute; top: 0; left: 0; width: 280px; height: 100%; background: #ffffff; z-index: 2; transform: translateX(-100%); transition: transform 0.3s, box-shadow 0.3s; } .cd-filter-trigger { position: absolute; top: 0; left: 0; height: 50px; width: 60px; z-index: 3; } .cd-main-content.is-fixed .cd-tab-filter-wrapper { position: fixed; top: 0; left: 0; width: 100%; } .cd-main-content.is-fixed .cd-filter { position: fixed; height: 100vh; overflow: hidden; } .cd-main-content.is-fixed .cd-filter-trigger { position: fixed; }

Еще одна вещь, о которой стоит упомянуть - это.filter-is-visible класс. Он применяется к нескольким элементам, когда пользователь запускает панель фильтра. На всех устройствах оно используется для изменения значения translateX элемента.cd-filter (от -100% до 0). На больших устройствах (> 1170px) мы также нацеливаем на.cd-gallery и.cd-tab-filter и уменьшаем их ширину: таким образом панель не будет перекрывать контент, а пользователь использует дополнительные возможности Пространство для применения фильтров и просмотра изменений одновременно, без необходимости закрывать панель.

Обработка событий

Для реализации функциональности фильтра содержимого мы интегрировали плагин MixItUp jQuery. Чтобы инициализировать плагин в контейнере галереи, мы используем функцию mixItUp () и объявляем переменную buttonFilter , которая содержит все пользовательские функциональные возможности фильтра. Кроме того, мы используем jQuery для открытия / закрытия панели фильтров и исправления (вместе с навигацией с вкладками), чтобы он все еще отображался при прокрутке галереи.

Мы научились собирать данные на клиенте и отправлять их на сервер. А на сервере написали заглушку в том месте, где должны возвращаться товары, отфильтрованные по введенным параметрам. Сейчас мы избавимся от заглушки и напишем пару методов и запросов, которые вытаскивают из базы нужные товары и возвращают их клиенту. Урок достаточно короткий. Приступаем

Что будем делать?

Нам нужно выполнить всего 3 пункта:

  • 1. Получить данные с клиента и обработать их под нужды сервера. Например, проставить параметры по умолчанию
  • 2. Написать, собственно, сам код для извлечения товаров из базы. В первую очередь, подготовить sql-запрос
  • 3. Вернуть клиенту полученные данные
Получение данных с клиента

Вы можете спросить: для чего нужно выделять эту простую операцию отдельно, если все данные мы легко вытащим из массива $_GET?

Во-первых, для того, чтобы проставить значения по умолчанию. Нельзя полагаться на то, что клиент сам позаботится об этом.

Во-вторых, не все данные находятся в $_GET в пригодном для использования виде. Например, сортировку с клиента нам удобнее передавать одним параметром в виде поле_направление, например, price_asc. Но в sql-запросе это отдельные сущности, поэтому их нужно предварительно обработать.

Похожая ситуация и с брендами. На клиенте мы отправляем их в виде массива brands, и php их получает тоже как массив. Но для sql-запроса нужна строка - список брендов через запятую. Поэтому бренды тоже нужно дополнительно обрабатывать.

Итак, напишем функцию getOptions(), которая вытащит данные из $_GET и преобразует их в удобный нам вид. Почти все вводные я уже сообщил, поэтому сразу смотрим на готовый код.

// Получение данных из массива _GET function getOptions() { // Категория и цены $categoryId = (isset($_GET["category"])) ? (int)$_GET["category"] : 0; $minPrice = (isset($_GET["min_price"])) ? (int)$_GET["min_price"] : 0; $maxPrice = (isset($_GET["max_price"])) ? (int)$_GET["max_price"] : 1000000; // Бренды $brands = (isset($_GET["brands"])) ? implode($_GET["brands"], ",") : null; // Сортировка $sort = (isset($_GET["sort"])) ? $_GET["sort"] : "price_asc"; $sort = explode("_", $sort); $sortBy = $sort; $sortDir = $sort; return array("brands" => $brands, "category_id" => $categoryId, "min_price" => $minPrice, "max_price" => $maxPrice, "sort_by" => $sortBy, "sort_dir" => $sortDir); }

Здесь мы видим, что сначала получаем id категории. Если категория не передана, мы считаем category_id = 0. Минимальная цена будет 0, максимальная - 1 миллион. Если Ваш интернет-магазин продает плутоний (нефть китайцам, муравьев поштучно), то Вы всегда можете добавить нулей в нужную строку или на худой конец вести расчеты в евро.

Сортировку преобразуем по-другому. Отдельно вытаскиваем поле сортировки и параметр: asc или desc.

Обратите внимание, что во всех случаях мы не забываем подставлять значение по умолчанию, если нужный параметр не приехал с клиента. И теперь, когда все данные преобразованы, осталось только вернуть их из функции в ассоциативном массиве через return array(...)

Подготовка sql-запроса и извлечение данных из базы

Все данные подготовлены в нужном нам виде, теперь напишем запрос и выполним его. Этим будет заниматься функция getGoods($options, $conn). В параметрах она принимает $options - данные, подготовленные предыдущей функцией, и $conn - объект подключения к БД, который мы создали в предыдущем уроке . Наша задача - написать sql-запрос. В общем виде он выглядит так:

Select g.id as good_id, g.good as good, b.brand as brand, g.price as price, g.rating as rating, g.photo as photo from goods as g, brands as b where g.category_id = выбранная_категория and g.brand_id in (список_брендов_через_запятую) and g.brand_id = b.id and (g.price between минимальная_цена and максимальная_цена) order by поле_сортировки направление_сортировки

Мы извлекаем нужные поля, применив ряд условий where и указав нужную сортировку. С ценами и сортировкой вопросов нет, просто подставляем в соответствующие места запроса нужные значения. Но с категорией и брендами нужно быть повнимательнее и вот почему.

Каждый товар у нас всегда имеет категорию. Понятия нулевой категории в нашей базе данных нет - мы это сделали для своего же удобства, чтобы понимать, что пользователь в браузере не выбрал никакую категорию (или выбрал все - для нас это одно и то же). И в этом случае мы не должны включать в запрос строчку
g.category_id = выбранная_категория and
То же самое и с брендами, если они не выбраны, то соответствующую строку пропускаем. Вот как это выглядит в коде.

// Получение товаров function getGoods($options, $conn) { // Обязательные параметры $minPrice = $options["min_price"]; $maxPrice = $options["max_price"]; $sortBy = $options["sort_by"]; $sortDir = $options["sort_dir"]; // Необязательные параметры $categoryId = $options["category_id"]; $categoryWhere = ($categoryId !== 0) ? " g.category_id = $categoryId and " : ""; $brands = $options["brands"]; $brandsWhere = ($brands !== null) ? " g.brand_id in ($brands) and " : ""; $query = " select g.id as good_id, g.good as good, b.brand as brand, g.price as price, g.rating as rating, g.photo as photo from goods as g, brands as b where $categoryWhere $brandsWhere g.brand_id = b.id and (g.price between $minPrice and $maxPrice) order by $sortBy $sortDir "; $data = $conn->query($query); return $data->fetch_all(MYSQLI_ASSOC); }

Сначала мы извлекаем из массива $options переменные цен и сортировок - они просто вставляются в запрос без изменений. А для категории и брендов мы формируем строки $categoryWhere и $brandsWhere по принципу: нужное условие для секции where, если данные есть, и пустая строка если данных нет. Таким образом получился достаточно вменяемый sql-запрос, учитывающий все наши пожелания. Две последние строчки выполняют оный запрос и возвращают из функции массив из объектов с нужными полями. Осталось собрать все в кучу и отправить полученные товары обратно уже заждавшемуся клиенту/браузеру.

Возвращаем товары клиенту

Это самая простая часть урока. Посмотрим на заглушку, написанную в предыдущем уроке.

// Подключаемся к базе данных $conn = connectDB(); // Возвращаем клиенту успешный ответ echo json_encode(array("code" => "success", "data" => $_GET));

Заменим этот код на

// Подключаемся к базе данных $conn = connectDB(); // Получаем данные от клиента $options = getOptions(); // Получаем товары $goods = getGoods($options, $conn); // Возвращаем клиенту успешный ответ echo json_encode(array("code" => "success", "options" => $options, "goods" => $goods));

Мы добавили пару строк: функцией getOptions извлекли данные в переменную $options. Тут же использовали ее в получении товаров getGoods, результаты сохранили в $goods. И расширили ответ клиенту. Параметр data переименовали в options и вернули в него не содержимое $_GET, а уже преобразованные значения. И в параметре goods вернули массив полученных товаров.

На этом урок закончен. Пока мы не можем использовать эти данные на клиенте, отрисовать их в браузере - этим мы займемся на следующем уроке. Но всегда можем открыть консоль, потыкать кнопочки и галочки и убедиться, что сервер возвращает нам правильные товары.

Проверяем результаты работы

Выберем категорию Смартфоны и отметим бренды Apple и Samsung. В ответе увидим, что сервер вернул 3 товара, отсортированных по возрастанию цены

Теперь поставим минимальную цену в 20 тысяч и сменим сортировку на убывание цены
Как видно, теперь всего 2 товара - один самсунг отбросился из-за неподходящей по фильтрам цены в 17 тысяч. И отсортированы товары уже наоборот. Если Вы все сделали правильно, то увидите точно такую же картинку.

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

Но еще HTML поддерживает работу с Фильтрами . Применяя различные Фильтры к тексту, можно добиться интересных эффектов. Но будьте осторожны, не все браузеры одинаково отображают эффекты которые должны давать фильтры , некоторые браузеры откровенно игнорируют фильтры. Поэтому тестируйте свои web-странички в различных браузерах. Все Фильтры корректно работают Internet Exhlorer. Итак давайте рассмотрим работу фильтров.

Например мы хотим выделить фразу: "Доброго времени суток!!! " Давайте попробуем поизвращать эту фразу:-) , применяя к ней различные фильтры.

Фильтр Mask.

Выделяет текст, точнее фон на котором написан текст, как будто бы Вы выделили текст мышью.

Синтаксис фильтра: STYLE="filter:Mask(Color="Color")

Color - цвет выделения в шестнадцатиричном виде (напр. #000FFF) или название цвета на английском, например, Red, Blue, Green. Такое определение цвета применяется во всех фильтрах, поэтому дальше это повторяться не будет.

Листинг 19.1.

Фильтр DropShadow.

Добавляет тень к тексту.

Синтаксис фильтра:
STYLE="filter:DropShadow(Color="Color", OffX="Offx", OffY="Offy", Positive="Positive")"

Color - Цвет тени
OffX - Смещение тени по X
OffY - Смещение тени по Y
Positive - Тень слева или справа (0 или 1 соответственно)

Листинг 19.3.

Вот как это смотрится web-странице:

Фильтр FlipV.

Переворачивает текст вертикально.

Синтаксис фильтра: STYLE="filter:FlipV"

Листинг 19.5.

Вот как это смотрится web-странице:

Фильтр Wave.

Делает текст волнистым.

Синтаксис фильтра: STYLE="filter: Wave(Freq="Freq", Add="Add", LightStrength="LightStrength", Phase="Phase", Strength="Strength")"

Freq - колличество волн
Add - показать/скрыть окантовку (1 или 0 соответственно)
LightStrength - сила волн
Phase - угол волн
Strength - интенсивность волн

Листинг 19.7.

Доброго времени суток!!!


Вот как это смотрится web-странице:

Фильтр Blur.

Размывает текст в определенную сторону.

Синтаксис фильтра:
STYLE="filter:Blur(Add="Add", Direction="Direction", Strength="Strength")"

Add - умеренное или сильное размытие (соответственно 1 или 0)
Direction - в какую сторону произойдет размытие (oт 0 до 315)
Strength - смещение размытия

Как использовать

Для начала нужно скачать архив плагина со страницы разработчика и распаковать его в директорию на вашем сайте. Доступны две версии - минимизированная (Production version) и для разработчиков (Development version). В версии для разработчиков текст плагина представлен в структурированном виде с комментариями, что удобно для того, чтобы разобраться в принципе работы (в исходниках к уроку содержится версия плагина для разработчиков с переведенными комментариями).

Затем в секцию страницы, на которой планируется использовать фильтрацию, нужно вставить код подключения плагина:

$(document).ready(function() { $("элемент_для_фильтрации").liveFilter("опция"); });

Нужно заменить “/путь_к_плагину/ ” на путь, где расположен плагин liveFilter , который вы распаковали ранее. Также нужно заменить “элемент_для_фильтрации ” селектором CSS, который соответствует нужному элементу.

Параметр плагина "опция" управляет использованием анимации при скрытии и выводе элементов во время фильтрации. Доступны следующие значения: basic - элементы просто отключаются/включаются без какой-либо анимации, slide - фильтруемые элементы будут сворачиваться/разворачиваться, fade - фильтруемые элементы будут постепенно включаться/выключаться.

Например:

$(ul#filter_me").liveFilter("slide");

Выше приведенный код указывает плагину LiveFilter фильтровать неупорядоченный список с id “filter_me ” и использовать анимацию “slide ”.

Плагин можно использовать для неупорядоченных и упорядоченных списков и таблиц. Нужно указать требуемый селектор при вызове плагина.

Важно! Для работы плагина нужно добавить на страницу поле ввода текста с классом “filter” . Данное поле будет использоваться для ввода текста фильтрации:

Пример страницы с использованием фильтра:

Пример использования плагина LiveFilter $(document).ready(function() { $(ul#filter_me").liveFilter("slide"); });

  • Пункт № 1.
  • Пункт № 2.
  • Пункт № 3.
  • Пункт № 4.
  • Пункт № 5.
  • Пункт № 6.
  • Пункт № 7.
  • Пункт № 8.
  • Пункт № 9.
  • Пункт № 10.

Код плагина

(function($){ $.fn.liveFilter = function (aType) { // Определяем, что будет фильтроваться. var filterTarget = $(this); var child; if ($(this).is("ul")) { child = "li"; } else if ($(this).is("ol")) { child = "li"; } else if ($(this).is("table")) { child = "tbody tr"; } // Определяем переменные var hide; var show; var filter; // Событие для элемента ввода $("input.filter").keyup(function() { // Получаем значение фильтра filter = $(this).val(); // Получаем то, что нужно спрятать, и то, что нужно показать hide = $(filterTarget).find(child + ":not(:Contains("" + filter + ""))"); show = $(filterTarget).find(child + ":Contains("" + filter + "")") // Анимируем пункты, которые нужно спрятать и показать if (aType == "basic") { hide.hide(); show.show(); } else if (aType == "slide") { hide.slideUp(500); show.slideDown(500); } else if (aType == "fade") { hide.fadeOut(400); show.fadeIn(400); } }); // Пользовательское выражение для нечувствительной к регистру текста функции contains() jQuery.expr[":"].Contains = function(a,i,m){ return jQuery(a).text().toLowerCase().indexOf(m.toLowerCase())>=0; }; } })(jQuery);