0
votes

I have a custom multi-select drop-down element in one of my kendo grid header columns titled "Status". Each selection in the drop-down represents many statuses, but they are grouped together for simplicity, and so we can show groups of like statuses.

Since this is a custom filter, I know I have to manipulate the kendo filter manually, and this seems to be giving me fits.

When any selection is changed in my custom drop-down, I fire off a function to modify the filters (the section where I spin through the status array has been truncated for easier reading):

// Apply the status filters from the multi-select drop down
function applyStatusFilter(statusValues) {
    var gridData = $("#accountsGrid").data("kendoGrid");
    var currentFilterObj = gridData.dataSource.filter();
    var currentFilters = currentFilterObj ? currentFilterObj.filters : []; // If there are no current filters, set to empty array
    var statusFilters = { logic: "or", filters: [] };
    var statusArray = statusValues.split(','); // Convert status selections to array

    // Remove any pre-existing status filters from the existing filter
    if (currentFilters && currentFilters.length > 0) {
        for (var i = 0; i < currentFilters.length; i++) {
            if (currentFilters[i].field == 'status') {
                currentFilters.splice(i, 1);
                //break;
            }
        }
    }

    if (statusArray[0].length > 0) {
        $.each(statusArray, function (key, value) {
            if (value == 'AC') {
                statusFilters.filters.push({
                    field: "status",
                    operator: "eq",
                    value: "A"
                });
                statusFilters.filters.push({
                    field: "status",
                    operator: "eq",
                    value: "G"
                });
                statusFilters.filters.push({
                    field: "status",
                    operator: "eq",
                    value: "O"
                });
            if (value == 'OH') {
                statusFilters.filters.push({
                    field: "status",
                    operator: "eq",
                    value: "G"
                });
                statusFilters.filters.push({
                    field: "status",
                    operator: "eq",
                    value: "H"
                });
                statusFilters.filters.push({
                    field: "status",
                    operator: "eq",
                    value: "I"
                });
            }
        });
    }

    currentFilters.push(statusFilters);

    gridData.dataSource.filter({
        logic: "and",
        filters: currentFilters
    });
}

This isn't working as expected, although it's still a work in progress. There are two main issues; when I call this function, I want to remove all current "status" related filters, then rebuild. I can't clear all filters, as I need to maintain other column filters that might be applied. My remove status filters block doesn't seem to be working.

Second big issue, is how to properly combine two filter objects; when one can be a nested blocked of status filters using "or" logic, then combining it to any possible existing filters using "and" logic between the two filter objects.

1
here is a logic , do not care about the current gird filters you have . simply in change event of the multiselect get all the values and make a filter object and equal to the grid dataSource filter and refresh the grid. will that work ?cwishva

1 Answers

0
votes

About your first issue. There are sure several ways to remove all current "status" related filters, but I have built a recursive function that clear the filters for a given column.

function clearFilter(filter, columnToClear) {
    if (filter == undefined)
        return filter;

    if (filter.logic != undefined) {
        filter.filters = $.map(filter.filters, function (val) {
            if (val.field == undefined && typeof (val.filters) == "object" && typeof (val.logic) == "string") {
                val.filters = clearFilter(val.filters, columnToClear)

                if (val.filters.length == 0)
                    val = null;
                return val;
            }
            else if (val.field != columnToClear)
                return val;
        });

        if (filter.filters.length == 0)
            filter = null;
    }
    else {
        filter = $.map(filter, function (val) {
            if (val.field != columnToClear)
                return val;
        });
    }

    return filter;
}

In your case the function should be called as:

clearFilter(currentFilterObj, "status");