Reputation: 351
I have a multi select component which I have bounded with an 'options' binding, the 'options' get refreshed based on the value I select in another multi select component. Below is the first multi select component
<select data-bind="multiple: true, required: true, options:repositoriesForSelect, value: selectedRepository"></select>
Based on the value selected in this component, am refreshing the options of the second component
<select data-bind=" multiple: true,required: true,options: branchesForSelect,value: selectedBranch"></select>
using the computed variables to refresh the 2nd options:
branchesForSelect = ko.computed(function(){
//selectedRepository is an observable array here
//some logic
});
Which works fine, but in addition to the above, I want to refresh the 'branchesForSelect' based on the values selected in the same component. Meaning, if the 'branchesForSelect' contains values 'A', 'B', 'C', then on select of 'A', I want to refresh 'branchesForSelect' to show only 'C' in the list of options.
Can someone please guide me? please let me know in comments if the question is unclear.
Thanks
Upvotes: 1
Views: 1316
Reputation: 23372
You're on the right track by making the second option list a computed. This is what you still need to do: Inside the computed, use selectedRepository
's value to return an array of options that are linked to the selection. By using this value, knockout will make sure that after the value
variable of the first select changes, the second option list is reevaluated.
After clarification of question in comments:
Changing the values of the select itself after user input is a bad idea from a UX perspective (if you ask me), but can certainly be done. The code below will show you how. When the first option of a multi-select is active, the others get hidden.
Here's an example:
var repositoryBranches = {
a: ["All", 1, 2, 3, 4, 5, 6],
b: ["All", 0, 7, 8],
c: ["All", 9, 10]
};
var VM = function() {
var self = this;
this.repositoryKeys = ["a", "b", "c"];
this.selectedRepository = ko.observable("a");
this.selectedBranches = ko.observableArray([]);
this.branchesForSelectedRepository = ko.computed(function() {
var allBranchesForRepo = repositoryBranches[self.selectedRepository()];
// We're making an exception if the first one is selected:
// don't show any other options if the selected one is the first one
if (self.selectedBranches()[0] === allBranchesForRepo[0]) {
return ["All"];
}
return allBranchesForRepo;
});
// Clear selection when changing repository
this.selectedRepository.subscribe(function clearSelection() {
self.selectedBranches([]);
});
};
ko.applyBindings(new VM());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="options:repositoryKeys, value: selectedRepository"> </select>
<select multiple="true" data-bind="options:branchesForSelectedRepository, selectedOptions: selectedBranches"></select>
(fiddle)
Let me know if you need help finding a nice way to link "branches" to "repositories". Ideally, the "repositories" have their own models that contain an array of "branches". You'd then be able to define your computed array something like return self.firstSelection().branches;
Upvotes: 2