jqGrid: использование нескольких методов для фильтрации данных - PullRequest
9 голосов
/ 20 октября 2010

Мое требование - показать страницу с несколькими фильтрами для применения к данным сетки.

Предположим, мы говорим о заказах, а заказ имеет следующие атрибуты

public class Order {
    public int OrderID
    public DateTime OrderDate
    public DateTime ShipmentDate
    public int OrderTotal
    public int OrderStatus
}

Внутри jqgridобъект Я показываю все атрибуты , кроме OrderStatus

Требуется создать представление, которое имеет

  • jqGrid в левой части
  • панель справа

Внутри правой панели пользователь увидит список флажков, представляющих все возможные значения OrderStatus, и он захочет выполнить поиск, используя оба метода (например, установив флажок "Отправлено"Заказы », а затем фильтруем сетку с суммой, превышающей значение)

Я уже настроил расширенную фильтрацию (multiplesearch:true) внутри объекта jqGrid, и я могу создавать сложные фильтры, объединяющие поля и логические операторы.

Есть идеи о том, как я могу подать даже данные с правой панели, когда пользователь нажимает кнопку поиска?

Обновление 1 :

Преамбула: Образец Олега фантастический, но, к сожалению, не соответствует требованиям моего клиента: (

@ Олег: Я не понимаюпочему вы думаете, что:

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

Возможно, мое описание было не таким ясным, но я не собираюсь показывать детали заказа.Чтобы лучше уточнить мои требования, я изменил ваш образец, чтобы показать вам желаемый конечный интерфейс, как показано на следующем рисунке: UI as teh customer want it

Клиент хочет отфильтровать данные в сетке, используя два метода или оба вместе:

  • Использование multiplesearch средств, предоставляемых самой сеткой (спасибо за упоминание обходного пути)
  • Использование настраиваемой панели поиска (с флажками справа)

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

Подводя итог, я должен:

  • Добавить состояние флажков при отправке сообщения через нативный multiplesearch
  • Добавить текущее состояние multiplesearch (еслилюбой) когда пользователь нажимает на флажок

Есть ли способ сделать это?

Ответы [ 2 ]

18 голосов
/ 20 октября 2010

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

Чтобы иметь возможность поместить много флажков в таблицу без постоянной горизонтальной прокрутки, я повернул заголовки столбцов, имеющих "флажок сТехника описана в Вертикальный текст внутри заголовков таблиц с использованием библиотеки SVG на основе JavaScript . Это вращение выглядит не идеально в IE, но в других браузерах оно работает идеально.

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

Поскольку использование хочет использовать multiplesearch:true, я должен упомянуть об ошибке в jQuery.clone , которые следуют за ошибкой в ​​мульти-поиске jqGrid во всех версиях браузеров IE. Если вы определите более одного поискового фильтра, будет использован только первый, потому что поле операции всех других фильтров будетчитать как undefined. Жаль, но ошибка также не исправлена ​​в только что опубликованной jQuery 1.4.3.возможность использовать multiplesearch:true вы можете использовать обходной путь Jiho Han на форуме trirand.com .

Все вместе вы можете увидеть в демонстрационном примере , который производитсетка

alt text

, где можно искать несколько полей

alt text

Соответствующий код:

var myData = [
    { orderID: "10", orderDate: "2010-09-18", shipmentDate: "2010-09-20", orderStatus: "2" },
    { orderID: "15", orderDate: "2010-09-20", shipmentDate: "2010-09-24", orderStatus: "3" },
    { orderID: "20", orderDate: "2010-10-16", shipmentDate: "2010-10-17", orderStatus: "1" }
];
// decode 'orderStatus' column and add additional boolean data based on the bitmap mask
for (var i=0, l=myData.length; i<l; i++) {
    var myRow = myData[i];
    var orderStatus = parseInt(myRow.orderStatus, 10);
    myRow.airPost = (orderStatus & 2) != 0? "1": "0";
    myRow.heavy = (orderStatus & 1) != 0? "1": "0";
}
var grid = jQuery('#list');
grid.jqGrid({
    data: myData,
    datatype: 'local',
    caption: 'Order Details',
    height: 'auto',
    gridview: true,
    rownumbers: true,
    viewrecords: true,
    pager: '#pager',
    rownumbers: true,
    colNames: ['Order ID', 'Order', 'Shipment', 'Air-Post', 'Heavy', 'RowVersion'],
    colModel: [
        { name: 'orderID', index: 'orderID', key:true, width: 120, sorttype: 'int' },
        { name: 'orderDate', index: 'orderDate', width: 180,
          sorttype: 'date', formatter: 'date' },
        { name: 'shipmentDate', index: 'shipmentDate', width: 180,
          sorttype: 'date', formatter: 'date' },
        { name: 'airPost', width: 21, index: 'airPost', formatter: 'checkbox', align: 'center',
          editoptions: { value: "1:0" }, stype: 'select', searchoptions: { value: "1:Yes;0:No" } },
        { name: 'heavy', width: 21, index: 'heavy', formatter: 'checkbox', align: 'center',
          editoptions: { value: "1:0" }, stype: "select", searchoptions: { value: "1:Yes;0:No" } },
        { name: 'orderStatus', index: 'orderStatus', width: 50, hidden: true }
    ]
}).jqGrid ('navGrid', '#pager', { edit: false, add: false, del: false, refresh: true, view: false },
            {},{},{},{multipleSearch:true})
  .jqGrid ('navButtonAdd', '#pager', { caption: "", buttonicon: "ui-icon-calculator", title: "choose columns",
      onClickButton: function() {
          grid.jqGrid('columnChooser');
      }
  });

где rotateCheckboxColumnHeaders и исправление в расширенном поиске, определенное так:

// we use workaround from http://www.trirand.com/blog/?page_id=393/bugs/in-multiple-search-second-and-subsequent-ops-are-sent-as-undefined-in-ie6/
// to fix the bug in the jQuery.clone (see http://bugs.jquery.com/ticket/6793 and
// dscussion on the http://api.jquery.com/clone/
jQuery.event.special.click = {
    setup: function() {
        if (jQuery(this).hasClass("ui-search")) {
            jQuery(this).bind("click", jQuery.event.special.click.handler);
        }
        return false;
    },
    teardown: function() {
        jQuery(this).unbind("click", jQuery.event.special.click.handler);
        return false;
    },
    handler: function(event) {
        jQuery(".ui-searchFilter td.ops select").attr("name", "op");
    }
};
var rotateCheckboxColumnHeaders = function (grid, headerHeight) {
    // we use grid as context (if one have more as one table on tnhe page)
    var trHead = jQuery("thead:first tr", grid.hdiv);
    var cm = grid.getGridParam("colModel");
    jQuery("thead:first tr th").height(headerHeight);
    headerHeight = jQuery("thead:first tr th").height();

    for (var iCol = 0; iCol < cm.length; iCol++) {
        var cmi = cm[iCol];
        if (cmi.formatter === 'checkbox') {
            // we must set width of column header div BEFOR adding class "rotate" to
            // prevent text cutting based on the current column width
            var headDiv = jQuery("th:eq(" + iCol + ") div", trHead);
            headDiv.width(headerHeight).addClass("rotate");
            if (!jQuery.browser.msie) {
                if (jQuery.browser.mozilla) {
                    headDiv.css("left", (cmi.width - headerHeight) / 2 + 3).css("bottom", 7);
                }
                else {
                    headDiv.css("left", (cmi.width - headerHeight) / 2);
                }
            }
            else {
                var ieVer = jQuery.browser.version.substr(0, 3);
                // Internet Explorer
                if (ieVer !== "6.0" && ieVer !== "7.0") {
                    jQuery("span", headDiv).css("left", 0);
                    headDiv.css("left", cmi.width / 2 - 4).css("bottom", headerHeight / 2);
                }
                else {
                    headDiv.css("left", 3);
                }
                headDiv.parent().css("zoom",1);
            }
        }
    }
};

Если вы предпочитаете держать флажки за пределами сетки, вы можете выполнить декодирование битовой маски OrderStatus внутри onSelectRow обработчик событий.

ОБНОВЛЕНО : Я действительно что-то неправильно понял в начале.Посмотрите на модифицированный пример .Теперь это выглядит как alt text

и ближе к тому, что вам нужно.

0 голосов
/ 24 октября 2010

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

Этот метод предполагает использование параметра postData в jqGrid. Внутри метода я определил различные функции, которые проверяют текущее состояние флажков и отправляют параметр на сервер, где его можно использовать для фильтрации.

Это образец

postData: {
    pending: function () {
        if ($("#cb_pending").is(':checked')) {
            return true;
        } else {
            return false;
        }
    }
}

Преимущество этого решения по сравнению с изображенным Олегом состоит в том, что можно использовать смешанные логические операторы (И / ИЛИ) на стороне сервера, а в разделе фильтров - как в ответе Олег это невозможно.

Удачного кодирования!

...