Declined
Last Updated: 31 May 2022 14:23 by Marianne
Marianne
Created on: 17 May 2022 15:13
Category: UI for ASP.NET Core
Type: Feature Request
0
IN operator for grid filter

It would be useful to have a grid operator for "IN" conditions. Right now we only have 2 options for an OR without having to use a custom filtering and custom clearing functions.

We have a lot of data that needs to be filtered that is not sequential.  For example purposes:

Given that a customer has a standing purchase order for parts over time.

Given that serial numbers on said parts will not be sequential and may not be even be similar enough for wildcards (if that feature is provided.)

Given that we need to filter grid data to retrieve customer number, purchase order and a set of serial numbers, we need the equivalent of:

SELECT * FROM testdatatable WHERE customer = '#####' AND purchaseorder = '#####' AND serialnumber IN ('abciqwe', 'cid235', 'sn34087', 'hpk2679');

which would be WHERE WHERE customer = '#####' AND purchaseorder = '#####' AND (serialnumber  = 'abciqwe' OR serialnumber =  'cid235' OR serialnumber = 'sn34087' OR serialnumber 'hpk2679');

So basically I would like to have the ability to have multiple OR statements and the operand could be 'contains' or 'not contains' as that would probably work better than "equal".

4 comments
Marianne
Posted on: 31 May 2022 14:23

Thank you for your consideration.  The multi-select doesn't easily fit our needs since we are dealing with millions of rows of data and almost as many serial numbers. 

I will stick with the solution I already have which are:

  $(document).ready(function () {
        var grid = $("#grid").data("kendoGrid"); // Get an instance of the Grid
        var gridColumns = grid.columns; //get the current grid columns options
        gridColumns[1].filterable = { //set the "filterable" options of the 3rd column "SERIAL_NO"
            extra: false,
            operators: { //specify the operators that should be displayed in the column filter menu. Here you can review the available operators based on the field data type (date, number, string, enum): https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/configuration/filterable.operators
                string: {
                    contains: "Contains",
                    eq: "Equal to",
                    startswith: "Starts With",
                    endswith: "Ends With",
                    neq: "Not Equal to",
                    doesnotcontain: "Doesn't contain",
                    doesnotstartwith: "Does not start with",
                    doesnotendwith: "Does not end with",

                }
            }
        };
        grid.setOptions({ //update the grid column settings
            columns: gridColumns
        });
    });

 

function onFilter(e){
  if(e.filter === null) {
     e.sender.dataSource.filter();
     //this will clear all
      //e.preventDefault()
      //e.sender.dataSource.filter({})
       } else {      
       //come here is not null and then if field is serial no
        if(e.field == "SERIAL_NO"){
          var operator = e.filter.filters.filter(x=>x.field == "SERIAL_NO")[0].operator;
           var searchcondition = (e.filter.filters.filter(x=>x.field == "SERIAL_NO")[0].value);
            var isComma = searchcondition.includes(",");
             e.preventDefault()
             e.filter.logic = "or";
            if(isComma) {
                const conditions = searchcondition.split(",");
                for(i = 0; i<conditions.length; i++) {
                    var c = conditions[i].trim();                    
           e.filter.filters.push({field:"SERIAL_NO",operator:""+operator+"",value: c})
                }

            } else {
                 e.filter.filters.push({field:"SERIAL_NO",operator:""+operator+"",value: e.filter.filters.filter(x=>x.field == "SERIAL_NO")[0].value})
            }
                 
            e.sender.dataSource.filter(e.filter);
        }
               }  //else e.filter is not null
    }                    
ADMIN
Mihaela
Posted on: 31 May 2022 08:37

Hi Marianne,

Thank you for providing this information and the code snippet.

We have discussed the scenario with the team, and here is our feedback:

  1. UI implementation - can be achieved by integrating the MultiSelect control in the column filter menu, as is demonstrated in the following KB article:

https://docs.telerik.com/kendo-ui/knowledge-base/multiselect-used-for-column-filtering

Also, the users can add new options to the MultiSelect: https://demos.telerik.com/kendo-ui/multiselect/addnewitem

Alternatively, the filter menu form element can be accessed and customized based on your needs in the "filterMenuInit" event of the Grid.

If the comma-separated approach in the "filter" event handler does not work as per your requirements, you could try integrating the MultiSelect through the columns.filterable.ui option:

  $(document).ready(function () {
        var grid = $("#grid").data("kendoGrid"); // Get an instance of the Grid
        var gridColumns = grid.columns; //get the current grid columns options
        gridColumns[1].filterable = { //set the "filterable" options of the 3rd column "SERIAL_NO"
            ui: addMultiSelectFilter,
            extra: false,
            operators: { 
                string: {
                    contains: "In List"
                }
            }
        };
        grid.setOptions({ //update the grid column settings
            columns: gridColumns
        });
    });

