Custom Filtering

2 Answers 7497 Views
Data Source
Andrés
Top achievements
Rank 1
Andrés asked on 28 Mar 2012, 08:41 PM
Hi guys, congrats on the Q1 release, it's really awesome!
Anyway, I was working on something and it occurred to me that It would be cool if there was a new option for implementing custom filtering (only available for local fitlering). Something such as:

var dataSource=...;
var filterValues=[1,5,7];
dataSource.filter({
  operator: "custom",
  value: function(item) {
    return (filterValues.indexOf(item.property) == -1);
  }
});


or maybe just pass the function to the filter such as dataSource.filter(function(item) {...})
I hope you consider this for a future release.

Thanks,
Andrés
Stephen
Top achievements
Rank 1
commented on 01 May 2012, 09:54 PM

I too would really appreciate custom filtering, though I require it for remote binding. For me, it would be great to just be able to specify something like:

dataSource.filters = [{
text: "Adheres to this custom filter",
operator: "custom"
}, {
text: "Adheres to another custom filter",
operator: "custom2"
}]

where "text" specifies the option that is displayed in, for instance, a grid column filter. Then I could just override a parameterMap or read function to handle the server-side filtering. It would be even better if I could specify filters on a column-by-column basis for a grid.
IT-Consol
Top achievements
Rank 1
commented on 16 May 2014, 05:53 AM

Hi there,

I'm just trying to add a custom filter to my grid, where I can iterate through a list of items and search for a matching element.
So "MessageContents" is a List in my object which is bound to my grid. It has a title and a body and I want to search for it. This is my code:
gridFilters.push({
     field: "MessageContents",
     operator: function (item, value) {
          //iterate through my list "MessageContents" and ask if item.title or item.body contains term
     },
     value: term
 });
IT-Consol
Top achievements
Rank 1
commented on 16 May 2014, 05:57 AM

addition:

When I do so (as you can see in my last post) I always run into this exception:
Kendo.Mvc.Infrastructure.Implementation.FilterParserException "Expected token".

What am I doing wrong? Or is it not possible to search through a list in my filter?

Thank you!
Alexander Valchev
Telerik team
commented on 16 May 2014, 08:01 AM

Hello Daniel,

Since you are working with the MVC wrappers I believe that you are using server side filtering. Using custom filter operator makes sense only for client side filtering.
In your case the filtering happens on the server so you should use custom binding and implement the filtering logic in the controller. Please check the following help article as it explains how to configure custom binding:
In the offline MVC examples project you can also find a custom binding demo which demonstrates the approach in action.

Regards,
Alexander Valchev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
IT-Consol
Top achievements
Rank 1
commented on 21 May 2014, 10:23 AM

Hello Alexander,

thanks for your reply - I managed to do a server side custom filtering. My next problem is grouping. I can't find a proper solution on the site you provided.
What I need is to be able to group my elements in the grid AND also do lazy loading (IQueryable, ToDataSourceResult,...). I already tried a couple of things, but I didn't come up with a solution.
If I have one property to group by, I do so on serverside like ".GroupBy(x=> x.MessageCategory)" but then I run into this error:
"Invalid property or field - "MessageCategory" for type: IGrouping`2"

If I do "request.Groups.Clear()" afterwards, I do get a sqlexception, because I cannot select x columns but only group by one.

So is there any possibility to do a grouping serverside, with lazy loading?

Thank You!
Alexander Valchev
Telerik team
commented on 21 May 2014, 12:51 PM

Hi Daniel,

I would like to remind you that as a general practice it is accepted to ask different questions in separate support threads. In this way it is much easier to follow and concentrate on the particular issue which usually leads to its faster resolving.
Since the second question you asked is not directly related to the initial subject of this thread I kindly ask you to submit a new support ticket for it. We will appreciate if you provide the needed details in it (sample/code) so we can understand/reproduce the issue and assist you.
Thank you in advance for the understanding.

Regards,
Alexander Valchev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Nathan
Top achievements
Rank 1
commented on 03 Nov 2014, 07:20 PM

I know this is an old thread so I'm wondering if its still possible to pass a function as the operator as mentioned in a previous post.

When I use 'eq' as the operator my application works fine, however when trying to use a function like below it fails:

