How can I combine 2 columns filterable options on a column? Per example multi + operators

1 Answer 78 Views
Data Source Filter Grid
Jacob
Top achievements
Rank 1
Jacob asked on 05 May 2022, 08:00 PM

Hi,

I encoutered a problem where I'm trying to have 2 different filter options for a Kendo Grid column and I can't manage to find the answer on how to combine filters like Operators (equal to, is greater than, etc.) and filter multi checkboxes listing all results for that column.

I have a working copy of filter multi checkboxes, but when I try to add a second option on one of my columns.filterable it's not taken into account and I didn't manage to find any answers on a possible how to.

filterable: {
   multi: true,
   operators: {
            string: {
              eq: "Equal to",
              neq: "Not Equal to"
            }
     },
}

I wonder if I need to create a custom template in order to achieve a combination of both to produce this intended result as depicted in the attached picture : IntendedResult.PNG

We are on Kendo UI for jQuery v2019.1.220

Thank you!

1 Answer, 1 is accepted

Sort by
0
Georgi Denchev
Telerik team
answered on 10 May 2022, 01:02 PM

Hi, Jacob,

Yes, you would have to use custom logic/template to achieve the desired behavior. A similar approach is showcased in the following Knowledge Base article:

https://docs.telerik.com/kendo-ui/knowledge-base/use-both-multi-and-default-filtering 

I've made a couple of modifications to it, to better suit the requirement:

https://dojo.telerik.com/@gdenchev/eRoNiGoQ 

Let me know if you have any questions.

Best Regards,
Georgi Denchev
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/.

Jacob
Top achievements
Rank 1
commented on 13 May 2022, 05:17 PM

Hi Georgi,
I worked to customize the solution to my needs, but up to now I have to code the filters manually because the default filters are cosmetic when we combine them with filter Multi Checkbox, I managed to make it work for strings, but I'm having problem with numbers and dates, as if I would need to recreate the entire logic behind these kendo filters for them to work... 

I finally made the decisions to use multi checkbox with default operators instead of custom operators but the solution from the article don't work properly except giving the graphical result for the filters interface. So I wonder if there is a way to tell Kendo when using the Default Filters use the Default Kendo Methods for filtering and when using Multi use the custom initFilterMethod event if they are both combined in the same Filter Window.

Here is a look at my initCheckboxFilter method.
const initCheckboxFilter = function (e) {
		var estNombre = false;
		var container = e.container;
		var popup = container.data("kendoPopup");
		var dataSource = this.dataSource;
		var field = e.field;
		var checkboxesDataSource = new kendo.data.DataSource({
			data: uniqueForField(dataSource.data(), field)
		});

		checkboxesDataSource.options.data  = triABulleAlgo(checkboxesDataSource.options.data, field);

		var helpTextElement = e.container.children(":first").children(":first");

		var element = $("<div class='checkbox-container p-2'></div>").insertAfter(helpTextElement).kendoListView({
			dataSource: checkboxesDataSource,
			template: "<div><input type='checkbox' value='#:" + field + "#'/> #:" + field + "#</div>"
		});
		

		// Get the dropdownlists
		var ddlElements = container.find("select"),
			firstOperator = ddlElements[0],
			condition = ddlElements[1],
			secondOperator = ddlElements[2];

		// Get the inputs
		var inputElements = container.find(".k-textbox"),
			firstInput = inputElements[0],
			secondInput = inputElements[1];

		if (!inputElements.length) {
			inputElements = container.find(".k-input[data-role='numerictextbox']");
			firstInput = inputElements[0];
			secondInput = inputElements[1];
			estNombre = true;
		}

		// Remove the data binding attributes, otherwise the values from the checkboxes will replace the values in the inputs.
		$(firstInput).removeAttr("data-bind");
		$(secondInput).removeAttr("data-bind");

		container.find("[type='submit']").click(function (e) {
			e.preventDefault();
			e.stopPropagation();

			var filter = dataSource.filter() || { logic: "or", filters: [] };

			var fieldFilters = [];

			var fieldFiltersMulti = $.map(element.find(":checkbox:checked"), function (input) {
				return {
					field: field,
					operator: "eq",
					value: input.value
				};
			});

			var logicOperators = $(condition).data(
				"kendoDropDownList").value();
            
			removeFiltersForField(filter, field);

			// If it does, get the operator.
			var operator = $(firstOperator).data(
				"kendoDropDownList").value();

			// Check if the first input has a value.
			if ($(firstInput).val()) {
				// Create a filter object.

				let filterObject = {
					field: field,
					operator: operator,
					value: estNombre ? parseFloat($(firstInput).val()) : $(firstInput).val()
				}

				// Push the object to the rest of the filters(the checkboxes).
				fieldFilters.push(filterObject)
			} else if (operator == 'isnull' || operator == 'isnullorempty' || operator == 'isnotnull' || operator == 'isnotnullorempty' || operator == 'isempty' || operator == 'isnotempty') {
				let filterObject = {
					field: field,
					operator: operator
				}

				fieldFilters.push(filterObject)
            }

			var operator2 = $(secondOperator).data(
				"kendoDropDownList").value();

			// Repeat the same process.
			if ($(secondInput).val()) {
				let filterObject = {
					field: field,
					operator: operator2,
					value: estNombre ? parseFloat($(secondInput).val()) : $(secondInput).val()
				}


				fieldFilters.push(filterObject)
			} else if (operator2 == 'isnull' || operator2 == 'isnullorempty' || operator2 == 'isnotnull' || operator2 == 'isnotnullorempty' || operator2 == 'isempty' || operator2 == 'isnotempty') {
				let filterObject = {
					field: field,
					operator: operator2
				}

				fieldFilters.push(filterObject)
            }

			

			// Finally push the fieldFilters to the entire filter object.
			if (fieldFilters.length) {
				filter.filters.push({
					logic: logicOperators,
					filters: fieldFilters
				});
            }
			
			if (fieldFiltersMulti.length) {
				filter.filters.push({
					logic: 'or',
					filters: fieldFiltersMulti
				});
            }
			
			// And apply the filter to the dataSource.
			dataSource.filter(filter);
			popup.close();
		});
	}
Your help is welcome!


Georgi Denchev
Telerik team
commented on 18 May 2022, 01:52 PM

Hi, Jacob,

Thank you for the provided code snippet.

I am having a bit of a difficulty understanding the problem and the requirement. The filtering in the Dojo seems to be working with both the checkboxes and the default UI(the inputs with dropdowns).

Could you let me know what filter values/operators should I use in the Dojo to try and replicate the issue on my end?

Afterwards, I should be able to provide you with a solution.

Best Regards,

Georgi

Tags
Data Source Filter Grid
Asked by
Jacob
Top achievements
Rank 1
Answers by
Georgi Denchev
Telerik team
Share this question
or