This is a migrated thread and some comments may be shown as answers.

Kendo Grid Filter Posting Twice

6 Answers 776 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Tony
Top achievements
Rank 1
Tony asked on 09 Aug 2016, 05:03 AM

Ok so I have a kendo grid. Leaving off the definition to make not so long, but I do have autoBind: false on it. I then do the 3 functions below to add a custom multi-select filter to one column. The other thing I have is I set an initial filter on that same column in the grid definition. The problem I am having is that filter gets called twice, once with correct params and a 2nd time with the original filter, or if I have that original filter commented out; it will call it the second time using any other column filters on the grid you have set in the ui, but without using the custom filter on this one column.

I've spent all day and night trying to figure this out... Any ideas.

 

01.self.onSchemaPopulated = function (columns, model) {
02. 
03.        var measureKey = _.find(columns, function(item) {
04.            return item.field === 'measure_key';
05.        });
06. 
07.        measureKey.filterable =
08.            {
09.                extra: false,
10.                operators: {
11.                    string: {                          
12.                        eq: "Is equal to"                          
13.                    }
14.                },
15.                ui: self.measureKeyFilter                  
16.            };
17. 
18.    };
19. 
20.    self.measureKeyFilter = function (element) {
21. 
22.        element.removeAttr("data-bind");
23. 
24.        var menu = $(element).parent();
25. 
26.        menu.find(".k-filter-help-text").text("Show records for measure keys in:");
27.        menu.find("[data-role=dropdownlist]").remove();
28. 
29.        var multiSelect = element.kendoMultiSelect({
30.            dataBound: function (e) {
31.                e.sender.tagList.addClass('k-full-button');
32.                e.sender.ul.addClass('k-multiselect-items');
33.            },
34.            dataSource: _.invoke(self.itemSelected().measures(), 'measure_key'),
35.            tagMode: 'single',
36.            tagTemplate: '<div>#:values.length# measures selected...</div>',
37.            value: _.invoke(self.itemSelected().checkedMeasures(), 'measure_key'),
38.        }).data("kendoMultiSelect");
39. 
40.        menu.find("[type=submit]").on("click", { widget: multiSelect }, self.filterByMeasureKey);
41. 
42.    };
43. 
44.    self.filterByMeasureKey = function (e) {
45. 
46.        var newFilter = { logic: "and", filters: [] };
47.        var measureFilter = null;
48.        var values = e.data.widget.value();
49. 
50.        if (values.length !== self.itemSelected().measures().length) {
51. 
52.            measureFilter = { logic: "or", filters: [] };
53. 
54.            $.each(values, function (i, v) {
55.                measureFilter.filters.push({ field: "measure_key", operator: "eq", value: v });
56.            });
57. 
58.            newFilter.filters.push(measureFilter);
59. 
60.        };
61. 
62.        var grid;
63. 
64.        if (self.isRelationshipSummaryToggled()) {
65.            grid = $('#' + self.rsOptions.id).data("kendoGrid");
66.        } else {
67.            grid = $('#' + self.rdOptions.id).data("kendoGrid");
68.        };
69. 
70.        var currentFilters = grid.dataSource.filter();
71. 
72.        if (!isNull(currentFilters)) {             
73. 
74.            _.each(currentFilters.filters, function (x) {                  
75. 
76.                if (!_.isArray(x.filters)) {
77.                    newFilter.filters.push(x);
78.                } else if (x.filters[0].field !== 'measure_key') {
79.                    newFilter.filters.push(x);
80.                };
81. 
82.            });                
83. 
84.        };         
85. 
86.        grid.dataSource.filter(newFilter);
87. 
88.    };

6 Answers, 1 is accepted

Sort by
0
Accepted
Daniel
Telerik team
answered on 11 Aug 2016, 07:54 AM
Hello Tony,

The second filter will be sent because the built-in filter menu will still filter the dataSource if the default action is not prevented. You should call the event argument preventDefault method to prevent the form from submitting in order to stop the built-in filter. Since the event will not be handled in this case by the built-in logic, you also will need to manually close the popup. The scenario is demonstrated in this example.

Regards,
Daniel
Telerik by Progress
 
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
 
0
Tony
Top achievements
Rank 1
answered on 19 Aug 2016, 09:42 PM

