Почему возникла необходимость в рассматриваемом компоненте?



Для jqgrid существует 4 вcтроенных механизма фильтрации данных

  1. Опция search:true в параметрах футера грида. Выражается в появлении иконки в футере, по нажатию на которую появляется диалог поиска по одному полю. Минусы в том, что поле только одно, используется текстовое поле для задание искомой величины и набор операторов универсален (общий) для всех полей.
  2. Конструкция
    jQuery("#mysearch").filterGrid("#grid_id",{...})

    Она создает на странице в месте элемента “#mysearch” поисковую панель. Набор полей в панели и элементов управления для них статичен и определяется по colModel или по специальной опции filterModel. Минус в статичности панели (пользователь не может менять набор полей) и в том, что поисковые условия посылаются в отдельных post-параметрах, а не в json-массиве. Это плохо ложится на концепцию универсального источника данных (server-side) для грида. Так же используется только один оператор сравниения для всех условий (равно).

  3. Опция multipleSearch:true футера грида. В футере появляется кнопка поиска, по нажатию на которую появляется диалог. В этом диалоге можно добавлять поисковые условия и объединять их всех условием OR или условием AND. Минус данной возможности в том, что как элемент управления для задания значений поиска используется только текстовое поле. Операторы сравления тоже всегда одинаковые.
  4. Поисковый toolbar.
    jQuery("#toolbar").jqGrid('filterToolbar', {stringResult: true});

    Его минус в использовании тестовых полей и постоянного оператора справления (равно). Все условия объединяются одним только общим (AND).

Как мы видим все 4 механизма поиска имеют ряд недостатков. Эти недостатки и призван решить новый компонент smartSearchPanel.

Что представляет собой smartSearchPanel для пользователя?



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

jqgrid filter panel

Каждое поле грида имеет свой элемент управления в панели поиска. Например Date - datepicker, поле Status - select и т.д.

Каждое поле грида в панели поиска имеет свой набор операторов, зависящий от типа поля.

Пользователь может выбирать использовать ли все условия или использовать любое из них (AND/OR) при отборе записей.

Посмотрите видео ролик использования (скачать с зеркала)

Как создать smartSearchPanel для грида?



Подключаем файлы js и css-файлы jquery и jquery ui, затем подключаем
jquery.json-1.3.min.js - Библиотека для формирования json из js-объектов
jqgrid.smart.search.css - Стили для панели поиска
jqgrid.smart.search.js - Код панели поиска

Далее необходимо добавить на страницу место, в котором будет размещена панель поиска.

<div id=”search-form”></div>

Затем надо вызвать функцию иннициализации панели

testGrid.smartSearchPanel('#search-form');

testGrid - это ссылка на грид, а параметр функции - селектор элемента, в котором разместится панель.

Для того, чтобы иметь контроль над тем какие элементы управления будут иметь конкретные поля здесь используется colModel.

Вот например фрагмент colModel для элемента select

{label: 'Status', name:'status', index: 'status', align: 'left', width: 120,
	edittype: 'select', editoptions: {
		value: "new:New Ticket;assigned:Assigned;fixed:Done"} 
}

Ключевые вещи здесь это edittype - тип элемента управления и editoptions - настройки элемента управления.

Как видно используются уже существующие опции полей из colModel. Опция index определяет к какому полю на уровне sql-запроса применять условие. Однако я добавил еще опцию field для тех же целей, если использовать index неудобно.

Для даты пример

{label: 'Date', name:'date', index:'date', width:100, 
	editable: true, formatter: 'date' }

Здесь formatter со значением date говорит о том, что необходимо использовать datepicker как элемент управления. Возможно это не очень согласуется с editoptions (из предыдущего примера), но я старался по максимуму использовать именно существующие опции jqgrid дабы не нарушать идеологию. Если есть другие предложения, то с радостью выслушаю.

По-умолчанию все поля будут иметь текстовое поле в качестве элемента управления. Поэтому лучше указывать edittype там, где это необходимо. Если необходимо запретить поиск по полю, то следует использовать search: false в colModel таким образом:

{ name:'id', index:'index', hidden: true, search: false }

Вот и вся наука. Пример использования на данный момент есть тут.

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

Tags: ,

