0
votes

I have created custom popup that contains 4 kendo multi select controls and one apply button. When I hit the apply button the selected value should use in kendogrid and filter the result. Each time I open the popup and every time same filters are being added to kendogrid odata query, even if I remove the value from multiselect controls.

I tried the remove filters from kendo grid datasource filters if it is already there. But I am not able to do that because of kendo multiselect controls gives me array of value and when we add those value to filters it create a group of filters

below code is called on apply button clicked from popup

var filter = {   logic: "AND",  filters: [] };           
                var controllerValue = $("#controller").data("kendoMultiSelect").dataItems();
                var reconciledByValue = $("#reconciledBy").data("kendoMultiSelect").dataItems();
                var reviewedByValue = $("#reviewedBy").data("kendoMultiSelect").dataItems();
                var approvedByValue = $("#approvedBy").data("kendoMultiSelect").dataItems();

                if (controllerValue.length > 0) {
                    filter.filters.push(createFilterGroup(controllerValue, "OR", "Controller"));
                }
                if (reconciledByValue.length > 0) {
                    filter.filters.push(createFilterGroup(reconciledByValue, "OR", "ReconciledByA"));
                }
                if (reviewedByValue.length > 0) {
                    filter.filters.push(createFilterGroup(reviewedByValue, "OR", "ReviewedByA"));
                }
                if (approvedByValue.length > 0) {
                    filter.filters.push(createFilterGroup(approvedByValue, "OR", "ApprovedByA"));
                }
if (filter.filters.length > 0) {
var gridDatasource = $("#" + gridid).data("kendoGrid").dataSource;
var allFilters = [];

allFilters = gridDatasource.filter().filters; //previous filters
allFilters.push(filter); //Add filters
 gridDatasource.filter(allFilters);
}


function createFilterGroup(filterData, operator, field) {
   var filterGroup = {
    logic: operator,
    filters: []
   };

 $.each(filterData, function (key, value) {
   filterGroup.filters.push({ field: field, operator: "eq", value: value[field] });
   });

return filterGroup;
 }




I expect the output of odata query to remove already added filter condition first and than add new condition

below URL contains Controller+eq+%27denekewj%27+OR+Controller+eq+%27jabbott%27
in the first search
https://localhost:44335/odata/UserReconciliationAccounts/GetDistinctRoleCountForAccountBase?%24format=json&%24top=50&%24filter=((((FiscalYear+lt+2019+OR+(FiscalPeriod+lt+8+AND+FiscalYear+eq+2019))+AND+(IsReconLateAndIncomplete+eq+true+OR+IsReviewLateAndIncomplete+eq+true+OR+IsApprovalLateAndIncomplete+eq+true))+OR+(FiscalPeriod+eq+8+AND+FiscalYear+eq+2019))+and+(Controller+eq+%27denekewj%27+OR+Controller+eq+%27jabbott%27))&%24count=true

next time if I remove one controller value than query is forming like below

https://localhost:44335/odata/UserReconciliationAccounts/GetDistinctRoleCountForAccountBase?%24format=json&%24top=50&%24filter=((((FiscalYear+lt+2019+OR+(FiscalPeriod+lt+8+AND+FiscalYear+eq+2019))+AND+(IsReconLateAndIncomplete+eq+true+OR+IsReviewLateAndIncomplete+eq+true+OR+IsApprovalLateAndIncomplete+eq+true))+OR+(FiscalPeriod+eq+8+AND+FiscalYear+eq+2019))+and+(Controller+eq+%27denekewj%27+OR+Controller+eq+%27jabbott%27)+and+Controller+eq+%27jabbott%27)&%24count=true

Now I remove all conroller value from kendo multiselect and added value in other multiselect than below query formed
https://localhost:44335/odata/UserReconciliationAccounts/GetDistinctRoleCountForAccountBase?%24format=json&%24top=50&%24filter=((((FiscalYear+lt+2019+OR+(FiscalPeriod+lt+8+AND+FiscalYear+eq+2019))+AND+(IsReconLateAndIncomplete+eq+true+OR+IsReviewLateAndIncomplete+eq+true+OR+IsApprovalLateAndIncomplete+eq+true))+OR+(FiscalPeriod+eq+8+AND+FiscalYear+eq+2019))+and+(Controller+eq+%27denekewj%27+OR+Controller+eq+%27jabbott%27)+and+Controller+eq+%27jabbott%27+and+ReconciledByA+eq+%27sihuda%27)&%24count=true
1

1 Answers

0
votes

Finally spending time a lot. I am able to get the solution.

Step 1: Add recursive function to clear already added filter(nested filters)

function removeFilter(filter, searchFor) {
                if (filter == null)
                    return [];

                for (var x = 0; x < filter.length; x++) {

                    if (filter[x].filters != null && filter[x].filters.length >= 0) {
                        if (filter[x].filters.length == 0) {
                            filter.splice(x, 1);
                            return removeFilter(filter, searchFor);
                        }
                        filter[x].filters = removeFilter(filter[x].filters, searchFor);
                    }
                    else {
                        if (filter[x].field == searchFor) {
                            filter.splice(x, 1);
                            return removeFilter(filter, searchFor);
                        }
                    }
                }

                return filter;
            }

            function clearRootLevelArray(filter) {
                for (var x = 0; x < filter.length; x++) {
                    if ((filter[x].filters !== undefined || filter[x].filters != null)
                        && filter[x].filters.length == 0) {
                        filter.splice(x, 1);
                        return clearRootLevelArray(filter);
                    }
                }
                return filter;
            }
            function clearInnerLevelArray(filter) {
                for (var x = 0; x < filter.length; x++) {
                    if (filter[x].filters !== undefined || filter[x].filters != null) {
                        for (var y = 0; y < filter[x].filters.length; y++) {
                            if ((filter[x].filters[y].filters !== undefined || filter[x].filters[y].filters != null)
                                && filter[x].filters[y].filters.length == 0) {
                                filter[x].filters.splice(y, 1);
                                return clearInnerLevelArray(filter);
                            }
                        }
                    }
                }
                clearRootLevelArray(filter)//once again clear root level after clearing innerlevel
                return filter;
            }

//Last step how/when calling these function 
 var gridDatasource = $("#gridid").data("kendoGrid").dataSource;
 var allFilters = [];

 allFilters = gridDatasource.filter().filters; //previous filters
 //before pushing new filters, first check if filters are already added, //if yes than remove them and add again
allFilters = removeFilter(allFilters, "status");
allFilters = clearRootLevelArray(allFilters);
allFilters = clearInnerLevelArray(allFilters);
allFilters.push(filter); //Add filters
gridDatasource.filter(allFilters);