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

Rebind all Grid Filter Drop Downs when Grid re-binds

7 Answers 242 Views
Grid
This is a migrated thread and some comments may be shown as answers.
im
Top achievements
Rank 2
im asked on 24 Jan 2013, 11:04 PM
I have a grid, with filtering enabled, and the dropdown list for the filters is being loaded from a datasource on the server.

column.Bound(o => o.Color).Title("Color").Filterable(filterable => filterable.UI("colorFilter"));
function colorFilter(element) {
element.kendoDropDownList({
     dataSource: {
     transport: {
     read: "@Url.RouteUrl("ProductData", new { action = "FilterMenuCustomization_Colors", controller = "Inventory", catagory = "XYZ" })"
     , type: "POST"
     , data: { catagory: "@ViewData["productType"].ToString()", filters: $("#Products").data.filter }
     }
     },
     optionLabel: "--Select Value--"
});
    }

This works just fine. I actually have 3 columns just like the one above for different values. My question is, how do I programatically re-bind these drop downs once the grid gets rebound? What Im trying to accomplish is if I change one of the filters, I would like the other filters to be changed as well based on the selected filter. Like cascading drop-downs, but they are all mutually exclusive. Its not a direct hierarchy.

So If I can get the drop-downs to rebind (each time the grid data gets bound), I can send the current filtered parameters with it, and change the response options based on that. I hope this makes sense.

7 Answers, 1 is accepted

Sort by
0
Rosen
Telerik team
answered on 28 Jan 2013, 10:05 AM
Hello,

In order to achieve this, you will need to find the element within the appropriate column filter menu and to repopulate its DataSource. The dataBound event of the Grid widget can be use for implementing this. For example:

function  dataBound() {
    var filterMenu = this.thead.find("th[data-field=Color]").data("kendoFilterMenu");
    filterMenu.form.find("input.color").data("kendoDropDownList").dataSource.read();
}

Note that a CSS class is added to the input element in order to get a reference more easily. 

function colorFilter(element) {
    element.addClass("color").kendoDropDownList({
     // ....
    });
}

All the best,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
im
Top achievements
Rank 2
answered on 28 Jan 2013, 04:54 PM
This looks perfect, however when I tried it, I get an error through Firefox Firebug,

"Resuming debugger: error during debugging loop: TypeError: firstViewRangeElement is null"
TypeError: this.thead is undefined

Thanks for getting me this far, it looks promising, I look forward to any updates you may have, and if I find the issue Ill post it, but please advise incase there is something else that may be going on.

--update
Changed the line
var filterMenu = this.thead.find("th[data-field=Color]").data("kendoFilterMenu")
 Added using the jQuery selector
var filterMenu = $("#Products.th[data-field=Color]");
filterMenu seems to get the the correct element. However

$("#Products.th[data-field=Color]").data("kendoFilterMenu") , is still undefined.



0
Rosen
Telerik team
answered on 29 Jan 2013, 07:04 AM
Hello,

Could you please provide the entire Grid declaration as well as the attached handlers code. 

All the best,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
im
Top achievements
Rank 2
answered on 29 Jan 2013, 02:33 PM
Here is the Grid Code...

@(
 Html.Kendo()
        .Grid<ProductData>()
        .Name("Products")
         .Columns(column =>
        {
            column.Bound(o => o.ItemNumber).Title("Item").HtmlAttributes(new { style = "white-space:nowrap;" }).Width(120);
             column.Bound(o => o.Type).Title("Type").Width(100).HeaderHtmlAttributes(new { id = "typecolumn"  }).Filterable(filterable => filterable.UI("typeFilter")).HtmlAttributes(new { style = "white-space:nowrap;text-align:center;" });
            column.Bound(o => o.Size).Title("Size").Width(80).Filterable(filterable => filterable.UI("sizeFilter")).HtmlAttributes(new { style = "white-space:nowrap;text-align:center;" });
 
 
            column.Bound(o => o.MilitarySpec).Title("MIL Spec-NAS").Width(160).HtmlAttributes(new { style = "white-space:nowrap;text-align:center;" }).Sortable(false)
                 .HeaderTemplate((@<text>
@(Html.Kendo().DropDownList().Name("cMILSpecs")
                .Events(ev => ev.Change("onAnyComboChange"))
                    .OptionLabel("MIL Spec-NAS")
                .AutoBind(true)
                .Enable(true)
                .BindTo(Model.MilitarySpecs)
                .HtmlAttributes(new { style = "width:10em;" })
          )
</text>));
 
            column.Bound(o => o.Color).Title("Color").Width(100).Filterable(filterable => filterable.UI("colorFilter")).HtmlAttributes(new { style = "white-space:nowrap;text-align:center;" });
             
..ommitted for brevity
        })
                .Pageable(pager => pager
                    .Refresh(true)
                    .PageSizes(new int[] { 15, 30, 45, 60 }))
                .Sortable()
                .Filterable(filterable => filterable
                    .Extra(false)
                    .Operators(operators => operators
                    .ForString(str => str.Clear()
                    .IsEqualTo("Is equal to")
                ))
        )
 
                .Selectable()
                .Events(e => e
                .Change("onRowSelect")
                .DataBound("onGridBound")
               )
                .ClientDetailTemplateId("productsTemplate")
                .DataSource(dataSource => dataSource
                    .Ajax()
                    .PageSize(15)
                    .Read(read => read.Action(ViewData["productType"].ToString(), "Inventory").Route("ViewProducts")
                    .Type(HttpVerbs.Post))
 
            )
 )
