How to use custom filter menu on one column when using GridColumnSettings

2 Answers 1558 Views
Filter Grid
Marianne
Top achievements
Rank 1
Iron
Iron
Marianne asked on 17 May 2022, 07:51 PM | edited on 17 May 2022, 07:53 PM

Hello all,

Could someone point me to an example or suggest the best approach for this? The application is asp.net core 5 using Razor.

I am using GridColumnSettings in my grid because there is one SQL table to populate many different pages & we change elements based on the context of use.

On one page, we've added a custom function to the filtering for one column so that we can provide a SQL "IN" condition.  This is working great. However for that one column, can someone suggest how to provide a custom filter menu so that we restrict what options are provided. (Users are going to be confused if they have options on the filter menu that do not work as they expected...)

I've tried a few examples found from searching this site but none seem to work.  Either I got it wrong (for possible) or  because of the columns.LoadSettings<Model.columns> from the server side, it doesn't execute any client side code on the .cshtml page.

I've included the relevant code below.

Any suggestions or examples will be greatly appreciated.  Thank you.

This is the grid on the .cshtml page.

<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()
    .DataSource(dataSource => dataSource
        .Ajax()
        .PageSize(20)
        .Read(read => read.Url(Url.Action()+"?handler=Read").Data("forgeryToken"))
     )
)
</div>

This is a portion of the gridcolumnsetting code for brevity.  The column that needs a custom filter menu is the SERIAL_NO.

  IList<GridColumnSettings> columns = new List<GridColumnSettings>
 {
                  new GridColumnSettings
            {
                Member = "ROWID",
                Title = "Id",
                Visible = false,
                Width = "15px",
                Filterable = true

            },
                   new GridColumnSettings
            {
                Member = "ITEM_NO",
                Title = "Item No.",
                Visible = true,
                Width = "150px",
                Filterable = true

            },
                     new GridColumnSettings
             {
                Member = "SERIAL_NO",
                Title = "Serial No.",
                Visible = true,
                Width = "150px",
                Filterable = true
                               
            },

2 Answers, 1 is accepted

Sort by
0
Mihaela
Telerik team
answered on 20 May 2022, 12:41 PM

Hi Marianne,

Thank you for the extensive information and details.

To customize the filter menu of a specified column, I would suggest updating the filterable column options by using the setOptions() method after the initialization of the Grid:

<script>
    $(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[2].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"
                }
            }
        };
        grid.setOptions({ //update the grid column settings
            columns: gridColumns
        });
    });
</script>

Let me know if this approach works for you.

 

 

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
Top achievements
Rank 1
Iron
Iron
commented on 20 May 2022, 06:17 PM

Perfect! I thought the solution might have something to do with $(document.ready(function() but not familiar enough with how to navigate to and what options are available.

Your solution is doing exactly what I need.

0
Marianne
Top achievements
Rank 1
Iron
Iron
answered on 24 May 2022, 04:38 PM

For anyone that is interested, based on Mihaela's suggestion, this is how we are adding a custom filter menu to grid using a GridColumnSettings.  This application also gets and passes the filters and data to a backend function that creates and downloads a custom report for our external customers.  

@page
@model TestData.Pages.CreateReportModel
@{
    ViewData["Title"] = "Create Test Data Report";
}
@using TestData.Models
@using Kendo.Mvc.UI
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@Html.AntiForgeryToken()

<h1>HPK Data - Create Report</h1>
<p><span style="font-weight: bold;color: red;">@Model.message</span></p>
<p>Use filtering and sorting to locate information - click button when done.</p>
<p>
<form method="post">
    <input type="hidden" id="export-data" name="data" />
    <input type="hidden" id="export-model" name="model" />
    <input type="hidden" id="export-filter" name="filter" />
    <input type="submit" asp-page-handler="ExportServer" class="k-button k-button-increase k-button-solid-primary k-button-solid k-button-md k-rounded-md download" data-format="csv" data-title="CSVTestDataReport" value="&nbsp;&nbsp;&nbsp;&nbsp;Export to CSV&nbsp;&nbsp;&nbsp;&nbsp;" />
 </form>
</p>
<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()
    .Resizable()
    .Filterable()
    .Resizable(r => r.Columns(true))
    .DataSource(dataSource => dataSource
        .Ajax()
        .PageSize(20)
        .Read(read => read.Url(Url.Action()+"?handler=Read").Data("forgeryToken"))
     )
)
</div>


<script>
     var escapeQuoteRegExp = /'/ig;

        $(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 encodeFilterValue(value, encode) {
        if (typeof value === "string") {
            if (value.indexOf('Date(') > -1) {
                value = new Date(parseInt(value.replace(/^\/Date\((.*?)\)\/$/, '$1'), 10));
            } else {
                value = value.replace(escapeQuoteRegExp, "''");

                if (encode) {
                    value = encodeURIComponent(value);
                }

                return "'" + value + "'";
            }
        }

        if (value && value.getTime) {
            return "datetime'" + kendo.format("{0:yyyy-MM-ddTHH-mm-ss}", value) + "'";
        }
        return value;
    }

    function serializeFilter(filter, encode) {
         if (filter.filters) {
            return $.map(filter.filters, function (f) {
                var hasChildren = f.filters && f.filters.length > 1,
                    result = serializeFilter(f, encode);

                if (result && hasChildren) {
                    result = "(" + result + ")";
                }

                return result;
            }).join("~" + filter.logic + "~");
        }

        if (filter.field) {
            return filter.field + "~" + filter.operator + "~" + encodeFilterValue(filter.value, encode);
        } else {
            return undefined;
        }
    }

   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
    }

    $(".download").click(function () {
        var grid = $("#grid").data("kendoGrid");
        var options = {
            format: $(this).data("format"),
            title: "TestData"
        }

        $("#export-data").val(encodeURIComponent(JSON.stringify(options)));
        $("#export-model").val(encodeURIComponent(JSON.stringify(grid.columns)));
        $("#export-filter").val(encodeURIComponent(serializeFilter(grid.dataSource.filter())));
    });


    function forgeryToken() {
        return kendo.antiForgeryTokens();
    }
</script>

                                     
Tags
Filter Grid
Asked by
Marianne
Top achievements
Rank 1
Iron
Iron
Answers by
Mihaela
Telerik team
Marianne
Top achievements
Rank 1
Iron
Iron
Share this question
or