Reputation: 179
I have two dropdowns one depending on other (cascading). The selection on the ‘MainCategories’ decides the items for ‘SubCategories’. Also, the selection on the ‘MainCategories’ decides the visibility of a table row as well. The following is what I tried:
<table>
<tbody data-bind="foreach: contacts">
<tr>
<td>MainCategories:
<select data-bind='options: MyCategories, value: mycategory, optionsText: "Type", optionsValue: "Type",optionsCaption: "Select..."'></select>
</td>
<td>
<!-- ko with: mycategory -->SubCategories:
<select data-bind='options: Categories, optionsText: "Category", optionsCaption: "Select...", value: $parent.product'></select>
<!-- /ko -->
</td>
</tr>
<tr data-bind="visible:mycategory()=='Type1'">
<td>I am visible</td>
</tr>
</tbody>
</table>
<script type = "text/javascript" >
var MyCategories = [{
"Categories": [{
"Category": "Category1"
}, {
"Category": "Category2"
}],
"Type": "Type1"
}, {
"Categories": [{
"Category": "Category3"
}, {
"Category": "Category4"
}],
"Type": "Type2"
}];
var initialData = [{
category: "Mobile",
product: "Nokia"
}];
var ContactsModel = function (contacts) {
var self = this;
self.contacts = ko.observableArray(ko.utils.arrayMap(contacts, function (contact) {
return {
mycategory: ko.observable(contact.category),
product: ko.observable(contact.product)
};
}));
};
ko.applyBindings(new ContactsModel(initialData));
</script>
If I remove optionsValue: "Type", then the ‘SubCategories’ gets the right items. But the visibility of the table row is not working as expected. If I have optionsValue: "Type", then the ‘SubCategories’ is not getting populated. And also, when I change the options of ‘MainCategories’ 1 or 2 times, then only the visibility is working fine.
Please help me find what I am doing wrong here. Thanks,
Upvotes: 2
Views: 1854
Reputation: 14995
I read your question and I have a feeling that this will answer it if not address it enough that you can apply it -
*Problem * -
You need to have a cascading dropdown using Knockout to select a value and set your observable equal to the child select's selected object.
*Solution * -
Use a computed to make the second dropdown dependent on the first. Example -
var selectedParent = ko.observable();
var parentCategories = ko.observableArray(MyCategories);
var childCategories = ko.computed(function () {
if (!selectedParent()) { return new Array(); }
var childArray = [];
// get the values you want for the child here
return childArray;
});
By adding if (!selectedParent()) you are making the childCategories dependent on the selectedParent. Whenever the selection changes the childCategories will automatically update.
Then your view can be something like this -
<td>MainCategories:
<select data-bind='options: parentCategories, value: selectedParent, optionsText: "Type", optionsValue: "Type",optionsCaption: "Select..."'></select>
</td>
<td> SubCategories:
<select data-bind='options: childCategories, optionsText: "Category", optionsCaption: "Select...", value: $parent.product'></select>
<!-- /ko -->
</td>
Upvotes: 2