Using Custom Datasource in Kendo Grid for Filtering

1 Answer 57 Views
Data Source Filter Grid
Matt
Top achievements
Rank 1
Matt asked on 01 Feb 2024, 08:39 AM | edited on 01 Feb 2024, 08:51 AM

Morning,

I've been using the Kendo Grid for years and absolutely love it for what I can do with it, but every so often I get asked to stretch the functionality of what it can do,  I haven't found much documentation on this, but i'll try my best to give an example of what I've done, and to see if there is a better way of doing it..

I have a field in my Grid that is a string, with multiple "Tags" explicitly given in the dataSource in filterable.

    {
        "columnMenu": {
            "componentType": "modern"
        },
        "stickable": true,
        "field": "conditions",
        "filterable": {
            "enabled": true,
            "multi": true,
            "search": true,
            "dataSource": [
                {
                    "conditions": "TEST123"
                },
                {
                    "conditions": "TEST"
                },
                {
                    "conditions": "ABC"
                },
                {
                    "conditions": "DEF"
                }
            ]
        },
        "groupable": true,
        "aggregates": "count",
        "groupHeaderTemplate": "Conditions: #= value # (Count: #= count#)",
        "sortable": true,
        "title": "Conditions",
       

The data in the field is a string of comma separated tags, i.e.

TEST, ABC, DEF

I've updated the filter method on the Grid so that I can select multiple options in the filter menu, and it does a "contains" look up to match multiple hits.

filter: function(e){
	this.columns.forEach(function(f){
		if(e.field === f.field){
			if(f.filterable.hasOwnProperty('dataSource')){
				e.filter.filters.forEach(function(f){
					f.operator = "contains";
					e.filter.logic = "and";
				})
			}
		}
	})
},

I have two issues here.

1. I'm using contains, so if the tags are similar (TEST, TEST123), selecting TEST will show both TEST and TEST123 - which isn't ideal.

2. If I select an option from the filter menu, it doesn't remain checked if you were to go back into the filter menu again.

I've asked this question before and had some great help to get it to this point using: https://docs.telerik.com/kendo-ui/knowledge-base/grid-how-to-change-multi-checkbox-filter-to-contains but I'm wondering if there is a better way of achieving the functionality I'm looking for here with the grid.  I added square brackets to the tags to distinguish them ([TEST], [TEST123]) , but my users didn't like this change.

Is there a way to do this without using contains?

I'd also like to be able to see the selected option in the filter menu - I can find the checkbox through jQuery, but I cannot toggle it's state..

e.filter.filters.forEach(function(f){
	var checkbox = $(".k-filter-menu").find("input[value='"+f.value+"']");

	console.log(checkbox);												 
        checkbox.prop("checked", true).trigger("change");
	checkbox.attr("checked", true).trigger("change");

	f.operator = "contains";
	e.filter.logic = "and";
})

Thanks for your help,

Matt

1 Answer, 1 is accepted

Sort by
0
Martin
Telerik team
answered on 05 Feb 2024, 12:45 PM

Hello, Matt,

As far as I understand the requirement, it is very similar to what is shown in the knowledge base example you shared, so I must be missing something from the issue you are experiencing. Could you please elaborate a bit more what the expected behaviour is, and maybe provide some steps with expected versus current behaviour? That way I should be able to better understand the case and assist you.

Thank you for the cooperation. Looking forward to your reply.

Regards,
Martin
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Kendo family, check out our getting started resources
Matt
Top achievements
Rank 1
commented on 07 Feb 2024, 10:13 AM

Hi Martin,

Thanks for your reply.

I was hoping there would be a better out of the box alternative than having to effectively code in this specific use case - if that is not the case, I'd heavily advocate their to be some way of having a list of "tags" associated to a field that can be toggled via the filter menu.  Almost as if there were a field of just an array of fields that could be matched without having to concatenate a string and use a contains.

I still have the issue that when these filters are checked and then filtered from the filter menu, if I was to reopen the filter menu for that field, the checkboxes are unchecked - as if they weren't active.  The examples shown don't have this issue and I cannot for the life of me see why it isn't staying checked.  As from my example, I even try to force the check when the filters are active.

So I can use this on columnMenuOpen, which feel like a horrendous hack to make it work.

columnMenuOpen: function(e){
	var filters = this.dataSource.filter();
	var column = null;

	this.columns.forEach(function(col){
		if(e.field === col.field){
			column = col;
		}
	});

	if(column && column.hasOwnProperty('filterable') && 							 
               column.filterable.hasOwnProperty('dataSource')){
			filters.filters.forEach(function(filter){
				if(column.field === filter.field){
					var checkbox = $("input[value='"+filter.value+"']");

					checkbox.prop("checked", true).trigger("change");
				}
		});
	}
},

As just as a side point, it would be really nice to see something in the UI that shows the currently active filters/sorts/groups applied to the grid in an overview! i.e.

Martin
Telerik team
commented on 12 Feb 2024, 09:14 AM

Hello, Matt,

I tried the code snippets provided in the initial reply in this Dojo example, and all appears to be working as expected. Note that I have modified the if statement below as otherwise an error occurs. Could you please review it and let me know if it would be helpful? If not, kindly try to modify the example so that I can see the issues you are having.

if(f.filterable.hasOwnProperty('dataSource') && e.filter !== null ){
                e.filter.filters.forEach(function(f){
                  f.operator = "contains";
                  e.filter.logic = "and";
                })
              }

Tags
Data Source Filter Grid
Asked by
Matt
Top achievements
Rank 1
Answers by
Martin
Telerik team
Share this question
or