Kendo Grid Filter Posting Twice

7 posts, 1 answers
  1. Tony
    Tony avatar
    6 posts
    Member since:
    Jul 2011

    Posted 09 Aug Link to this post

    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.    };

  2. Answer
    Daniel
    Admin
    Daniel avatar
    2118 posts

    Posted 11 Aug Link to this post

    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.
     
  3. Kendo UI is VS 2017 Ready
  4. Tony
    Tony avatar
    6 posts
    Member since:
    Jul 2011

    Posted 19 Aug in reply to Tony Link to this post

    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

  5. Daniel
    Admin
    Daniel avatar
    2118 posts

    Posted 23 Aug Link to this post

    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.
     
  6. Tony
    Tony avatar
    6 posts
    Member since:
    Jul 2011

    Posted 23 Aug Link to this post

    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.  
  7. Tony
    Tony avatar
    6 posts
    Member since:
    Jul 2011

    Posted 23 Aug in reply to Daniel Link to this post

    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.  
  8. Tony
    Tony avatar
    6 posts
    Member since:
    Jul 2011

    Posted 23 Aug in reply to Tony Link to this post

    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. 

     

     

Back to Top
Kendo UI is VS 2017 Ready