I have two ajax calls. One to load release cycles in first dropdown and another to load scenarios in second dropdown. The scenarios in the second dropdown correspond to the value selected in first dropdown. I am unable to load both on page load. I have to go and select the value by clicking an option in the first dropdown, only then the options in the second dropdown get loaded. How can I achieve this functionality on page load and not by manually selecting or triggering that event.. I do not wish to use ko handlers. Thank you for help in advance.
//load release cycles in first dropdown
self.pushReleaseCycles = function(releaseCycleUrl,scenarioNameUrl1,scenarioNameUrl2){
$.ajax({
url: sharepointScenarioListUrl + releaseCycleUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var items = data.d.results;
items.forEach( function(item) {
if (self.release_cycles.indexOf(item.Release_x0020_Cycle) == -1) {
self.release_cycles.push(item.Release_x0020_Cycle);
}
});
self.selectedCycle.subscribe(function(value) {
self.scenarios([]);
self.pushScenariosToDropdown(value,scenarioNameUrl1,scenarioNameUrl2);
});
},
error: function (data) {
alert("ERROR in function pushReleaseCycles : " + data);console.log(data);
}
});
};
//load scenarios in second dropdown
self.pushScenariosToDropdown = function(value,scenarioNameUrl1,scenarioNameUrl2){
$.ajax( {
url: sharepointScenarioListUrl + scenarioNameUrl1 + value + scenarioNameUrl2,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var items = data.d.results;
items.forEach( function(item) {
self.scenarios.push(new ScenarioModel(item));
console.log(data);
});
self.selectedScenario.subscribe(function(value) {
dbName = ko.toJSON(value.title);
jarFile1 = ko.toJSON(value.jar);
fdMimoAvailable = ko.toJSON(value.fdmimo);
self.setValues(dbName,jarFile1,fdMimoAvailable);
});
},
error: function (data) {
alert("ERROR in function pushScenariosToDropdown: " + data);console.log(data);
}
});
};
My HTML:
<select id="dropdown" required class="form-control select2" data-bind="options: release_cycles,value:selectedCycle">
</select>
<select id="dropdown2" required="required" class="form-control select2" data-bind="options: scenarios, optionsText:'scenarioName',optionsCaption:'Please Select Scenario', value:selectedScenario,validationOptions: { errorElementClass:'input-validation-error' },selectedOptions: chosenScenario">
</select>
If you don't want to go retrieve the values from the server for the second select box based on the values of the first, but want to load the whole data set, then just load a json object of all of the options for the second box and then parse through that after the first selection. If it's a lot of data though, it's going to impact performance.
The way I would handle this is to change how the data is pulled from the server. You will want to include the entire menu structure as needed for the page. In my opinion it's better to have a slightly longer load than a choppy experience. Here's an example of nesting the menus and how that might look.
function ViewModel() {
var self = this;
self.Dropdown1 = ko.observableArray();
self.SelectedItem1 = ko.observable();
self.Dropdown2 = ko.computed(function() {
if (self.SelectedItem1() == null) {
return [];
};
console.log(ko.toJS(self.SelectedItem1()))
return self.SelectedItem1().Submenu;
});
self.SelectedItem2 = ko.observable();
self.LoadDropDown = function() {
self.Dropdown1.push({
"Name": "Hat",
"Value": "top",
"Submenu": [{
"Name": "Blue",
"Value": "#0000FF"
},
{
"Name": "Green",
"Value": "#00FF00"
},
{
"Name": "Red",
"Value": "#FF0000"
}
]
});
self.Dropdown1.push({
"Name": "Shirt",
"Value": "middle",
"Submenu": [{
"Name": "Striped",
"Value": "Striped"
},
{
"Name": "Logo",
"Value": "Logo"
},
{
"Name": "Plain",
"Value": "None"
}
]
});
self.Dropdown1.push({
"Name": "Pants",
"Value": "bottom",
"Submenu": [{
"Name": "Jeans",
"Value": "Jeans"
},
{
"Name": "Kakhis",
"Value": "Kakhis"
},
{
"Name": "Cordroy",
"Value": "Cordroy"
}
]
});
}
self.LoadDropDown();
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="options: Dropdown1, optionsText: 'Name', value: SelectedItem1"></select>
<select data-bind="options: Dropdown2, optionsText: 'Name', value: SelectedItem2"></select>
</div>