Два связанных вопроса о фильтрах заголовков столбцов jqGrid и диалоге расширенной фильтрации

При разработке моего первого приложения ASP.NET MVC 3 с использованием jqGrid для отображения некоторых данных я использую фильтры заголовков столбцов, а также позволяю выполнять расширенную фильтрацию на панели инструментов фильтров. Самостоятельно эти вещи работают довольно хорошо.

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

Например, пользователь может фильтровать по столбцу "Имя мороженого", вводя частичное имя, например, "Шоколад", и он будет фильтроваться до "Взрыв шоколада", "Темный шоколад" и т. Д. - отлично. Было бы неплохо открыть расширенный фильтр и автоматически заполнить фильтр столбцов "содержит шоколад" в расширенном фильтре. Я признаю, что другое направление (где кто-то может И или ИЛИ два значения для одного и того же столбца, например, "Шоколад" ИЛИ "Карамель") становится проблематичным, но в другом направлении кажется, что это возможно. Возможно, это просто настройка сетки, которую мне не хватает. Кто-нибудь решил это?

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

2 ответа

Решение

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

Одним из важных, но простых приемов является использование recreateFilter: true, По умолчанию диалог поиска будет создан один раз, а затем будет только скрывать или показывать. В результате postData.filters Параметр не будет обновлен. После настройки recreateFilter: true проблема с заполнением диалогового окна расширенного поиска значениями из панели инструментов поиска будет решена. Я лично установил параметры поиска по умолчанию следующим образом

$.extend(
    $.jgrid.search,
    {
        multipleSearch: true,
        multipleGroup: true,
        recreateFilter: true,
        overlay: 0
    }
);

Теперь более сложной частью решения является функция refreshSerchingToolbar который я написал. Функция не так проста, но она просто используется:

loadComplete: function () {
    refreshSerchingToolbar($(this), 'cn');
}

Последний параметр - это тот же параметр, который вы использовали в качестве defaultSearch свойство метода панели инструментов поиска filterToolbar (значением по умолчанию является "bw", но я лично предпочитаю использовать "cn" и установить параметр jqGrid ignoreCase: true).

Если вы заполните диалоговое окно расширенного поиска демо следующим полем

и нажмите кнопку "Найти", у вас будет следующая сетка:

(Я пометил столбец "Всего" как недоступный для поиска в отношении search: false показать только то, что все правильно работает и в деле)

Видно, что все поля панели инструментов поиска, кроме "Количество", заполнены значениями из диалогового окна поиска. Поле не заполнено, потому что мы использовали операцию "больше или равно" вместо "равно". Функция refreshSerchingToolbar заполняет только те элементы панели поиска, которые могут быть созданы

В качестве напоминания должен упомянуть, что в случае использования панели инструментов фильтра очень важно определить параметры searchoptions.sopt colModel, Для всех нестроковых столбцов, содержащих (даты, числа, select, int, currency), крайне важно иметь 'eq' в качестве первого элемента sopt массив. Смотрите здесь и здесь для деталей.

Если вы измените фильтр расширенного диалога на следующий

вы будете иметь, как ожидалось

В конце я включаю код refreshSerchingToolbar функция:

var getColumnIndex = function (grid, columnIndex) {
        var cm = grid.jqGrid('getGridParam', 'colModel'), i = 0, l = cm.length;
        for (; i < l; i += 1) {
            if ((cm[i].index || cm[i].name) === columnIndex) {
                return i; // return the colModel index
            }
        }
        return -1;
    },
    refreshSerchingToolbar = function ($grid, myDefaultSearch) {
        var postData = $grid.jqGrid('getGridParam', 'postData'), filters, i, l,
            rules, rule, iCol, cm = $grid.jqGrid('getGridParam', 'colModel'),
            cmi, control, tagName;

        for (i = 0, l = cm.length; i < l; i += 1) {
            control = $("#gs_" + $.jgrid.jqID(cm[i].name));
            if (control.length > 0) {
                tagName = control[0].tagName.toUpperCase();
                if (tagName === "SELECT") { // && cmi.stype === "select"
                    control.find("option[value='']")
                        .attr('selected', 'selected');
                } else if (tagName === "INPUT") {
                    control.val('');
                }
            }
        }

        if (typeof (postData.filters) === "string" &&
                typeof ($grid[0].ftoolbar) === "boolean" && $grid[0].ftoolbar) {

            filters = $.parseJSON(postData.filters);
            if (filters && filters.groupOp === "AND" && typeof (filters.groups) === "undefined") {
                // only in case of advance searching without grouping we import filters in the
                // searching toolbar
                rules = filters.rules;
                for (i = 0, l = rules.length; i < l; i += 1) {
                    rule = rules[i];
                    iCol = getColumnIndex($grid, rule.field);
                    cmi = cm[iCol];
                    control = $("#gs_" + $.jgrid.jqID(cmi.name));
                    if (iCol >= 0 && control.length > 0) {
                        tagName = control[0].tagName.toUpperCase();
                        if (((typeof (cmi.searchoptions) === "undefined" ||
                              typeof (cmi.searchoptions.sopt) === "undefined")
                             && rule.op === myDefaultSearch) ||
                                (typeof (cmi.searchoptions) === "object" &&
                                    $.isArray(cmi.searchoptions.sopt) &&
                                    cmi.searchoptions.sopt[0] === rule.op)) {

                            if (tagName === "SELECT") { // && cmi.stype === "select"
                                control.find("option[value='" + $.jgrid.jqID(rule.data) + "']")
                                    .attr('selected', 'selected');
                            } else if (tagName === "INPUT") {
                                control.val(rule.data);
                            }
                        }
                    }
                }
            }
        }
    };

ОБНОВЛЕНО: приведенный выше код больше не нужен в случае использования бесплатной jqGrid 4.13.1 или выше. Содержит новую опцию по умолчанию loadFilterDefaults: true из filterToolbar, который обновляет значения панели инструментов фильтра и операций фильтра (если searchOperators: true вариант filterToolbar ised), если postData.filters а также search: true установлены (фильтр применен). Бесплатная jqGrid обновляет панель инструментов фильтра jqGridAfterLoadComplete (если loadFilterDefaults: true установлены) или если событие jqGridRefreshFilterValues явно сработали.

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

Изменяя это в первом цикле в refreshSearchingToolbar, из

control = $("#gs_" + $.jgrid.jqID(cm[i].name));

в

control = $("#gview_"+$grid.attr('id')+" #gs_" + $.jgrid.jqID(cm[i].name));

и это во втором цикле из

control = $("#gs_" + $.jgrid.jqID(cmi.name));

в

control = $("#gview_"+$grid.attr('id')+" #gs_" + $.jgrid.jqID(cmi.name));

должен сделать свое дело.

Слава Олегу

Другие вопросы по тегам