Small bug in AwareApp_QueryLayoutParser filter function

If you think that something doesn't work in Aware IM post your message here
Post Reply
nhofkes
Posts: 124
Joined: Mon Sep 07, 2020 6:03 am
Location: Netherlands

Small bug in AwareApp_QueryLayoutParser filter function

Post by nhofkes »

I came across a small bug in the filter function (event listener) in the AwareApp_QueryLayoutParser (I believe part of the 'setupEvents' method). Below I will describe when the issue occurs, quote the parser code where the problem likely is, describe a temporary work-around and make a few suggestions to amend the parser code to solve the issue.

Use case when this occurs:
If you dynamically prefill the filter for a grid by setting the dataSource.filter value in the initialization script of the query, and the user subsequently clicks the clear button for the filter on the grid, a TypeError exception occurs because a null value is referenced.
For example, suppose that you have a database of cars and the grid lists all cars with brand, year, type, color etc. and you want to dynamically filter this list to show only the cars with a specific color, this can be done with the following initalization script:

Code: Select all

const filter = "<<Session.Filter>>";	
if (filter !== "" && filter !== undefined) {
  config.dataSource.filter = {
    logic: "and",
    filters: [
      {
        field: "Color", // name of the column in the grid (BO attribute) that the filter is applied to.
        operator: "contains",
        value: filter,
      },
    ],
  };
}
(This example assumes that the Filter field in the Session object contains the relevant value that must be used to set the filter).

This init script will set the filter and Kendo will put the relevant filter value in the filter and display the Clear filter button. Example screen shot below, where the filter column is 'Status' and the filter value is set to 'Draft' (note that I have the filter displayed on a separate row - I did not test what happens if the filter is included in the column menu; most likely the same error occurs).
Screenshot 2024-08-31 083639.png
Screenshot 2024-08-31 083639.png (2.31 KiB) Viewed 5642 times

So far so good. But when the user clears the filter by clicking on the clear filter button, nothing happens and when you have the Browser Developer Tool open, you can see that there is a TypeError exception: 'm_extParams is null' (or something like that).

I believe this is caused by the following code in the QueryLayout Parser (Version 9.0 build 3272):

Code: Select all

gridConfig.filter = function (e)
{
	// This will be used by encodeDataSourceParam for the group paging mode. These filters are considered external ones
  	if (e.filter)
  	{
		me.externalFilterApplied = true;
				
	        // remember the current filter
		if (! me.m_extParams)
			me.m_extParams = {};

			if (! me.m_extParams.gridKendoFilters)
				me.m_extParams.gridKendoFilters = new Array ();

			me.m_extParams.gridKendoFilters.push ({ filter: e.filter, field: e.field });
		}
		else if (me.m_extParams.gridKendoFilters)
		{
			// filter is cleared
			for (var i = 0; i < me.m_extParams.gridKendoFilters.length; ++ i)
			{
				if (me.m_extParams.gridKendoFilters[ i ].field == e.field)
				{
					me.m_extParams.gridKendoFilters.splice (i, 1);
					break;
				}
			}
		}
	}
}
Looking more closely, you can see that the m_extParams is set to an empty object {} when the filter is set for the first time (if it wasn't already set before). But if the filter is set by the initialization script instead of the user at runtime and then the clear filter button is clicked, the e.filter parameter of the event is null (Kendo reference: https://docs.telerik.com/kendo-ui/api/j ... nts/filter), which means that the first part of the code (after "if (e.filter)" ) is skipped and the second part "if (me.m_extParams.gridKendoFilters)" is evaluated, causing the null reference error because at that time m_extParams is still null (not yet initialized).

As a work-around, I have now added the following code to the initialization script:
if (! parser.m_extParams)
parser.m_extParams = {};
This solves the issue, the filter can now be cleared normally. But I don't know whether doing this may cause unexpected side effects, for example if other parts of the parser code rely on the m_extParams being null instead of an empty object. So it's more a hack than a real solution.

I think the parser code can be easily amended to avoid the null reference error:
either put the lines "if (! me.m_extParams) me.m_extParams = {};" at the top of the filter function (before the first 'if')
or change the line "else if (me.m_extParams.gridKendoFilters)" to "else if (me.m_extParams && me.m_extParams.gridKendoFilters)"
Niels
(V9.0 build 3272 - MariaDB - Windows)
Jaymer
Posts: 2523
Joined: Tue Jan 13, 2015 10:58 am
Location: Tampa, FL
Contact:

Re: Small bug in AwareApp_QueryLayoutParser filter function

Post by Jaymer »

FYI
I've never had this issue.
I use Render script.

Code: Select all

var grid = widget;
var ds=grid.dataSource;
ds.filter( {
logic: "and",
filters: [
{field: "ActiveYN", operator: "eq", value: "Y" }
]
});
I clear the filter with the "x" or [Clear] button if the funnel icon is being used and it happily clears it and re-runs the query.
Click Here to see a collection of my tips & hacks on this forum. Or search for "JaymerTip" in the search bar at the top.

Jaymer
Aware Programming & Consulting - Tampa FL
nhofkes
Posts: 124
Joined: Mon Sep 07, 2020 6:03 am
Location: Netherlands

Re: Small bug in AwareApp_QueryLayoutParser filter function

Post by nhofkes »

Jaymer wrote: Tue Sep 03, 2024 5:11 pm I've never had this issue.
I use Render script.
That is probably why you didn't have the issue: because you are using a render script, the filter is applied after the grid is rendered. I was referring to the situation where the filter is put in the initialization script, therefore before the grid is rendered.

The difference is visible on screen: when put in the render script, initially the full table is loaded in the grid and then re-rendered to apply the filter, whereas if it is put in the initialization script the table will already be filtered when displayed - which is easier on the eyes.
Niels
(V9.0 build 3272 - MariaDB - Windows)
Post Reply