Reputation: 1796
Looked at a lot of stackoverflow examples but to no avail. I have a javascript array of strings which I wish to map to a ko observableArray, which I then want to apply to a select in my HTML. Here is the main ko object:
actionData: {
json: false,
xml: false,
pdf: false,
word: false,
csv: false,
excel: false,
prophet: false,
editablePdf: false,
editableWord: false,
zip: false,
httpUrl: null,
username: null,
password: null,
connectionTest: false,
requiredAlerts: [],
folder: null,
first: null,
libraries: []
},
Then when my ajax call returns with the data I map it. At this point I have verified that it is happy (see the "first" variable has have the proper data when I look at it the debugger):
var list = JSON.parse(data.libraries);
self.CurrentAction.actionData.libraries = ko.observableArray(list);
//self.CurrentAction.actionData.folder = ko.observable();
self.CurrentAction.actionData.first = ko.observable(list[0]);
var first = self.CurrentAction.actionData.libraries()[0];
Finally in my .CSHTML I do the following:
<div class="row">
<div class="col-xs-12 col-sm-10 col-sm-offset-2" data-bind="with: CurrentAction.actionData">
<div class="checkbox"><label><input class="format-checkbox" type="checkbox" data-bind="checked: editablePdf"> Make PDF document editable</label></div>
<div class="checkbox"><label><input class="format-checkbox" type="checkbox" data-bind="checked: editableWord"> Make Word document editable</label></div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6" data-bind="with: CurrentAction.actionData">
<label>LIB</label>
<input data-bind="value: first">
</div>
</div>
<div class="col-xs-12" style="padding-left:0px; padding-right:0px">
<label>SharePoint Library</label>
<!-- ko with: CurrentAction.actionData. -->
<select data-bind="options : libraries,
value : folder,
optionsCaption : 'Please choose a SharePoint Library...'"
style="width: 100%; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; border-radius:4px;border:1px solid #AAAAAA;">
</select>
<!-- /ko -->
<p style="font-size: 13px; margin-top: 5px;">Your files will be sent to this library when submitted</p>
</div>
And I get nothing in the select. I have verifies that other elements in the construct are there, but for some reason the "libraries" is not or I am mapping it incorrectly?
UPDATE
Thanks to the great answers below I have figured it all out. Basically I had a few problems:
My actionData
was actually mapping to another object which was missing the library
object. This was due to some other code that I was unaware of. Once I got that fixed the data started to map/bind correctly
Once I had the correct object the library
was already an observeableArray, so there was no need to re-map it to observable. The new code looks like:
if (data.statusCode == "200") {
var list = JSON.parse(data.libraries);
self.CurrentAction.actionData.libraries(list);
}
The final HTML version looks like this:
<div class="col-xs-12" style="padding-left:0px; padding-right:0px">
<label>SharePoint Library</label>
<select data-bind="options : CurrentAction.actionData.libraries,
value : CurrentAction.actionData.folder,
optionsCaption : 'Please choose a SharePoint Library...'"
style="width: 100%; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; border-radius:4px;border:1px solid #AAAAAA;">
<option data-bind="text: Name"></option>
</select>
<p style="font-size: 13px; margin-top: 5px;">Your files will be sent to this library when submitted</p>
</div>
Many thanks for the great answers!
Upvotes: 1
Views: 57
Reputation: 5294
I'm not quite following your question but I used your data and mapped it to a select using the options binding it seemed to work ok. run snippet below
var data = {
json: false,
xml: false,
pdf: false,
word: false,
csv: false,
excel: false,
prophet: false,
editablePdf: false,
editableWord: false,
zip: false,
httpUrl: null,
username: null,
password: null,
connectionTest: false,
requiredAlerts: [],
folder: 'three',
first: null,
libraries: ['one', 'two', 'three', 'four', 'five']
}
var viewModel = ko.mapping.fromJS(data);
$(document).ready(function() {
ko.applyBindings(viewModel);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<select data-bind="options : libraries,
value : folder,
optionsCaption : 'Please choose a SharePoint Library...'" style="width: 100%; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; border-radius:4px;border:1px solid #AAAAAA;">
</select>
Upvotes: 1