function addMultiSelectFilter(element) {
  element.kendoMultiSelect({
    filter: "contains",
    dataTextField: "..",
    dataValueField: "...",
    dataSource: ...,
    noDataTemplate: ...
    ...
  });
}

 

2. Filter logic - Generally, operator "IN" can be replaced by multiple "OR" statements. When passing multiple filter expressions (the MultiSelect values or the comma-separated list values) with logic "OR" to the filter() method of the DataSource, the data will be filtered as expected.

I hope these suggestions will help you extend the current custom logic if needed. If you have any queries, you are more than welcome to share them.

We appreciate your spending time on this topic.


Regards, Mihaela Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Marianne
Posted on: 24 May 2022 16:27

Thank you for asking.  I've attached a short mockup of a way I think it could be shown and additional information on how we are hacking to get the "IN".  If this does not provide the information you need, please let me know.

With the help of Telerik experts, I was able to hack the behavior of a SQL "In" condition by adding custom code to the cshtml page. For this particular application, all other column fields only use 1 value; only the serial number column needed multiple values beyond 2 values.

We will tell our users to enter multiple values comma-separated.  They will be using a copy/paste action from lists that come from our external customers. (This is an application to provide our external customers with test data on the components they have purchased from us & there will be many serial numbers included in the report.)

We also did a custom filter menu because for this application, we think having the And/Or will confuse the users since they have the ability to enter multiple items in any condition. A comma-separated list is turned into "OR" operators.

Here is the relevant code in what we are doing:

                    

<div id="griddiv">
    @(Html.Kendo().Grid<HPK_DATA>(Model.testdata)    
    .Name("grid")
    .Columns(columns => {
       columns.LoadSettings(Model.columns);
    })
    .Events(ev=>{
        ev.Filter("onFilter");
        //ev.FilterMenuInit("filterMenuInit");
    })
    .Pageable()
    .Sortable()
    .Scrollable()
    .Filterable()
    .Resizable(r => r.Columns(true))
    .DataSource(dataSource => dataSource
        .Ajax()
        .PageSize(20)
        .Read(read => read.Url(Url.Action()+"?handler=Read").Data("forgeryToken"))
     )
)
</div>

  $(document).ready(function () {
        var grid = $("#grid").data("kendoGrid"); // Get an instance of the Grid
        var gridColumns = grid.columns; //get the current grid columns options
      //  alert("This is gridColumns 2 " + gridColumns[1].title);
        gridColumns[1].filterable = { //set the "filterable" options of the 3rd column "SERIAL_NO"
            extra: false,
            operators: { //specify the operators that should be displayed in the column filter menu. Here you can review the available operators based on the field data type (date, number, string, enum): https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/configuration/filterable.operators
                string: {
                    contains: "Contains",
                    eq: "Equal to",
                    startswith: "Starts With",
                    endswith: "Ends With",
                    neq: "Not Equal to",
                    doesnotcontain: "Doesn't contain",
                    doesnotstartwith: "Does not start with",
                    doesnotendwith: "Does not end with",

                }
            }
        };
        grid.setOptions({ //update the grid column settings
            columns: gridColumns
        });
    });

 

function onFilter(e){
  if(e.filter === null) {
     e.sender.dataSource.filter();
     //this will clear all
      //e.preventDefault()
      //e.sender.dataSource.filter({})
       } else {      
       //come here is not null and then if field is serial no
        if(e.field == "SERIAL_NO"){
           var operator = e.filter.filters.filter(x=>x.field == "SERIAL_NO")[0].operator;
          var searchcondition = (e.filter.filters.filter(x=>x.field == "SERIAL_NO")[0].value);
            var isComma = searchcondition.includes(",");
             e.preventDefault()
             e.filter.logic = "or";
            if(isComma) {
                const conditions = searchcondition.split(",");
                for(i = 0; i<conditions.length; i++) {
                    var c = conditions[i].trim();                    
           e.filter.filters.push({field:"SERIAL_NO",operator:""+operator+"",value: c})
                }

            } else {
                 e.filter.filters.push({field:"SERIAL_NO",operator:""+operator+"",value: e.filter.filters.filter(x=>x.field == "SERIAL_NO")[0].value})
            }
    e.filter.filters.filter(x=>x.field == "SERIAL_NO")[0].value})
            e.sender.dataSource.filter(e.filter);
        }
               }  //else e.filter is not null
    }

Attached Files:
ADMIN
Mihaela
Posted on: 24 May 2022 10:43

Hello Marianne,

Thank you for the examples.

Should the "IN" operator be available in the UI Filter menu of the Grid? If yes, would you please share a mockup so we can get a better idea of how it should be displayed? 

Thank you for your cooperation.

 

Regards, Mihaela Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.