I wanted some persistence with Cascading Combo Boxes when using an AJAX data binding.
The solution also needed to be able to pass a 'selected value from the controller handling the data retrieval.
This is what i came up with, hopefully this is useful to someone else aswell
cshtml
Only thing of note here is the jQuery DataBound event that will handle getting the selected value and setting it
ToolsController.cs
Additional bool coloumn in select that will return true only if selected Client/Package Id is = to session var
JS ondatabound events
These functions are called when data is bound to the combo boxes. They get the data object from the AJAX call and return an array of objects, using jQuery Grep, where selected is === true then use the first object found to populate select a default value from the combo.
I initially tried compacting these two functions into one abstracted function and passing the jquery selector reference and selectedObject[].property as variables in the event handler. Evidently passing variable eg (.Events(e => e.DataBound("onDataBoundPackage('var1', 'var2')")) in the databound event handler breaks the databinding.
The solution also needed to be able to pass a 'selected value from the controller handling the data retrieval.
This is what i came up with, hopefully this is useful to someone else aswell
cshtml
Only thing of note here is the jQuery DataBound event that will handle getting the selected value and setting it
<label for="Client">Client</label> @(Html.Kendo().ComboBox() .Name("Client") .Placeholder("Select Client...") .DataTextField("ClientName") .DataValueField("ClientID") .Events(e => e.DataBound("onDataBoundClient")) .DataSource(source => { source.Read(read => { read.Action("GetClientsCombo", "Tools"); }); }) ) <label for="Package">Package</label> @(Html.Kendo().ComboBox() .Name("Package") .Placeholder("Select Package...") .DataTextField("PackageName") .DataValueField("PackageID") .Events(e => e.DataBound("onDataBoundPackage")) .DataSource(source => { source.Read(read => { read.Action("GetPackagesCombo", "Tools") .Data("filterPackages"); }) .ServerFiltering(true); }) .Enable(false) .AutoBind(false) .CascadeFrom("Client") )Additional bool coloumn in select that will return true only if selected Client/Package Id is = to session var
public JsonResult GetClientsCombo() { int selectedClientId = Session["selectedClientId"]; var query = //Linq Query to get results select new { ClientID = LinqClientIdColumn, ClientName = LinqClientNameColumn, Selected = LinqClientIdColumn == selectedClientId }; return Json(query, JsonRequestBehavior.AllowGet); } public JsonResult GetPackagesCombo(int clients, string packageFilter) { int selectedPackageId = Session["selectedPackageId"]; var query = //Linq Query to get results select new { PackageID = LinqPackageIdColumn, PackageName = LinqPackageNameColumn, Selected = LinqPackageIdColumn == selectedPackageId }; return Json(query, JsonRequestBehavior.AllowGet); }These functions are called when data is bound to the combo boxes. They get the data object from the AJAX call and return an array of objects, using jQuery Grep, where selected is === true then use the first object found to populate select a default value from the combo.
I initially tried compacting these two functions into one abstracted function and passing the jquery selector reference and selectedObject[].property as variables in the event handler. Evidently passing variable eg (.Events(e => e.DataBound("onDataBoundPackage('var1', 'var2')")) in the databound event handler breaks the databinding.
function onDataBoundClient() { var DataObject = $("#Client").data("kendoComboBox").dataSource.data(); var selectedObject = $.grep(DataObject, function (obj) { return obj.Selected === true; }); $("#Client").data('kendoComboBox').value(selectedObject[0].ClientID); }; function onDataBoundPackage() { var DataObject = $("#Package").data("kendoComboBox").dataSource.data(); var selectedObject = $.grep(DataObject, function (obj) { return obj.Selected === true; }); $("#Package").data('kendoComboBox').value(selectedObject[0].PackageID); };