• Адаптивный фильтр товаров. Получение данных с клиента

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

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

    Нам нужно выполнить всего 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 - смещение размытия

    Наконец, я нашел время и хочу представить вашему вниманию свой новый скрипт, который позволяет осуществить фильтрацию данных в 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
    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; } } };

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

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

    ... ... ...
    ОТ ДО

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

    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 <= parseInt(filters.value,10)); } return accept; }), /* Фильтр для четвертого столбца радио кнопки: */ 3: ... , /* Фильтр для пятого столбца Постепенный ввод слова: */ 4: ... });

    Примеры фильтров таблиц без учета регистра

    Фильтр не чувствительный к регистру для точного совпадения (можно заменять им стандартный)

    New filterTable.Filter(document.getElementById("text"), function (value, filters, i) { var empty_filter = filters[i].value == "", match_value = value.toLowerCase() == filters[i].value.toLowerCase(); return empty_filter || match_value; })

    Фильтр не чувствительный к регистру для постепенного ввода слова

    New filterTable.Filter(document.getElementById("regexp"), /* Коллбэк ф-ция валидации */ function (value, filters, i) { var c_value = value.toLowerCase(), f_value = filters[i].value.toLowerCase(); return c_value.indexOf(f_value) === 0; }, /* Будем вызывать валидацию по событию onkeyup фильтра */ "onkeyup")

    В принципе не чувствительность к регистру можно встроить и в сам скрипт фильтра, но пока нет времени думаю в будущем переписать этот скрипт с учетом всех ваших пожеланий тогда и сделаем эту фичу там. Как говорится: оставайтесь с нами;)

    Хорошо спроектированный фильтр - это мощный инструмент, которым могут воспользоваться пользователи. На самом деле это важная функция, если на вашем сайте (интернет-магазине) есть много товара, распределенного по разным категориям.

    ИСХОДНИКИ

    Для электронной коммерции это способ повысить коэффициент конверсии за счет сокращения времени, необходимого пользователю, чтобы найти то, что он ищет.

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

    Он использует преимущества CSS Transitions, CSS Transformations и jQuery для плавного перехода в случае необходимости.

    Создание структуры

    Структура HTML немного сложнее, чем обычно. Прежде всего, есть два основных блока контента: элементы header и main , второй используется для обертывания как галереи.cd-gallery , так и фильтра.cd-filter . В дополнение к этому у нас есть вкладная навигация (вложенная в 2 div элемента, из-за эффекта выпадающего эффекта, видимого на мобильных устройствах) и триггер фильтра.cd-filter-trigger .

    Вы также можете заметить множество имен классов (например, в элементах списка галереи) и фильтры данных: они используются для фильтрации содержимого, а не для стилизации.

    Примечание. Назначение элемента.cd-gallery> 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 для открытия / закрытия панели фильтров и исправления (вместе с навигацией с вкладками), чтобы он все еще отображался при прокрутке галереи.

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

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

    Но все же в CSS-фильтрах имеется один небольшой недостаток – не все веб-браузеры поддерживают визуальные эффекты. Разумеется, это лишь вопрос времени. И к наступлению часа «х» разработчикам нужно быть готовым. А пока рассмотрим то, что на данный момент уже реализовано.

    Поддержка CSS фильтров браузерами

    В основном все ходовые браузеры, Firefox, Chrome, Opera, имеют «дружеское» отношение с фильтр-эффектами. Чего не скажешь о IE, который напрочь отказывается поддерживать эффекты, даже в самых поздних версиях.

    Браузер Explorer Chrome Firefox Safari Opera Android iOS
    Версия no 31+ 35+ 7+ 18+ 4.4+ 6+
    filter (-webkit-) + (-webkit-) (-webkit-) (-webkit-) (-webkit-)

    Функции и синтаксис CSS фильтров

    Во всех свойствах CSS имеются некие параметры, сочетающие в себе порядок прописывания значений. Свойство filter не является исключением, как и другие, оно может использовать комбинацию нескольких правил в одном применении. К примеру, добавить фильтр яркости для изображения, а через пробел указать еще один — контрастность. Мы рассмотрим все в этой статье с несколькими примерами для лучшего понимания.

    Синтаксис

    Filter: название фильтра (процент значения) ; filter: url(img.svg); filter: blur(10px); filter: brightness(0.9); filter: contrast(150%); filter: drop-shadow(5px 5px 10px black); filter: grayscale(80%); filter: hue-rotate(60deg); filter: invert(80%); filter: opacity(50%); filter: saturate(50%); filter: sepia(40%); /* Применение нескольких фильтров */ filter: contrast(150%) grayscale (80%);

    Список фильтров

    Фильтр Описание
    blur (px) Фильтр для размытия изображения. Степень размытия указывается в пикселях. Если число не задано, то по умолчанию используется 0.
    drop-shadow () Тень. Альтернатива свойству box-shadow с аналогичными параметрами и тем же порядком прописывания. Исключением является четвертое значение «растяжение»: почти все браузеры его не поддерживают.
    grayscale (%) Фильтр «обесцветить». Применяются оттенки серого цвета к изображению в зависимости от указанного процента. Не допускается отрицательное значение, а оригинальность картинки равна 0.
    brightness (%) Настройка яркости изображения. Значение в 100% показывает исходную точку яркости. Регулировка совершается как отрицательно (-50%), так и положительно (150%).
    contrast (%) Настройка контрастности изображения. Как и в предыдущем фильтре, значение в 100% покажет исходную точку. Изменения можно задавать отрицательные (-20%) и положительные (120%).
    hue-rotate (deg) Поворотное наложение тона цвета. В зависимости от указанного градуса (от 0deg до 360deg) на изображение будет налаживается цвет, который определяется по цветовому кругу.
    invert (%) Инверсия изображения. Применяется значение от 0 до 100% без отрицательного параметра.
    saturate (%) Насыщенность изображения. Исходное положение определяется в 100% и не имеет отрицательного значения.
    sepia (%) Эффект сепия. Оригинальность картинки определяется в 0% и доступна до значения 100% без отрицания.
    opacity (%) Прозрачность картинки. Еще один фильтр, у которого есть аналогичное свойство opacity с таким же способам в использовании. Настройка допускается от 0 до 100% без отрицательного параметра.
    url () CSS ссылка на SVG элемент с определенным идентификатором #id.
    initial Устанавливает значение свойства по умолчанию.
    inherit Наследует все значения свойства своего родительского элемента.

    Примеры CSS filters

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

    Фильтр размытия

    В графических редакторах фильтр размытия является незаменимым инструментом и часто применяемым в работе. Он способен непросто создавать расплывчатое изображение, а делать эффект фокусирования на определенном элементе при этом остальная часть изображения попадает под размытие. И многое другое.

    В оформлении сайта (к примеру – размытие) можно использовать как подкладку для лучшей читаемости текста, расположенного на картинке. Собственно, размытие совершается по гауссу от значения 0 px и до полного исчезновения.

    Оригинал

    Фильтр

    Hover-эффект

    /*статичное правило*/ .efbl1 img{ filter: blur(2px); -webkit-filter: blur(2px); } /*для hover-эффекта*/ .efbl2 img{ transition: all 0.6s ease 0s; } .efbl2:hover img{ filter: blur(4px); -webkit-filter: blur(4px); transition: all 0.6s ease 0s; }

    Фильтр тень

    Свойство тень пришло к нам еще с третьей версией каскадной таблицы. Безусловно, оно знакомо всем, кто занимается сайтостроением, так как box-shadow в дизайне играет далеко не последнюю роль. Фильтр drop-shadow можно назвать неполноценной альтернативой с аналогичными параметрами, а их всего 5, не считая внутреннюю тень.

    Порядок прописывания такой: 5px/-5px (смещение по горизонтали), 5px/-5px (смещение по вертикали), 15px (радиус размытия тени), 5px/-5px (растягивание тени), black (цвет). Фильтр поддерживает весь синтаксис кроме растягивания и значения inset (внутренняя тень), а также добавления нескольких теней через запятую. Но несмотря на все это, присутствуют свои достоинства, к примеру, фильтр учитывает псевдоэлементы, что позволяет отображать точную форму тени элемента.

    Также интересным является то, что когда у блока нет фона, а лишь задана обводка border , то при использовании box-shadow будет отображаться тень с якобы учетом фона, то есть сплошная. А в случае использования drop-shadow тень принимает форму обводки без учета фона.

    Оригинал

    Фильтр

    Hover-эффект

    /*статичное правило*/ .efdrswd1 img{ filter: drop-shadow(6px 7px 3px rgba(0, 0, 0, 0.4)); -webkit-filter: drop-shadow(6px 7px 3px rgba(0, 0, 0, 0.4)); } /*для hover-эффекта*/ .efdrswd2 img{ transition: all 0.6s ease 0s; } .efdrswd2:hover img{ filter: drop-shadow(6px 7px 3px rgba(0, 0, 0, 0.4)); -webkit-filter: drop-shadow(6px 7px 3px rgba(0, 0, 0, 0.4)); transition: all 0.6s ease 0s; }

    Фильтр обесцвечивания

    Классический стиль фотографии для всех времен в правильном направлении. Фильтр допускает лишь одно значение — положительное. В зависимости от указанного процента оттенки серого будут плавно заменять цвет изображения. Также вместо процентов можно применять дробь до целого числа (0.01/1).

    Оригинал

    Фильтр

    Hover-эффект

    /*статичное правило*/ .efgrays1 img{ filter: grayscale(90%); -webkit-filter: grayscale(90%); } /*для hover-эффекта*/ .efgrays2 img{ transition: all 0.6s ease 0s; } .efgrays2:hover img{ filter: grayscale(90%); -webkit-filter: grayscale(90%); transition: all 0.6s ease 0s; }

    Фильтр яркости

    Добавление света к «неизведанным» черным углам изображения. В обработке фотографий применяется нередко, так как любительские снимки, как правило, совершаются в плохо освещенных местах. Яркость фильтра регулируется от 0% (полностью черная картинка) до почти полного исчезновения изображения. Оригинальная точка определяется в 100%, а значение также можно указывать дробью.

    Оригинал

    Фильтр

    Hover-эффект

    /*статичное правило*/ .efbrig1 img{ filter: brightness(150%); -webkit-filter: brightness(150%); } /*для hover-эффекта*/ .efbrig2 img{ transition: all 0.6s ease 0s; } .efbrig2:hover img{ filter: brightness(150%); -webkit-filter: brightness(150%); transition: all 0.6s ease 0s; }

    Фильтр контрастности

    Нехитрый способ сделать изображение более выразительным, поэкспериментировав с настройками яркости самых светлых и темных частей картинки. Фильтр contrast готов этому помочь. Его параметры, как и у многих, исключают отрицательное значение (-150%), а исходное положение обозначается в 100%. Кроме процентов, допускается также дробь (1.5).

    Оригинал

    Фильтр

    Hover-эффект

    /*статичное правило*/ .efcontr1 img{ filter: contrast(150%); -webkit-filter: contrast(150%); } /*для hover-эффекта*/ .efcontr2 img{ transition: all 0.6s ease 0s; } .efcontr2:hover img{ filter: contrast(150%); -webkit-filter: contrast(150%); transition: all 0.6s ease 0s; }

    Фильтр тона цвета

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

    Если значение указано положительное (150deg), то поворот происходит по часовой стрелке. Соответственно, если отрицательное, то против часовой. В двух положения начинается от 0deg до 360deg.

    Оригинал

    Фильтр

    Hover-эффект

    /*статичное правило*/ .efhrotai1 img{ filter: hue-rotate(180deg); -webkit-filter: hue-rotate(180deg); } /*для hover-эффекта*/ .efhrotai2 img{ transition: all 0.6s ease 0s; } .efhrotai2:hover img{ filter: hue-rotate(180deg); -webkit-filter: hue-rotate(180deg); transition: all 0.6s ease 0s; }

    Фильтр инверсия

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

    Оригинал

    Фильтр

    Hover-эффект

    /*статичное правило*/ .efinve1 img{ filter: invert(100%); -webkit-filter: invert(100%); } /*для hover-эффекта*/ .efinve2 img{ transition: all 0.6s ease 0s; } .efinve2:hover img{ filter: invert(100%); -webkit-filter: invert(100%); transition: all 0.6s ease 0s; }

    Фильтр насыщенность

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

    Оригинал

    Фильтр

    Hover-эффект

    /*статичное правило*/ .efsatut1 img{ filter: saturate(165%); -webkit-filter: saturate(165%); } /*для hover-эффекта*/ .efsatut2 img{ transition: all 0.6s ease 0s; } .efsatut2:hover img{ filter: saturate(165%); -webkit-filter: saturate(165%); transition: all 0.6s ease 0s; }

    Фильтр сепия

    Имитация эффекта старинных фотографий (слегка коричневый оттенок). Таким образом достигается ретро стиль изображения, который пользуется особой популярностью. Фильтр сепия регулируется от 0% (исходное положение) до 100%.

    Оригинал

    Фильтр

    Hover-эффект

    /*статичное правило*/ .efsepiaa1 img{ filter: sepia(100%); -webkit-filter: sepia(100%); } /*для hover-эффекта*/ .efsepiaa2 img{ transition: all 0.6s ease 0s; } .efsepiaa2:hover img{ filter: sepia(100%); -webkit-filter: sepia(100%); transition: all 0.6s ease 0s; }

    Фильтр прозрачность

    Фильтр аналогичный свойству opacity из каскадной таблицы 3-й версии. Синтаксис такой же, а значение прозрачности регулируется от 0% до 100% (исходное положение).

    Оригинал

    Фильтр

    Hover-эффект

    /*статичное правило*/ .efopaty1 img{ filter: opacity(50%); -webkit-filter: opacity(50%); } /*для hover-эффекта*/ .efopaty2 img{ transition: all 0.6s ease 0s; } .efopaty2:hover img{ filter: opacity(50%); -webkit-filter: opacity(50%); transition: all 0.6s ease 0s; }

    Фильтр ссылка

    Создается собственный фильтр на основе SVG элементов с определенным идентификатором, который впоследствии можно используется в CSS через фильтр ссылку. Эффекты могут очень сильно отличаться от стандартных фильтров начиная от маски-наложения до банальной прозрачности.

    Генератор CSS filters

    Уже давно повелось создавать генераторы различных CSS свойств. , и многое-многое другое. Они служат как инструмент, упрощающий работу. А для начинающих вебмастеров могут нести двойную пользу. Ими очень легко пользоваться: перемещаете ползунки, и сразу же виден результат. А по окончании остается лишь скопировать сгенерированный код. То же и с генераторами CSS фильтров. Вот два из них для ознакомления:

    Заключение

    Обзор получился весьма немаленький, но надеюсь, что кому-то пригодится на практике. Также не забывайте комбинировать фильтры, один – хорошо, а два будет лучше, в определенных случаях.