Kendo grid dataSource.filter all columns - kendo-ui

I have a kendogrid where I want to search three columns from a input field. The logic below will only search one of the columns is there another flag I need to add for it to search all three columns
$('#filter').on('input', function (e) {
var grids = $(".k-grid");
for (var j = 0; j < grids.length; j++) {
var grid = $(grids[j]);
var griddata = $(grid).data('kendoGrid');
griddata.dataSource.filter(
{ field: "Name", operator: "contains", value: e.target.value },
{ field: "Date", operator: "contains", value: e.target.value },
{ field: "Type", operator: "contains", value: e.target.value });
}
});

If you need to use more than one filter, pass them in as an array. You can also set or change the logic.
griddata.dataSource.filter({
logic: "or",
filters:
[
{ field: "Name", operator: "contains", value: e.target.value },
{ field: "Date", operator: "contains", value: e.target.value },
{ field: "Type", operator: "contains", value: e.target.value }
]});

Related

Multiple sort on Kendo Grid columns / DataSource - set sorting dynamically

What I'm trying to accomplish is to apply an "automatic" secondary column sort when a user sorts a column in a kendo grid.
So in this JS fiddle example, if a user sorts by "Value", it'll also sort by "Name". Note that the 0s are sorted together, but the names aren't alphabetical. I'd like them to be alphabetical (the secondary sort).
Here's an attempt at overriding the datasource sorting to accomplish this. I'm taking the user's original sort and the adding an additional sort on "SortedName". Based on the sorting array that's logged, it seems to be close but is still not working.
Any other ideas on how to accomplish this?
Note: I don't want to allow users to sort by multiple columns. The real world example I'm using this for can have up to 50+ columns (unfortunately), so multiple sort can get confusing / unintuitive. And I'd like it to be done behind the scenes without extra user interaction.
Example code for overriding kendo datasource sort():
dataSource.originalSort = dataSource.sort;
dataSource.sort = function () {
// take the user's sort and apply sorting on an additional column
// the sort array should look like this:
[
{ field: "Value", dir: "asc" }, // this is what the user sorted by
{ field: "SortedName", dir: "asc" }, // and I'm adding this
]
return dataSource.originalSort.apply(this, arguments);
}
Please try with the below code snippet.
<div id="grid">
</div>
<script>
var dataSource = new kendo.data.DataSource({
data: [
{ Name: "Lisa", Value: 1 },
{ Name: "Dan", Value: 12 },
{ Name: "Ken", Value: 5 },
{ Name: "Arthur", Value: 15 },
{ Name: "Bob", Value: 0 },
{ Name: "Sally", Value: 0 },
{ Name: "Alexis", Value: 0 },
{ Name: "Cody", Value: 0 },
{ Name: "Steve", Value: 0 },
{ Name: "Andrew", Value: 0 },
{ Name: "Duke", Value: 0 }
],
schema: {
model: {
fields: {
Name: { type: "string" },
Value: { type: "number" }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
dataBound: function (e) {
var isSortedByName = false;
var grid = $("#grid").data("kendoGrid");
var ds = grid.dataSource;
var sort = ds.sort();
if (sort) {
for (var i = 0; i < sort.length; i++) {
if (sort[i].field == "Name") {
isSortedByName = true;
}
}
if (isSortedByName == false) {
sort.push({ field: "Name", dir: "asc" });
ds.sort(sort);
}
}
},
columns: [
{ field: "Name" },
{ field: "Value" }
],
sortable: true
});
</script>

Kendo MultiSelect: Search on multiple fields

I'm working with kendo Multiselect and I would like to find a way to search in multiple fields of my data source.
Here is my actual code. but it works only for one field:
`
$scope.dataList = new kendo.data.DataSource({
data:[{id: "1",name: "Doe, John",email: "John.Doe#example.com"}],
});
$scope.customOption = {
dataSource: $scope.dataList,
dataTextField: "name",
dataValueField: "id",
filter: "contains",
itemTemplate: '<span>#=id#</span>#=name#<i> #=email#</i>',
}
`
As you see I'm also using AngularJS, I try to search for names and emails.
$("#id").kendoMultiSelect({
placeholder: "Select products...",
dataTextField: "name",
dataValueField: "id",
autoBind: false,
filtering: function (e) {
if (e.filter) {
var value = e.filter.value
var newFilter = {
filters: [
{ field: "id", operator: "contains", value: value },
{ field: "name", operator: "contains", value: value },
{ field: "email", operator: "contains", value: value }
],
logic: "or"
}
e.sender.dataSource.filter(newFilter)
e.preventDefault()
}
e.preventDefault()
},
dataSource: {
data:[
{id: "1",name: "Doe, John",email: "John.Doe#example.com"},
{id: "2",name: "sss, John",email: "sss.Doe#example.com"},
{id: "3",name: "fff, John",email: "fff.Doe#example.com"},
{id: "4",name: "ccc, John",email: "ccc.Doe#example.com"}
],
},
value: [
{id: "1",name: "Doe, John"},
]
});
Refer to API Documentation of Kendo DataSource and MultiSelect. hope it helps.

Javascript Filterable option not working for Kendo Grid?

So I have this unusual situation, where 3 of the Filter options display information correctly, but the fourth one doesn't? and im not sure why. also, on the bottom right, where the total # of rows displays, it will display as "Nan - 2" or "Nan - 8", instead of "1-8 - 8"
The option that doesn't work is Case 1.
Here is the code:
function changeProcessedItemFilter() {
var val = $("#processedItemFilter").prop("value");
var grid = $("#PLAGridMain").getKendoGrid();
var parsedValue = parseInt(val);
var approveBtn = $("#Approve").data("kendoButton");
var updateBtn = $("#Update").data("kendoButton");
switch(parsedValue)
{
case 0:
break;
case 1: //filter New Data only. Unprocessed/ UnSent.
approveBtn.enable(true);
updateBtn.enable(false);
grid.dataSource.query({
filter: [{ field: "Processed", operator: "eq", value: false }, { field: "Sent", operator: "eq", value: false }]
});
break;
case 2: //filter Processed/ Unsent Records.
approveBtn.enable(false);
updateBtn.enable(true);
grid.dataSource.query({
filter: [{ field: "Processed", operator: "eq", value: true }, { field: "Sent", operator: "eq", value: false }]
});
break;
case 3:// Filter GMCC Records. UnProcessed/Sent.
approveBtn.enable(true);
updateBtn.enable(true);
grid.dataSource.query({
filter: [{ field: "Processed", operator: "eq", value: false }, { field: "Sent", operator: "eq", value: true }]
});
break;
case 4:// Filter Updated Records. Processed/Sent.
approveBtn.enable(false);
updateBtn.enable(true);
grid.dataSource.query({
filter: [{ field: "Processed", operator: "eq", value: true }, { field: "Sent", operator: "eq", value: true }]
});
break;
}
}

Filter of Kendo UI Grid is not executed for specified column

Here is my MVC view code :-
<div id="reportsDb">
<div id="grid"></div>
<script type="text/x-kendo-template" id="template">
<div class="toolbar" id="template" >
<label class="Status-label" for="Status">Show reports by status:</label>
<input type="search" id="Status" style="width: 150px"/>
</div>
</script>
<script>
$(document).ready(function () {
var path = ""
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "#Url.Action("Report_Read", "Report")",
dataType: "json",
type: "Get",
contentType: "application/json"
}
},
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 10,
schema: {
model: {
id: "RequestId",
fields: {
IPAddress: { type: "string" },
RequestQuetime: { type: "date" },
RequestPicktime: { type: "date" },
RequestRespondTime: { type: "date" },
StatusType: { type: "string" },
RequestTimeDifference: { type: "datetime", format: "{0:hh:mm:ss}" },
RequestPickDifference: { type: "datetime", format: "{0:hh:mm:ss}" }
}
}
}
});
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
sortable: true,
pageable: true,
filterable: {
extra: false,
operators: {
string: {
startswith: "Starts with",
eq: "Is equal to",
neq: "Is not equal to"
}
}
},
toolbar: kendo.template($("#template").html()),
height: 430,
columns: [
{ field: "IPAddress", title: "IP address", width: 100, filterable: true },
{ field: "RequestQuetime", title: "Que time", width: 100, filterable: false },
{ field: "RequestPicktime", title: "Pick time", width: 110, filterable: false },
{ field: "RequestRespondTime", title: "Respond time", width: 100, filterable: false },
{ field: "StatusType", title: "status", width: 110, filterable: { ui: statusFilter } },
{ field: "RequestTimeDifference", title: "Time difference", width: 110, filterable: false },
{ field: "RequestPickDifference", title: "Pick difference", width: 110, filterable: false }
]
});
function statusFilter(element) {
element.kendoDropDownList({
dataSource: {
transport: {
read: {
url: "#Url.Action("RequestStatus_Read", "Report")",
dataType: "json",
type: "Get",
contentType: "application/json"
}
}
},
dataTextField: "Text",
dataValueField: "Value",
optionLabel: "--Select Value--"
});
}
});
</script>
</div>
And below is the Action Method of controller :-
public ActionResult Report_Read()
{
return Json(_oRepository.GetReports().ToList(), JsonRequestBehavior.AllowGet);
}
I want to apply filtering on StatusType filed and for that I have bound this filed with dropdownlist.
And my problem is when I am trying to do filtering by selecting one of the status from download its doing nothing.
I am working according to this example:
http://demos.telerik.com/kendo-ui/grid/filter-menu-customization
From your code, everything seems fine except the Controller Read Action. Now if the controller is being called when you apply filter from the view on Grid then the only change required on your side is below:
public JsonResult Report_Read([DataSourceRequest] DataSourceRequest request)
{
return Json(_oRepository.GetReports().ToList().ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
EDIT:
If you don't use Kendo.MVC then you have two option to filtering:
Option 1: Client side filtering
-> You will need to get all the data at read time so when the filtering is applied you have all the data, which is best option if the data source is not large as it saves unwanted controller requests for filtering.
-> First think you need do is subscirbe to filterMenuInit() of grid and add the below Script for client side filtering.
Code:
filterMenuInit: function(e) {
if (e.field == "name") {
alert("apply Filter");
var filter = []
... // Generate filters
grid.dataSource.filter(filters);
}
}
For detailed example: Extact from Kendo Examples
Option 2: Server side filtering
-> I don't have much idea about it, but whilst I was searching for my options to filtering I had came across the below Question which was good but a bit complex for my application. But I think you can use it.
JS Fiddle Sample
Please refer below Link for detailed explanation.
Reference: JS Kendo UI Grid Options
Check your rendered html for string you have in td and string you are filtering
Look if your td has any other code than the string you are trying to filter. If the case is there is some other html code inside td like a span or a div, then you have to refactor your code to make sure you have content only in td.
Make sure you trim your string inside td.
Try contains instead of equal to. if this works them the issue should be extran text/html or triming.
function applyFilter() {
var filters = [], item_filters = [], brand_filters = [], invoice_id = null;
var item_nested_filter = { logic: 'or', filters: item_filters };
var brand_nested_filter = { logic: 'or', filters: brand_filters };
var gridData = $("#invoicelistgrid").data("kendoGrid");
var invoiceId = $("#invoiceidsearch").data("kendoDropDownList").value();
var itemId = $("#itemsearch").data("kendoDropDownList").value();
var brandId = $("#brandsearch").data("kendoDropDownList").value();
var partyId = $("#party-dropdown").data("kendoDropDownList").value();
if (partyId !== "") {
filters.push({ field: "party_id", operator: "eq", value: parseInt(partyId) });
}
if (invoiceId !== "") {
filters.push({ field: "invoice_id", operator: "eq", value: parseInt(invoiceId) });
}
if (itemId !== "") {
for (var i = 0; i < gridData.dataSource._data.length; i++) {
var data = gridData.dataSource._data[i].tb_invoice_lines;
for (var j = 0; j < data.length; j++) {
if (parseInt(itemId) === parseInt(data[j].item_id)) {
item_filters.push({ field: "invoice_id", operator: "eq", value: parseInt(data[j].invoice_id) });
} else {
invoice_id = data[j].invoice_id;
}
}
}
if (item_filters.length > 0) {
filters.push(item_nested_filter);
} else {
filters.push({ field: "invoice_id", operator: "eq", value: parseInt(invoice_id) });
}
}
if (brandId !== "") {
for (var k = 0; k < gridData.dataSource._data.length; k++) {
var brand_data = gridData.dataSource._data[k].tb_invoice_lines;
for (var l = 0; l < brand_data.length; l++) {
console.log("Grid item id = " + brand_data[l].brand_id);
if (parseInt(brandId) === parseInt(brand_data[l].brand_id)) {
brand_filters.push({
field: "invoice_id",
operator: "eq",
value: parseInt(brand_data[l].invoice_id)
});
} else {
invoice_id = brand_data[l].invoice_id;
}
}
}
if (brand_filters.length > 0) {
filters.push(brand_nested_filter);
} else {
filters.push({ field: "invoice_id", operator: "eq", value: parseInt(invoice_id) });
}
}
console.log(filters);
gridData.dataSource.filter({
logic: "and",
filters: filters
});
}

Multiple Filter on kendogrid not working

I'm trying to put 2 filters on kendo grid with 'OR' logic.
It's not working. I need the grid to be filtered with the both the dropdowns.
If in Foo dropdown 'foo1' is selected and in Bar dropdown 'All' selected, then the grid should be displaying
foo bar
1 1
1 2
Code below:
$(function() {
var grid=$("#grid").kendoGrid({
dataSource: {
data: [
{ foo: "1", bar: "1" },{ foo: "1", bar: "2" },
{ foo: "2", bar: "2" },{ foo: "2", bar: "1" },
{ foo: "3", bar: "3" },{ foo: "3", bar: "2" }
]
},
columns: [
"foo","bar"
],
toolbar: kendo.template($("#template").html())
});
grid.find("#foo").kendoDropDownList({
dataTextField: "name",
dataValueField: "id",
autoBind: false,
optionLabel: "All",
dataSource: [{id:'1', name:'foo1'}, {id:'2', name:'foo2'},{id:'3', name:'foo3'}],
change: function () {
var ds = $("#grid").data("kendoGrid").dataSource;
var filter = {
logic: "and",
filters: []
};
if (this.value()) {
filter.filters.push([{ field: "bar", operator: "eq", value:
$("#bar").data('kendoDropDownList').value() },
{ field: "foo", operator: "eq", value: $("#foo").data('kendoDropDownList').value() }
]);
}
ds.filter([filter]);
}
});
grid.find("#bar").kendoDropDownList({
dataTextField: "name",
dataValueField: "id",
autoBind: false,
optionLabel: "All",
dataSource: [{id:'1', name:'bar1'}, {id:'2', name:'bar2'},{id:'3', name:'bar3'}],
change: function () {
var ds = $("#grid").data("kendoGrid").dataSource;
var filter = {
logic: "and",
filters: []
};
if (this.value()) {
filter.filters.push([{ field: "bar", operator: "eq", value:
$("#bar").data('kendoDropDownList').value() },
{ field: "foo", operator: "eq", value: $("#foo").data('kendoDropDownList').value() }
]);
}
ds.filter([filter]);
}
});
});
After pushing the filters to the filter array the grid datasource is not filtered.
Updated jsbin below:
http://jsbin.com/izuloj/23/edit
There are couple of problems:
The argument for DataSource filters is an array but you are pushing an array when you do:
filter.filters.push([
{ field: "bar", operator: "eq", value: $("#bar").data('kendoDropDownList').value() },
{ field: "foo", operator: "eq", value: $("#foo").data('kendoDropDownList').value() }
]);
Comparing with empty is not the same that not adding the condition. So you should actually do:
// If there is some value in "bar" we add a condition for filtering it
if ($("#bar").data('kendoDropDownList').value()) {
filter.filters.push({
field: "bar",
operator: "eq",
value: $("#bar").data('kendoDropDownList').value() }
);
}
// If there is some value in "foo" we add a condition for filtering it
if ($("#foo").data('kendoDropDownList').value()) {
filter.filters.push(
{
field: "foo",
operator: "eq",
value: $("#foo").data('kendoDropDownList').value() }
);
}
Finally, you should not set any filter if both drop down inputs are empty but in that case you cannot send an empty filter array, you should do ds.filter({})) instead.
So your change function ends being:
function onChange () {
var ds = $("#grid").data("kendoGrid").dataSource;
var filtering = false;
var filter = {
logic: "and",
filters: []
};
if ($("#bar").data('kendoDropDownList').value()) {
filtering = true;
filter.filters.push(
{ field: "bar", operator: "eq", value: $("#bar").data('kendoDropDownList').value() }
);
}
if ($("#foo").data('kendoDropDownList').value()) {
filtering = true;
filter.filters.push(
{ field: "foo", operator: "eq", value: $("#foo").data('kendoDropDownList').value() }
);
}
if (filtering) {
ds.filter([filter]);
} else {
ds.filter({});
}
}
Your code modified here : http://jsbin.com/izuloj/31/edit
Instead of
var filter = {
logic: "and",
filters: []
};
if (this.value()) {
filter.filters.push([{ field: "bar", operator: "eq", value:
$("#bar").data('kendoDropDownList').value() },
{ field: "foo", operator: "eq", value: $("#foo").data('kendoDropDownList').value() }
]);
}
ds.filter([filter]);
Doing below works....easy to read
if ( $("#foo").data('kendoDropDownList').value() === "")
{
ds.filter( { field: "bar", operator: "eq", value: $("#bar").data('kendoDropDownList').value()});
}
else
{
ds.filter({
logic: "and",
filters: [{ field: "foo", operator: "eq", value: $("#foo").data('kendoDropDownList').value() },{ field: "bar", operator: "eq", value: $("#bar").data('kendoDropDownList').value() }]
});
}
Remove the square brackets on ds.filter([filter]); so that it becomes ds.filter(filter);.

Resources