Then the handlers code as well (some are left out for brevity, but nothing that should change what Im trying to accomplish.)

function rebindFilters() {
           alert("rebind");
 
           //var filterMenu = this.thead.find("th[data-field=Color]").data("kendoFilterMenu");
           var filterMenu = $("#Products.th[data-field=Size]").data("kendoFilterMenu");
            
           if (filterMenu) {
               filterMenu.form.find("input.size").data("kendoDropDownList").dataSource.read();
               alert("read color");
           }
           //$("#Products.th[data-field=Size]").data("kendoFilterMenu").dataSource.read();
       }
       function onGridBound() {
           rebindFilters();
                   }
       function typeFilter(element) {
           element.addClass("type").kendoDropDownList({
               dataSource: {
                   transport: {
                       read: "@Url.RouteUrl("ProductData", new { action = "FilterMenuCustomization_Types", controller = "Inventory", catagory = "SMT" })"
                       , type: "POST"
                       , data: { catagory: "@ViewData["productType"].ToString()", filters: $("#Products").data.filter }
 
                   }
               },
               dataBound: function (e) {
                 //  alert("type bound");
               },
 
               optionLabel: "--Select Value--"
           });
       }
 
       function sizeFilter(element) {
           element.addClass("size").kendoDropDownList({
               dataSource: {
                   transport: {
                       read: "@Url.RouteUrl("ProductData", new { action = "FilterMenuCustomization_Sizes", controller = "Inventory", catagory = "SMT", type = "B2" })"
                       , type: "POST"
                      , data: { catagory: "@ViewData["productType"].ToString()", filters: $("#Products").data.filter }
                   }
               }, dataBound: function (e) {
                //   alert("size bound");
               },
               optionLabel: "--Select Value--"
           });
       }
       function colorFilter(element) {
           element.addClass("color").kendoDropDownList({
               dataSource: {
                   transport: {
                       read: "@Url.RouteUrl("ProductData", new { action = "FilterMenuCustomization_Colors", controller = "Inventory", catagory = "SMT" })"
                       , type: "POST"
                      , data: { catagory: "@ViewData["productType"].ToString()", filters: $("#Products").data.filter }
                   }
               }, dataBound: function (e) {
                    // alert("color bound");
               },
               optionLabel: "--Select Value--"
           });
       }

I was only working with one of the filters to start to see if I can get it to work, but I would extend the rebind filters to call all 3 , Type Size, color .. to rebind, and sending the current filters for the grid when they do, ao each can mutually filter by either. I hope this makes sense.


0
Rosen
Telerik team
answered on 30 Jan 2013, 08:01 AM
Hi,

I have look at the code you have provided.

The following construct

this.thead.find("th[data-field=Color]")

will not work as the rebindFilters function is executed in the global scope instead of the Grid widget scope (as with the event handler). Thus, there is no thead field attached to the window object (the this in the rebindFilters). In order to correct this you should get the Grid instance and call the thead on it.

Regarding the $("#Products.th[data-field=Size]") selector. It will not work as there is a dot between the id part and the th. As you may know the dot is used as a class selector. Removing the dot should address the issue.
Greetings,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
im
Top achievements
Rank 2
answered on 31 Jan 2013, 02:55 AM
Thanks,

This has really helped me, and I hate it when I miss the little things like a "." in the middle of everything else.

I have one last question. within each of the dropdowmlist function I am also trying to send the filters for the grid. This way, the response, will do server filterin of the available options. I have tried the following... The data just doesnt go through the post, to be read on the server side. Tried the content type json, and the Telerik GridCommand to receive oin the controller side... based on the examples. Nothing yet.

Please advise.


function sizeFilter(element) {
    element.addClass("size").kendoDropDownList({
        dataSource: {
            transport: {
                read: {
                    url: "@Url.RouteUrl("ProductData", new { action = "FilterMenuCustomization_Sizes", controller = "Inventory" })",
                    contentType: "application/json; charset=utf-8",
                    type: "POST",
                    parameterMap: function (options) {
                        var filters = $("#Products").data("kendoGrid").dataSource.filter();
                        var result = {};
                        if (filters) {
                            result["filter.logic"] = filters.logic;
 
                            for (var idx = 0, length = filters.length; idx < length; idx++) {
                                result["filter.filters[" + idx + "].operator"] = filters[idx].operator;
                                result["filter.filters[" + idx + "].field"] = filters[idx].field;
                                result["filter.filters[" + idx + "].value"] = filters[idx].value;
                            }
                        }
                        return result;
                    },
                   // data: {  command: kendo.stringify($("#Products").data("kendoGrid").dataSource.filter()) }
                }
                ,serverFiltering: true
            }
        },
        optionLabel: "--Select Value--"
    });
}
0
Rosen
Telerik team
answered on 31 Jan 2013, 07:12 AM
Hi,

As you may know the parameterMap is property of the transport not of the its operations, which is the way set in the code you have pasted. Moving it to the appropriate place should resolve the issue.

Regards,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
Grid
Asked by
im
Top achievements
Rank 2
Answers by
Rosen
Telerik team
im
Top achievements
Rank 2
Share this question
or