19 Responses to “Панель настраиваемого поиска для jqGrid”

  1.  Игорь Тельменко Says:

    Добавлена опция для отображения панели поиска в диалоге.

  2.  Scyther Says:

    очень сжато написано, и нельзя ли выложить пример для скачивания? в часности интересует action.php (блок для \"_search:true\")

  3.  Игорь Тельменко Says:

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

  4.  rudenich Says:

    Шикарно
    А скачать это чудо можно только с демо страницы?

  5.  Игорь Тельменко Says:

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

  6.  rudenich Says:

    пришлось подшлифовать код для создания select, у меня значения для selectov объявлены через объекты, если вам интересно куда можно исправления кинуть?

  7.  Игорь Тельменко Says:

    Вопрос. Это что-то дает или просто личные предпочтения?

  8.  rudenich Says:

    Исключительно личные, как то так сложилось что объекты ассоциируются с большей гибкостью, + в проете везде использовались объектные определения select-ов

  9.  Kandr Says:

    Без серверной части это статья не имеет смысла по сути..

  10.  Игорь Тельменко Says:

    Дело в том, что статья об элементе интерфейса, который работает на клиентской стороне. Гораздо более сложной частью в задаче постоения универсального фильтра является именно клиентская часть.
    Серврая часть может выполняться на основе совершенно различных решений. В данном примере используется php-фреймворк Kohana. Скорее всего не всех пользователей устроит этот выбор. Однако писать серверную часть, например, на чистом php - это не то что изобретать велосипед. Это - изобретать множество велосипедов.
    Если вы возьмете любой фреймворк с хорошей поддержкой ORM, то очень быстро поймете, что сможете написать серверную часть в 25 строк совершенно тривиального кода.

  11.  Kandr Says:

    Беда в том, что клиентский интерфейс, описанный в статье не работает с серверной частью, написанною мою под стандартный jqGrid - на выходе пустая таблица, только id выводит (если сделать hidden: true для этого поля)…
    PHP-скрипт формирует и выводит JSON объект. Думаю пример серверной части подойдет на любом фрэймворке (даже на .NET), важно увидеть принцип.

  12.  Игорь Тельменко Says:

    Вот серверная часть. Но она не готова к выкладыванию. Хотя вам поможет.

    Контроллер
    https://web-linux.ru/attaches/smart.txt
    и библиотечный класс, который использует контроллер
    https://web-linux.ru/attaches/GridRequestHander.txt

  13.  Kandr Says:

    Спасибо! Действительно помогло :)

  14.  Maxim Says:

    Доброго времени суток!
    Воспользовался вашим решением - Спасибо!
    Но на данный момент нашел недочет: для формата “select” Ваш плагин понимает опции только типа String, но jqGrid умеет делать и в object. Вот моя заплатка на скорую руку:
    со строки 120 заменить код:

    var valOptions = editOptions.split(';');
    var controlHtml = "";
    for(var i=0; i < valOptions.length; i++) {
    var tmpOpt = valOptions[i].split(’:');
    controlHtml += “”+tmpOpt[1]+”";
    }
    controlHtml += “”;

    на следующий:

    var controlHtmlHead = "";
    var controlHtmlOpt = "";
    var controlHtmlFoot = "";

    if(typeof(editOptions) == 'object'){
    for (var key in editOptions){
    controlHtmlOpt += ""+editOptions[key]+”";
    }
    }else{
    var valOptions = editOptions.split(’;');
    for(var i=0; i < valOptions.length; i++) {
    var tmpOpt = valOptions[i].split(’:');
    controlHtmlOpt += “”+tmpOpt[1]+”";
    }
    }

    var controlHtml = controlHtmlHead + controlHtmlOpt + controlHtmlFoot;

    P.S.: За качество простите, не пишу на JS и делал на скорую руку.

  15.  Игорь Тельменко Says:

    Спасибо! Видимо rudenich о том же говорил, да я неверно понял. Спасибо и ему

  16.  Игорь Тельменко Says:

    Друзья! Не так давно (в апреле) появилась 4я версия jqgrid. В ней уже реализованы похожие возможности. Новый модуль поиска в jqgrid видимо задумывается универсальным. В нем можно строить более сложные условия, осуществлять валидацию и т.п. Демка тут https://www.trirand.com/blog/jqgrid/jqgrid.html в разделе в разделе Searching (4.0) new.

    Возможно на мысли о таком модуле автора jqgrid натолкнул мой пост, возможно нет. Вопрос в другом. Имеет ли смысл развивать smartSearchPanel?
    У меня есть мысли сделать его более человекопонятным чем новый механизм поиска в jqgird. Все-таки последний, я думаю, будет не всегда удобен пользователям в силу своей мудреной древообразной структуры с AND-ами и OR-ами.

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

    Буду ждать отзывов.

  17.  Maxim Says:

    Игорь! Я считаю, что тебе необходимо занять определённую нишу и развивать далее, в области свое, кто ищет возможность создания быстрой фильтрации с минимум затрат, не завися от самой таблицы на странице. Т.е. как для меня: мне необходимо было сделать область поиска для таблицы за её пределами. Ваш плагин скоротал мне время, за что спасибо.

    P.S.: Плагин оочень сырой, нужно дорабатывать и шлефовать под новые возможности JqGrid. Пришлось переписывать плагин, для добавления удобного API.

  18.  Игорь Тельменко Says:

    Вот чем является эта самая ниша я пока не совсем вижу. Пока что 2 недостатка у штатного в глаза бросились.
    1. Не вижу date-пикера для полей с датами при поиске
    2. Уж больно на программера заточен интерфейс с этими эндами и орами и древовидной структурой. Надо, ИМХО, проще интерфейс делать.

    Но обе эти вещи в принципе можно и в штатный новый фильтр добавить вроде.

  19.  Maxim Says:

    Да, интерфейс надо делать лучше :) Интуитивно понятный