Reputation: 18965
I have two combo boxes and a grid in my MVC View:
<div id="Products" class="products maintField">
@Html.Label("something", "Product:")
@(Html.Telerik().ComboBox().Name("productList")
.AutoFill(true)
.DataBinding(c => c.Ajax().Select("GetProducts", "Maintenance").Enabled(true).Cache(true))
.Filterable(c => c.FilterMode(AutoCompleteFilterMode.StartsWith).Enabled(true))
.HighlightFirstMatch(true)
.ClientEvents(eb =>
{
eb.OnChange("productChanged");
})
)
</div>
<div id="Layouts" class="layout maintField">
@Html.Label("something", "Layout:")
@(Html.Telerik().ComboBox().Name("layoutList")
.ClientEvents(eb =>
{
eb.OnChange("layoutChanged");
})
)
</div>
<div style="clear: both;"/>
<div class="fields">
@(Html.Telerik().Grid<MaintenanceModel>().Name("fieldList")
.DataBinding(bc =>
{
bc.Ajax().Select("GetProductFields", "Maintenance", new { prodID = 0, layoutID = 0 }).Enabled(true);
})
.ClientEvents(c =>
{
c.OnDataBound("fieldGridBound");
})
.Columns(c =>
{
c.Bound(mm => mm.Field_ID).ClientTemplate("<input id='Field_ID_<#= Field_ID #>' type='checkbox' name='checkedRecords' class=\"checkBoxGroup\" value='<#= Field_ID #>' />")
.Title("<input id='mastercheckbox' type='checkbox' style='display:none;' />")
.HeaderHtmlAttributes(new { style = "text-align: center;" })
.Width(36)
.HtmlAttributes(new { style = "text-align:center" });
c.Bound(fld => fld.Field_Name).Title("Field Name").Width(225);
c.Bound(fld => fld.Field_Description).Title("Field Description");
}).Scrollable(c =>
{
c.Enabled(true);
c.Height(700);
}).Footer(false).Sortable(c =>
{
c.Enabled(false);
c.OrderBy(oc =>
{
oc.Add(fld => fld.SeqNbr);
});
})
)
</div>
And with some less than beautiful JS the comboboxes cascade and eventually populate the grid:
function productChanged(e) {
clearLayout();
var layoutCombo = $("#layoutList").data('tComboBox');
if (layoutCombo == null) {
alert("Can't find layoutList");
return;
}
if (e.value == "" || e.value == null) {
clearLayout();
return;
}
layoutCombo.loader.showBusy();
$.get('@Url.Action("GetProductLayouts", "Maintenance")', { prodID: e.value }, function (result) {
layoutCombo.dataBind(result);
layoutCombo.loader.hideBusy();
});
}
function layoutChanged(e) {
var prodCombo = $("#productList").data('tComboBox');
var fieldGrid = $("#fieldList").data('tGrid');
if (fieldGrid == null) {
alert("Can't find fieldList");
}
if (prodCombo == null) {
alert("Can't find prodCombo");
}
if (e.value == "" || e.value == null) {
clearGrid();
return;
}
fieldGrid.rebind({ prodID: prodCombo.value(), layoutID: e.value });
$("#mastercheckbox").css("display", "block");
}
function fieldGridBound(e) {
var prodCombo = $("#productList").data('tComboBox');
var layoutCombo = $("#layoutList").data('tComboBox');
$.get('@Url.Action("GetLayoutFields", "Maintenance")', { prodID: prodCombo.value(), layoutID: layoutCombo.value() }, function (result) {
var cbGroup = $(".checkBoxGroup");
$(cbGroup).each(function (i, e) {
if (result.indexOf(e.value) >= 0) {
$(e).attr('checked', 'checked');
} else {
$(e).removeAttr('checked');
}
});
});
}
This works beautifully except in the situation where the two combo boxes are filled, the grid is bound, and the user goes to select a different value from the first combo box. The second combo box rebinds as expected, but if the values bound to the combobox didn't change (in position or display value) and the user selects the same item again, the change event doesn't get fired.
Specific example
In the database I have a hierarchy of Products and Layouts:
Product A
Platinum Layout
Gold Layout
Silver Layout
Product B
Platinum Layout
Gold Layout
Silver Layout
Product C
Platinum Layout
Silver Layout
Scenario 1
Scenario 2
Scenario 3
In order to try to force the combo box to forget which item was selected prior to being rebound, I've tried manually setting the selected item to -1 (nothing) before binding using:
layoutCombo.select(-1);
and I've also tried reloading the combo box after the bind using
layoutCombo.reload();
However neither of them worked for me.
Has anyone else seen this behavior under similar circumstances? Is there any way to clear the combo box's last selected item variable manually from within my page (without digging around in the Telerik source)?
Upvotes: 1
Views: 2816
Reputation: 18965
After playing with it a little more and hoping it would just work, it looks like it works if I fire the change event manually after layoutCombo.select(-1)
and before I force the dataBind on the second combo box. Here's what my productChanged
code looks like now:
function productChanged(e) {
clearLayout();
var layoutCombo = $("#layoutList").data('tComboBox');
if (layoutCombo == null) {
alert("Can't find layoutList");
return;
}
if (e.value == "" || e.value == null) {
clearLayout();
return;
}
layoutCombo.loader.showBusy();
$.get('@Url.Action("GetProductLayouts", "Maintenance")', { prodID: e.value }, function (result) {
layoutCombo.select(-1);
layoutCombo.trigger.change(); //**** Trigger the change manually so the combobox knows its value has changed
layoutCombo.dataBind(result);
layoutCombo.loader.hideBusy();
});
//layoutCombo.reload();
}
It feels like a bit of a hack since the combo box should know it's own value already. Any other ideas to make this cleaner would be much appreciated.
Upvotes: 1