Thanks, that example made everything a tremendous amount better except for one thing.  The web api is not translating the list of checked filters correctly. The url was getting too big so I needed to change the GET to a POST.  I used nearly the exact same code as the ModelBinder, so I don't think that is the problem.    

01.public class KendoDataSourceRequest
02.{
03. 
04.    #region Public Properties
05. 
06.    public int page { get; set; }
07.    public int pageSize { get; set; }
08.    public string aggregates { get; set; }
09.    public string filter { get; set; }
10.    public string group { get; set; }
11.    public string sort { get; set; }
12. 
13.    #endregion 
14. 
15.    #region Public Methods
16. 
17.    /// <summary>
18.    /// Converts the posted request into a kendo datasource request
19.    /// </summary>
20.    /// <returns><see cref="DataSourceRequest"/></returns>
21.    public DataSourceRequest ToDataSourceRequest()
22.    {
23. 
24.        var request = new DataSourceRequest();
25. 
26.        request.Page = page > 0 ? page : 1;
27.        request.PageSize = pageSize > 0 ? pageSize : 100;
28. 
29.        request.Aggregates = GridDescriptorSerializer.Deserialize<AggregateDescriptor>(aggregates);
30.        request.Groups = GridDescriptorSerializer.Deserialize<GroupDescriptor>(group);
31.        request.Sorts = GridDescriptorSerializer.Deserialize<SortDescriptor>(sort);
32. 
33.        request.Filters = FilterDescriptorFactory.Create(filter);
34.        return request;
35. 
36.    }
37. 
38.    #endregion
39. 
40.}

1.public async Task<IHttpActionResult> GetRelationshipSummary([FromBody] KendoDataSourceRequest request, [FromUri] Guid pqmConfigId)
2.        {
3. 
4.            var translatedRequest = request.ToDataSourceRequest();
5.}

What is going on is that the filter string that comes in below isn't getting translated correctly...

measure_key~eq~'AAB16'~or~measure_key~eq~'AAP16'~or~measure_key~eq~'ABA16'~or~measure_key~eq~'ABX16'~or~measure_key~eq~'ADD16'~or~measure_key~eq~'ADV16'~or~measure_key~eq~'AMB16'~or~measure_key~eq~'AMM16'

It seems to get translated into some recursive groups of two type mess... Attached in the screenshot of the filters translated in QuickWatch...

Thanks for your help before... Tony

0
Daniel
Telerik team
answered on 23 Aug 2016, 06:54 AM
Hello again Tony,

Is there an issue with applying the filters? The ToDataSourceResult method should work with this structure.

On a side note, there is a built-in model binder that can be used to deserialize the DataSourceRequest when using the Api controllers.

Regards,
Daniel
Telerik by Progress
 
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
 
0
Tony
Top achievements
Rank 1
answered on 23 Aug 2016, 02:19 PM
Not sure what you mean on the question.  The whole post was about about there being an issue applying the filters.  I know there is model-binder code, and I have been using that on the GET requests, but  you can't use a model-binder and POST at the same time -- so I just moved the model-binder code over into something that would work.  

The translated.png shows the problem.  Instead of me getting a composite OR filter back that has my 8 measure keys in it, it is recursively grouping everything into pairs of 2's and thus not actually filtering correctly.  You can see this in the translated.png image.  
0
Tony
Top achievements
Rank 1
answered on 23 Aug 2016, 02:25 PM
Not sure what you mean on the question.  The whole post was about about there being an issue applying the filters.  I know there is model-binder code, and I have been using that on the GET requests, but  you can't use a model-binder and POST at the same time -- so I just moved the model-binder code over into something that would work.  

The translated.png shows the problem.  Instead of me getting a composite OR filter back that has my 8 measure keys in it, it is recursively grouping everything into pairs of 2's and thus not actually filtering correctly.  You can see this in the translated.png image.  
0
Tony
Top achievements
Rank 1
answered on 24 Aug 2016, 12:41 AM

Nevermind... It wasn't working as I expected to, but we also do have a lot of complex logic wrapped around it on either side.  It isn't a pure kendo solution.  I was able to find a place further down in the logic where I could correct the problem in my code. 

 

 

Tags
Grid
Asked by
Tony
Top achievements
Rank 1
Answers by
Daniel
Telerik team
Tony
Top achievements
Rank 1
Share this question
or