ASP.NET MVC: jqGrid и поиск

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

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

Плагин jqGrid предлагает несколько возможностей реализовать поиск:

  1. Toolbar searching;
  2. Custom searching;
  3. Single searching;
  4. Advanced searching.

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

Для этого достаточно в представлении Product\Index.aspx добавить строчку:

$('#ProductTable').jqGrid('filterToolbar');

 
        jQuery(document).ready(function () {
            jQuery('#ProductTable').jqGrid({
                url: '/Product/ProductData',
                datatype: "json",
                mtype: 'POST',
                jsonReader: {
                    page: "page",
                    total: "total",
                    records: "records",
                    root: "rows",
                    repeatitems: false,
                    id: ""
                },
                colNames: ['Id', 'Наименование', 'Категория', 'Поставщик', 'Цена', 'Количество на складе', 'Английское наименование'],
                colModel: [
                { name: 'ProductId', width: 20 },
                { name: 'ProductName', width: 150 },
                { name: 'Category', width: 100 },
                { name: 'Supplier', width: 200 },
                { name: 'UnitPrice', width: 100 },
                { name: 'UnitsInStock', width: 100 },
                { name: 'EnglishName', width: 200 }
                ],
                pager: '#ProductTablePager',
                viewrecords: true,
                height: 500
            });

            $('#ProductTable').jqGrid('filterToolbar');
        });
        
    

После этого небольшого изменения, у таблицы появляется тулбар с возможностью делать поиск по каждому полю. Для отключения поиска по определенному полю необходимо в colModel для нужной колонки указать свойство search: false. Детальнее об этом можно почитать в документации. Теперь таблица будет выглядеть следующим образом:

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

 
        public JsonResult ProductData(int? page, bool _search, int? productId,
            string productName, string category, string supplier,
            int? unitPrice, int? unitsInStock, string englishName)
        {
            var list = _repository.GetProducts();

            // флаг установлен в случае наличия значений в фильтре
            if (_search)
            {
                if (null != productId)
                    list = list.Where(x => productId ==  x.ProductId);

                if (!String.IsNullOrEmpty(productName))
                    list = list.Where(x => productName == x.ProductName);

                if (!String.IsNullOrEmpty(category))
                    list = list.Where(x => category == x.Category);

                if (!String.IsNullOrEmpty(supplier))
                    list = list.Where(x => supplier == x.Supplier);

                if (null != unitPrice)
                    list = list.Where(x => x.UnitPrice == unitPrice);

                if (null != unitsInStock)
                    list = list.Where(x => x.UnitsInStock == unitsInStock);

                if (!String.IsNullOrEmpty(englishName))
                    list = list.Where(x => x.EnglishName == englishName);
            }

            // постраничная выборка данных 
            var data = list
                        .Skip((page - 1 ?? 0) * PageSize)
                        .Take(PageSize)
                        .ToList();

            // формирование ответа в формате JSON
            var result = new JsonResult
                             {
                                 Data = new
                                 {
                                     page,
                                     total = Math.Ceiling((double)list.Count() / PageSize),
                                     records = list.Count(),
                                     rows = data
                                 }
                             };

            return result;
        }

А вот и результаты поиска по полю Категория

Готово.
Исходники итогового проекта.

Метод ProductData можно немного соптимизировать, опишу это в следующий раз.

  • ilfat

    Преимущества IQueryable налицо — фильтр на стороне сервера.
    Задача посложнее: как создать динамический фильтр сложных объектов (Product.Supplier.City == …)
    Приятно встретить знакомых в просторах интернета …

  • Аноним

    Про динамический фильтр мысль еще не созрела, но по этой теме собираюсь написать продолжение.