I have defined my select as below
<select id="selProductType" data-bind="options: productType , value: editProductType , optionsText: 'Name'" />
Below is my code to fill the select in my view model
// Loading combobox with Product Types
$.getJSON("../RestService/Product/AllProductTypes",
function (allData) {
var mappedProductType = $.map(allData, function (item) {
console.log(item.Id + ' ' + item.Name);
return new productType(item);
});
self.productType(mappedProductType);
});
When i initialise page i want to set default value to select. So i tried below
self.editProductType(4);
But it gives me TypeErrror saying object 4 has no method Id.
How to go about it. I have also gone through similar post in stackoverflow but no luck.
Knockout JS binding initial/default value of dropdown (select) list
If you don't specify the :
optionsValue: 'Id'
in data-bind, the binding value in this case must be an object in productType array.
You can select the default object:
self.editProductType(self.productType()[2]);
What is optionsValue?
Similar to optionsText, you can also pass an additional parameter called optionsValue to specify which of the objects’ properties should be used to set the value attribute on the elements that KO generates. You can also specify a JavaScript function to determine this value. This function will receive the selected item as its only argument and should return a string to use for the element’s value attribute.
Typically you’d only want to use optionsValue as a way of ensuring that KO can correctly retain selection when you update the set of available options. For example, if you’re repeatedly getting a list of “car” objects via Ajax calls and want to ensure that the selected car is preserved, you might need to set optionsValue to "carId" or whatever unique identifier each “car” object has, otherwise KO won’t necessarily know which of the previous “car” objects corresponds to which of the new ones.
read more at: http://knockoutjs.com/documentation/options-binding.html
Related
I wonder if there is a way to get a certain element of an array, which is stored in a single value. Sounds weird, I know, but this is my problem:
HTML
<select id="select">
<option value='{"array":["a","b"]}'>Option</option>
</select>
<button onClick="getArrayIndex()">Button</button>
--> I got one array with two elements (a and b) stored isnide one value in an option tag.
JS
function getArrayIndex() {
alert(option.value[0]);
}
So what I need is that the alert message displays only one element of the array, I hope this is somehow possible, thanks for answers! As you can see I tried to display only element 0, in this case "a", but it doesn't work.
I also tried these:
alert(option.value.array[0]);
alert(option.value.array(0));
alert(option.value(0));
alert(option.value.[0]);
...and so on. But none of these work.
Your value is a string containing JSON defining an object containing an array property with an array, rather than actually being an array. To use just the first element in that array, you need to parse the JSON into the object and array, then access the array from the object and get its first element:
alert(JSON.parse(option.value).array[0]); // "a"
Note that your getArrayIndex function currently uses an option identifier that doesn't appear to be defined anywhere. If you want to use the currently-selected value in the select, then:
function getArrayIndex() {
const select = document.getElementById("select");
const value = select.value;
if (value) {
alert(JSON.parse(value).array[0]);
}
}
Side note: I would xyz-attribute-style event handlers. Instead, hook up the event handler using modern techniques (such as addEventListener). Also beware that the default type of the button element is "submit", so if that button is in a form, by default it will submit the form.
I am trying to bind my selected category's guid property to another ko.observable element. I need to hold that data value in order to send it to the server in a correct JSON format.
Jsfiddle
I am stucked at the binding selected category's guid value to SelectedCategoryGuid in order to appear in JSON file like
'SelectedCategoryGuid': 'guid1'
I have tried $data and $root bindings in the HTML but couldn't achieve it.
Step 1: Remove the quotes around your value data-bind. You should pass a reference to an observable here, not the name of a property.
value: Info.SelectedCategoryGuid
Now, you'll see your guid paragraph print: [object Object]. That's because it's storing the whole category, not just the Guid.
Step 2: To only store the Guid property, use the optionsValue binding. This binding works similar to the optionsText binding you've already used:
optionsValue: 'Guid'
Now things start working as intended. You'll notice the initial bla value gets cleared, because it does not appear in your data set.
Here's the two changes in a fiddle: https://jsfiddle.net/40sh1vjj/
I have a KO model with a lot of nested objects and collections of nested objects. I use the ko.mappings mapping options to make sure they get properly generated during model creation, but the value gets cleared. Trying to start with a simple drop down menu and bind objects to it:
<select id="myList" name="SelectedSurvey" id="SelectedSurvey" class="form-control"
data-bind="options: AvailableSurveys, optionsText: 'Name', value: SelectedSurvey,
optionsCaption: '-- Select Survey --'"></select>
Then, take some data, when creating a new object on the page, it works fine, but when trying to edit an existing record from the same page, the drop down value is never selected. When I check viewModel.SelectedSurvey() the value is undefined, but it only becomes undefined after I callapplyBindings()`. Why is this happening? How can I fix it?
Here is a working example: http://jsfiddle.net/6wLcr52y/3/
If you open the console and run it, you'll see the log before applyBindings() is called the full ViewModel, and the nested object SelectedSurvey() are properly komapping objects that have values, but then after it's called. SelectedSurvey() becomes undefined and as such my dropdown list never has a selected value.
The SelectedValue parameter doesn't seem to want to accept an object as a valid value. It therefore clears the SelectedValue observable as soon as you apply bindings thinking that no valid value was provided.
As a workaround, I created a solution that uses the optionsValue parameter to accept the 'Id' property as a value. This will allow you to maintain control over which survey is selected by passing in merely an 'Id' value as opposed to an entire Survey object.
This requires that you update your Knockout version to 3.4.0. Are you locked in to using 2.2.1 for any reason?
I also updated your jsfiddle to include more readable implementation of the mapping plugin. Hopefully this will fix your issue:
var ViewModel = function(data) {
var self = this;
self.AvailableSurveys = ko.mapping.fromJS(data.AvailableSurveys);
self.SelectedId = ko.observable(data.SelectedSurvey.Id);
self.SelectedSurvey = ko.pureComputed(function () {
for (i = 0; i < self.AvailableSurveys().length; i++) {
if (self.AvailableSurveys()[i].Id() === self.SelectedId()) {
return self.AvailableSurveys()[i];
}
}
})
}
Fiddle: http://jsfiddle.net/dw1284/v1L5tw6h/3/
I am working using breeze + knockout using as base hottowel template.
Using this template I am able to make some binding like:
<select data-bind="options: $parent.rolesList, value: role">
Where rolelist it's a ko.observableArray() and role it's a string property. everything it's fine with this example.
My issue begin when I try make some more complex databinding, i.e:
select data-bind="options: mycollection, optionsText: 'dictionary().name()'"></select>
In this new example mycollection it's ko.observableArray() and dictionary().name() it's "object property" plus a string property.
If I go to chrome debuger I can see that mycollection()[0].dictionary().name() has a value.
So I dont' know what I am doing wrong.
Here you are a short example( you can see that I am using just dictionary.name) http://jsfiddle.net/rolandomartinezg/BN2ZP/2/
When passing a string to optionsText, Knockout simply tries to key into your object. It does not handle nested keys or run the string as JavaScript.
However, you can instead choose to pass a function for optionsText which takes in the item as the first argument and you can return whatever value that you like.
For example, in your jsFiddle, you could define a function like:
self.getOptionText = function(item) {
return item.dictionary.name;
};
Then, bind against it like:
<select data-bind="options: myCollection, optionsText: getOptionText"></select>
In your sample from the question, then you would just do item.dictionary().name() if you are dealing with observables.
I'm struggling with Knockout.js Options binding, to an Object.
I'm attempting to create a workflow for the user that allows them to add an Item, edit its properties and then save/cancel to propagate those changes.
I've accomplished this type of task before with jquery. However I'd like to avoid the complicated stack calls that jquery would require. (if possible).
I've created an example:
http://jsfiddle.net/nAE2f/
Whats working in the example:
The Add button, creates a new object.
The Save Button will save it to the array.
The Select Dialog will update with a new Option.
Unfortunately, this is where my progress has halted. While the Select Option is created, it doesn't reflect the underlying objects Name. Also Switching between objects doesn't change the forms properties as I would expect.
I've tried assigning the optionValue to the id, but in that case the Select Options isn't created on save.
The problem with the way you binding member name to item. In your case saved item always has empty name that's why select also display empty text. I fixed this by creating selectedMember property within ViewModel to handle selected member and assigning member name to item on Save.
Check fiddle for example