dataSource.filter({
    field: "FieldName",
    operator: function(item, value){
        //implement your logic
    },

I've also traced the Kendo logic (Kendo.web.js) and noticed a function called "normalizeOperator" which fails when the operator is not a string. 

Any suggestions?




Nathan
Top achievements
Rank 1
commented on 04 Nov 2014, 10:12 PM

Is it still possible to pass a function to the "Operator"? I'm using the latest version of Kendo UI and haven't been able to get a simple test working. As I traced through the kendo js, I found a "normalizeOperator" function that seemed to require a string. Thanks.
Alexander Valchev
Telerik team
commented on 06 Nov 2014, 01:27 PM

Hi Nathan,

You should be able to use the custom compare operator. Could you please provide a small but runnable page that demonstrates the issue so I can examine your current implementation?

Regards,
Alexander Valchev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
cluengas
Top achievements
Rank 2
commented on 05 Feb 2015, 02:21 AM

Hi Nathan,
Probably you already solved this, but I ran into this problem yesterday and came up with a "solution"/workaround:

The code looks like this:

01.dataSource.filter(
02.  {
03.    //logic operator to apply the filters: "and" or "or"
04.    logic:"and",
05.    filters:[
06.      {
07.        field:"theFieldToBeFiltered",
08.         
09.        operator:function(){
10.          //first parameter comes form the field to be filtered,
11.          //the rest comes from the "exploded" array
12.          var theArrayOfValues,fieldValue;
13.          theArrayOfValues=[].slice.call(arguments);
14.          //the array of values, once shifted contains the original values ...
15.          //and :) is an Array
16.          fieldValue= theArrayOfValues.shift();
17.          return a.indexOf((v*1))>=0;
18.        },
19.        //this array will be converted to a string and each element
20.        //will become a parameter on the custom "operator" function
21.        //any object will become [object Object]
22.        value:[0,1,2,3,4,5,6,7,8]
23.      },
24.      {
25.        field:"theFieldToBeFiltered2",
26.        operator:function(){
27.          //same thing as above, just short handed
28.          var a=[].slice.call(arguments),v= a.shift();
29.          return a.indexOf((v*1))>=0;
30.        },
31.        value:[3,4,5,9]
32.      }
33.    ]
34.  }
35.);
36.//let's see what we got
37.console.log(dataSource.view());
Scott
Top achievements
Rank 1
commented on 02 Mar 2015, 11:08 PM

I realize this is an old post, but I'm having trouble with passing an operator function as well and couldn't find much else on the subject. Using the simplest example I can think of, I get a similar error to what I'm getting in my own application.

What I'm trying to do is get the equivalent of an 'in' operator working on an array value. There are a number of examples of similar implementations on the forums but they all rely on being able to pass a function to the operator parameter, which I've been unable to make happen. Was this feature disabled at some point?
Andrés
Top achievements
Rank 1
commented on 03 Mar 2015, 12:10 AM

I think the problem is that you should pass "filters" instead of "filter".
Check out the modified example.
Also, it can be an array of objects like that one instead of just one, ie filters: [{field:"name", ...}, {field:"anotherfield", ...}]

Hope it helps!
Scott
Top achievements
Rank 1
commented on 03 Mar 2015, 03:54 PM

I've actually made some progress on this, still having issues with the way Kendo is compiling the filters and keeping track of my variable scope. However, the immediate solution to getting Kendo to recognize an operator function was to also make the value a function. See my updated sample here.

Andrés
Top achievements
Rank 1
commented on 03 Mar 2015, 04:35 PM

Sorry about my previous reply... note to self: don't reply late at night! It really was "filter", so disregard that part please.

Anyway, couple of points:
If you're specifying an operator function, you don't really need to pass "value", you could totally just access whatever variable you had your values in from the function itself.
Also, in case you need to filter on more than just a single column, you can skip the "field" setting and you'll get the full object.

So, taking those 2 into account, your whole filter could be something like:

filter: {
    operator: function(item) {
      return (item.name.indexOf(val)>=0);
    }
  }


Of course, if you do want to specify the value right there, the function technique definitely works.

Cheers

Siva
Top achievements
Rank 1
commented on 20 Apr 2015, 10:39 PM

Hi Alexander,

Is it possible to customize/specify filters for boolean type?  I tried using boolean:{ } in operators but it doesn't work.  

I would like to specify something like the follow:

filterable: {
                    extra: false,
                    operators: {
                        string: {
                            contains: "Contains",
                            doesnotcontain: "Does Not Contain"
                        },
                        number: {
                            eq: "Is equal to"
                        },
                        date: {
                            eq: "Is equal to",
                            neq: "Is not equal to"
                        },
                        boolean: {
                            isTrue: 'True',
                            isFalse: 'False',
                           otherOption:'Other Option'
                        }
                    }
                }

Thank you.

venky
Top achievements
Rank 1
commented on 04 Oct 2017, 06:52 AM

am unable to filter field values Page wise ..if am filtering on any page it is giving me first page results only ..is kendo supports filterable according to page wise???
Alex Hajigeorgieva
Telerik team
commented on 06 Oct 2017, 09:53 AM

Hello, Venky,

The Kendo UI Data Source filters all the items which it contains - you can see them with the data() method.

If the grid has enabled serverPaging, then the data of the dataSource is the current set of dataItems which the remote server has returned. If you wish to filter on the client, then remove the server operations:

For more information, check this section of our documentation:

https://docs.telerik.com/kendo-ui/framework/datasource/overview#mixed-data-operations-mode

Kind Regards,
Alex Hajigeorgieva
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
venky
Top achievements
Rank 1
commented on 06 Oct 2017, 10:04 AM

Thanks for the response AlexHajigeorgieva,

But server Paging is not working .I given server Paging=true .I don't know where am wrong in the code ..once check and help me .

here is my code

$("#orderitems-grid").kendoGrid({
        dataSource: {
            type: "json",
            transport: {
                read: {
                    url: "@Html.Raw(Url.Action("OrderItemsList", "Seller"))",
                    type: "POST",
                    dataType: "json"
                },
                update: {
                    url: "@Html.Raw(Url.Action("UpdateOrderItem", "Seller"))",
                    type: "POST",
                    dataType: "json"
                }
            },
            schema: {
                data: "Data",
                total: "Total",
                errors: "Errors",
                model: {
                    id:"Id",
                    fields: {
                        ProductName: { editable: false,type:"string"},
                        AttributesXml:{ editable:false },
                        SubOrderNumber: { editable: false, type: "number"},
                        PriceInclTax: {editable: false},
                        UnitPriceInclTax: {editable: false},
                        Quantity: {editable: false},
                        SubTotalInclTaxValue: {editable: false},
                        DiscountAmountInclTax: { editable: false },
                        SellerName: { editable: false},
                        OrderItemStatusId: { editable: true },
                        SellerRegisteredCompanyName: { editable: false,type:"string" }
                    }
                }
            },
            requestEnd: function (e) {
                if (e.type == "create" || e.type == "update") {
                    this.read();
                }
                if(e.type=="update" && e.response!="")
                {
                    alert(e.response);
                }
            },
            error: function (e) {
                display_kendoui_grid_error(e);
                // Cancel the changes
                this.cancelChanges();
            },
            pageSize: 25,
            serverPaging: true,
            serverFiltering: true,
            serverSorting: true
        },
        pageable: {
            refresh: true,
            pageSizes: [50, 100, 150, 200],
            buttonCount: 10
        },
        sortable: true,
        resizable: true,
        editable: {
            confirmation: false,
            mode: "inline"
        },
        filterable: true,
        scrollable: false,
        columns: [{
            field: "ProductName",
            title: "Product Name",
            template: '<a href ="@Url.Content("~/Product/Edit/#=ProductId#")">#=ProductName#</a>',
            width: 300
        }, {
            field: "AttributesXml",
            title: "Attributes",
            encoded: false,
            filterable: false,
            width: 150
        }, {
            field: "SubOrderNumber",
            title: "SubOrder No",
            width: 115,
            template: "<a href=\"\" onclick=\"window.open('/Order/GetOrderItemNotes/#=Id#','WindowOrderItemNote','align=center'); return false;\">#=SubOrderNumber#</a>",
        }, {
            field: "UnitPriceInclTax",
            title: "UnitPrice Incl Tax",
            width: 110,
            filterable: false,
            template: '<span style="font-weight:bold;color:\\#0000CD">₹&nbsp;#:UnitPriceInclTax #</span>'
        }, {
            field: "Quantity",
            title: "Qty",
            width: 75,
            filterable: false,
        }, {
            field: "SubTotalInclTaxValue",
            title: "Sub Total",
            width: 100,
            filterable: false,
            template: '<span style="font-weight:bold;color:\\#0000CD">₹&nbsp;#:SubTotalInclTaxValue #</span>'
        },{
            field: "DiscountAmountInclTax",
            title: "Discount",
            width: 100,
            filterable: false,
            template: '<span style="font-weight:bold;color:\\#0000CD">₹&nbsp;#:DiscountAmountInclTax #</span>'
        },{
            field: "PriceInclTax",
            title: "Price Incl Tax",
            width: 110,
            filterable: false,
            template: '<span style="font-weight:bold;color:\\#0000CD">₹&nbsp;#:PriceInclTax #</span>'
        }, {
            field: "SellerRegisteredCompanyName",
            title: "Company Name",
            template: '<a href="Edit/#=SellerId#">#=SellerRegisteredCompanyName#</a>',
            width: 200
        }, {
            field: "OrderItemStatusId",
            title: "Status",
            editor: OrderItemStatusDropDownEditor,
            template: "#=OrderItemStatus#",
            filterable: false,
            width: 250
        }, {
            command: ["edit"],
            title: "Action",
            filterable: false,
            width: 100
        }],

});

The above code is supporting only for client side filtering if i made Server Paging=false..But I want to work on server side filtering ..??

Alex Hajigeorgieva
Telerik team
commented on 11 Oct 2017, 06:30 AM

Hi Venkatesh,

Thank you for the provided Kendo UI Grid configuration.

When the server operations are set to true, the Kendo UI data source will send a request to the remote with the desired sort, filter and page. It is the responsibility of the server to go through the database, match the requested set and return it along with the total number of records. 

If you wish to perform the filtering, sorting and paging on the client, remove the below settings and return the entire data set:

serverPaging: true,
serverFiltering: true,
serverSorting: true

Finally, mixed operations are not recommended. If you prefer to have server filtering, then perform the sorting, paging and grouping on the server too.

Kind Regards,
Alex Hajigeorgieva
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Danny
Top achievements
Rank 1
Iron
Veteran
Iron
commented on 23 Nov 2020, 04:19 PM

Hi Alex.

a query with the Filter, I have the following filter in a DataSource and it works very well, but when there are accents it doesn't work, so my question would be what additional field or how to apply the filter when the "Name" Field contains data with accents?

 dataSourceMenu.filter({ field: "Nombre", operator: "contains", value: $("#txtBuscarMenu").val() });

 

thanks, best regards.

Georgi
Telerik team
commented on 26 Nov 2020, 10:17 AM

Hello Danny,

As of 2019 R2 the Kendo DataSource supports diacritic characters filtering. For further information, please refer to the following article:

 

Regards,
Georgi
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

2 Answers, 1 is accepted

Sort by
0
Alexander Valchev
Telerik team
answered on 03 May 2012, 01:44 PM
Hello guys,

The dataSource has a filter method that allows you to perform custom data filtering. The method works both with client and server filtering.

@Stephen
It is possible to specify filters on a column basis through the column configuration options. Here is the syntax:
columns: [{
    field: "BirthDate",
    filterable: {
        extra: true,
        operators: {
        //specify filters according to the field type - string, date, number
            date: {
                eq: "Equal to",
                neq: "Not equal to",
                gte: "Is after or equal to",
                gt: "Is after",
                lte: "Is before or equal to",
                lt: "Is before"
            }
        }                   
    }
}]

I hope this functionality will fit in your case.

Kind regards,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Andrés
Top achievements
Rank 1
commented on 03 May 2012, 02:29 PM

Hi Alexander
As far as the documentation shows, there's no way to do "customized" filtering. Only the standard filters are available, such as eq, gt, lt, etc....
What I'm talking about is allowing that same filter function to take a custom function containing calculations that determine if the row is filtered in or out.

Cheers,
Andrés
Alexander Valchev
Telerik team
commented on 08 May 2012, 11:36 AM

Hello Andres,

Indeed the filter operation could be a function:
dataSource.filter({
    field: "FieldName",
    operator: function(item, value){
        //implement your logic
    },
    value: 12
})

As a general information, if you want to retrieve the currently applied filters, I suggest using the following syntax:
dataSource.filter().filters //returns the array of current filters


All the best,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Josh Eastburn
Top achievements
Rank 1
commented on 18 Jun 2012, 04:54 PM

Alexander,

Can you give more specifics on how the custom operator function would work?

Does function(item, value) need to return true/false?

I'm trying a very simple implementation of the operator function to start with nothing within the function, but I get an Unexpected Token exception:

  1. Uncaught SyntaxError: Unexpected token ) kendo.web.min.js:8
    1. o.extend.querykendo.web.min.js:8
    2. o.extend._querykendo.web.min.js:8
    3. o.extend.filterkendo.web.min.js:8
Josh Eastburn
Top achievements
Rank 1
commented on 18 Jun 2012, 06:16 PM

You can disregard my previous post.  I'm not sure what the issue was originally, but I have the operator function working correctly now by returning a true or false based on my custom criteria.
John
Top achievements
Rank 1
commented on 10 Jan 2014, 11:37 AM

how to get some particular data from json 
Alexander Valchev
Telerik team
commented on 10 Jan 2014, 11:48 AM

Hi John,

I am afraid that your question is a bit unclear. Please open a new thread with more detailed explanation so we can review your case and assist you further.
Thank you in advance.

Regards,
Alexander Valchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
John
Top achievements
Rank 1
commented on 10 Jan 2014, 12:33 PM

product.html page display the chart,

when i click any one it's send that particular data to display.html page,

that page(display.html) show the details day order in chart

example:

if i press p1 jan report,it's send data next page,

display.html page will display day order sales report for(1,2,3,..)in chart
Alexander Valchev
Telerik team
commented on 13 Jan 2014, 02:24 PM

Hi John,

This thread is more than an year old and your question is not directly related to the initial subject discussed in it. In order to get assistance please open a new thread.

Regards,
Alexander Valchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Vince
Top achievements
Rank 1
commented on 19 Feb 2014, 07:39 PM

I tried this recently and the operator as a function failed to pass in the value.  If it is a string, it passes the string literal as a variable.  If it is an array, it inflates the array members into the function parameters and I got them undefined errors.  Any thoughts?  Here is the generated anonymous code from Kendo UI 

function anonymous(d, __f, __o) {
return ((d.MyFieldName1 || '').toLowerCase().indexOf('') >= 0 && __o[0](d.MyFieldName2, StringLiterature1, StringLiterature1))
}
Alexander Valchev
Telerik team
commented on 20 Feb 2014, 10:21 AM

Hello Calvin,

Could you please provide a small but runnable jsBin sample which demonstrates your current implementation so I can take a look at it and examine what is going wrong?
Thank you in advance.

Regards,
Alexander Valchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Vince
Top achievements
Rank 1
commented on 19 Mar 2014, 10:04 PM

Hi Alex,

Do you still want me to provide the runnable code snippet?  I was busy with other stuff so I totally forgot about this.  Please let me know.

Giavinh
Alexander Valchev
Telerik team
commented on 20 Mar 2014, 08:24 AM

Hello Calvin,

Since this is not a known issue we will need a sample to reproduce it. If the problem still persists and you would like help for it please provide a sample which demonstrates the case and we will check it right away. Thank you in advance.

Regards,
Alexander Valchev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Vince
Top achievements
Rank 1
commented on 21 Mar 2014, 05:34 PM

Good news. I could not reproduce with the recent version.
0
Aiswarya
Top achievements
Rank 1
answered on 05 Apr 2017, 01:37 PM

Hi,

I have used the following code to get the current filters applied in a grid

 var curr_filters = $("#grid").data("kendoGrid").dataSource.filter().filters;

but i am getting the below mentioned error

Uncaught TypeError: Cannot read property 'filters' of undefined
    at HTMLButtonElement.<anonymous> (list_read:169)
    at HTMLButtonElement.dispatch (jquery.min.js:3)
    at HTMLButtonElement.r.handle (jquery.min.js:3)

Thanks in advance.

Alex Hajigeorgieva
Telerik team
commented on 10 Apr 2017, 09:50 AM

Hello Aiswarya,

The error is expected if there are no filters applied to the Kendo UI Data Source.

The filter() method API where this is outlined is available at:

http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#methods-filter

I would suggest checking if there is a filter, then attempting to access the filters, i.e:

var curr_filter = $("#grid").data("kendoGrid").dataSource.filter();
if(curr_filter){
 var filters = curr_filter.filters;
}

Kind Regards,
Alex Hajigeorgieva
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data (charts) and form elements.
Tags
Data Source
Asked by
Andrés
Top achievements
Rank 1
Answers by
Alexander Valchev
Telerik team
Aiswarya
Top achievements
Rank 1
Share this question
or