Как определить фильтр столбцов сетки кендо между двумя датами?
в нашем приложении мы хотим, чтобы фильтр в столбце даты запрашивал у пользователя дату начала и дату окончания, а фильтр возвращал строки, где рассматриваемое поле находится между (Или На) этими двумя датами.
Первоначальный Подход
наш первоначальный подход состоял в том, чтобы ограничить типы дат для использования операторов gte и lte и добавить опцию "extra : true" в столбце. Это было близко, но представило следующие проблемы: A) каждый ввод даты может использовать либо оператор gte (Start) или LTE (End), обеспечивая нежелательную гибкость и возможность для пользователя создать фильтр, который никогда не вернет результаты, и Б) представил логическое сравнение (и / или), которое мы не хотим.
Лучше
этот вопрос имеет ответ Мэтью Эрвина, который приближает нас: он позволяет нам полностью изменить стиль фильтра полностью, поэтому мы можем представить просто ввод даты начала и Ввод даты окончания. Однако я не могу работать, связывая правильную операцию фильтра с правильным входом (gte для даты начала, lte для даты окончания). Мой пользовательский фильтр выглядит следующим образом:
$scope.dateFilter = {
extra: true,
operators: {},
ui: function (element) {
var parent = element.parent();
while (parent.children().length > 1)
$(parent.children()[0]).remove();
parent.prepend(
"Start Date:<br/><span class="k-widget k-datepicker k-header">" +
"<span class="k-picker-wrap k-state-default">" +
"<input data-bind="value: filters[0].value" class="k-input" type="text" data-role="datepicker"" +
" style="width: 100%" role="textbox" aria-haspopup="true" aria-expanded="false" aria-disabled="false" " +
" aria-readonly="false" aria-label="Choose a date">" +
"<span unselectable="on" class="k-select" role="button">" +
"<span unselectable="on" class="k-icon k-i-calendar">select</span></span></span></span>" +
"<br/>End Date:<br/>" +
"<span class="k-widget k-datepicker k-header"><span class="k-picker-wrap k-state-default">" +
"<input data-bind="value: filters[1].value" class="k-input" type="text" data-role="datepicker"" +
" style="width: 100%" role="textbox" aria-haspopup="true" aria-expanded="false" " +
" aria-disabled="false" aria-readonly="false" aria-label="Choose a date">" +
"<span unselectable="on" class="k-select" role="button">" +
"<span unselectable="on" class="k-icon k-i-calendar">select</span></span></span></span>"
);
}
};
при таком подходе опция фильтра Odata генерируется для каждой из дат, однако она использует эквалайзер, равный оператору, поэтому значения никогда не возвращаются. Мы не создаем фильтры специально для источника данных.
есть ли простой способ связать каждый из эти входные данные даты с конкретным оператором фильтра? Есть ли лучший способ подойти к этому вопросу? Похоже, что обычно желательно фильтровать даты на основе диапазона начала и конца.
Другие Подробности
мы используем AngularJS и WebAPI с Odata.
2 ответов
после работы с Telerik, я пришел к ответу. Нить, которую я открыл, может быть найти здесь, но я также подытожу в этом ответе.
конечным решением было:
- используйте опцию" сообщения "в столбце" фильтруемое", чтобы настроить отображаемое сообщение фильтра.
- используйте опцию " Extra "столбца" filterable", чтобы получить дополнительный селектор даты в меню фильтра.
- настройки Опция "операторы" в опции фильтрации сетки, чтобы установить, какие операторы могут использоваться для дат (gte, lte) и какой текст отображается для каждого (дата начала, Дата окончания).
- используйте событие filterMenuInit для настройки элементов управления фильтра.
Конечный Результат
Фильтрация
использовались следующие фильтруемые параметры:
filterable: { "extra": "true", "messages": { "info": "Show items between dates:" }}
Экстра дает нам второе выбор даты и сообщение "информация" настраивают текст, отображаемый в верхней части меню фильтра.
Решетки Фильтрующийся
я использовал опцию "операторы "в опции" filterable " на уровне сетки, чтобы фильтры даты предоставляли только операторы gte и lte и настраивали текст для этих операторов. Вот как выглядит объект конфигурации операторов:
"date": {
"gte": "Begin Date",
"lte": "End Date"
}
потому что мы хотим, чтобы это применялось ко всем датам, мы ставим это на заводе и повторно использовать его в каждом угловом контроллере / представлении.
filterMenuInit событие
предоставляя обработчик для события filterMenuInit, можно получить доступ и настроить отдельные элементы управления в меню фильтр по мере его создания. Функция обработчика, которую я создал, выглядит так:
function (e) {
if (e.sender.dataSource.options.schema.model.fields[e.field].type == "date") {
var beginOperator = e.container.find("[data-role=dropdownlist]:eq(0)").data("kendoDropDownList");
beginOperator.value("gte");
beginOperator.trigger("change");
beginOperator.readonly();
var logicOperator = e.container.find("[data-role=dropdownlist]:eq(1)").data("kendoDropDownList");
logicOperator.readonly();
var endOperator = e.container.find("[data-role=dropdownlist]:eq(2)").data("kendoDropDownList");
endOperator.value("lte");
endOperator.trigger("change");
beginOperator.readonly();
}
в частности, для любого поля даты эта функция устанавливает первые и последние выпадающие операторы в "gte" и "lte" с уважением (это выпадающие списки для первого оператора даты и второго оператора даты) и устанавливает все выпадающие списки только для чтения, чтобы пользователь не мог их изменить (единственный другой раскрывающийся список, который находится в индексе 1, является логическим сравнением и имеет смысл, поэтому мы не позволяем пользователям изменять его.)
эта функция применяет данную конфигурацию для любых полей типа "дата". Я сделал это таким образом, чтобы я мог создать эту функцию один раз, поместить ее в угловую фабрику, а затем повторно использовать ее для любой сетки, которая Я нуждался. Если вы не хотите применять это как общую конфигурацию для всех столбцов даты, вы можете изменить условие для проверки полей по имени. Пример:
if (e.field == "fieldName")
надеюсь это будет полезно кому-то еще. Это не дает вам конечной настройки пользовательского интерфейса в меню фильтра, но это позволяет вам просто настроить фильтр между двумя датами. Я уверен, что кто-то умный может объединить это с моей оригинальной стратегией (замена разметки для меню фильтра полностью), чтобы придумать что-то полностью настроенное.
вы можете попробовать следующий метод, который дает два варианта фильтрации: с двумя полями фильтрации и с колонной сетке.
<div>
From: <input id="from" /> To: <input id="to" />
<br />
<br />
<button id="filter" class="k-button">Filter</button>
</div>
<br />
<br />
<div id="grid"></div>
<script>
var grid = $("#grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: "/Controller/Action"
},
pageSize: 10,
schema: {
model: {
fields: {
OrderId: { type: 'number' },
OrderItem: { type: 'string' },
OrderDate: { type: 'date' }
}
}
}
},
pageable: true,
filterable: true,
navigatable: true,
selectable: true,
columns:
[
{ field: "OrderID", width: 100, title: "Order ID", filterable: false },
{ field: "OrderItem", width: 100, title: "Order Item", filterable: false },
{
field: "OrderDate", type: "date", width: 125, title: "Order Date",
template: "#= kendo.toString(kendo.parseDate(EventTime, 'dd.MM.yyyy hh:mm tt'), 'dd.MM.yyyy hh:mm tt') #",
filterable: {
ui: "datetimepicker"
}
},
]
}).data("kendoGrid");
$("#from, #to").kendoDatePicker({
});
$("#filter").on("click", function () {
//var from = $("#from").data("kendoDatePicker").value();
//var to = $("#to").data("kendoDatePicker").value();
//If there is a problem regarding to the two lines above, you can also try this:
var from = $("#from").val();
var to = $("#to").val();
var filter = [
{ field: "OrderDate", operator: "gte", value: from },
{ field: "OrderDate", operator: "lte", value: to }
];
grid.dataSource.filter(filter);
});
</script>
Для получения дополнительной информации фильтрация диапазона дат в сетке кендо с использованием веб-API и Entity Framework.