I would like to loop through an array that I define in my Javascript and render a list of radio buttons. My code which isn't working currently, and it is as follows (also on jsfiddle):
<div data-bind="foreach: options" >
<div>
<input type="radio" name="optionsGroup" data-bind="checked: selected" />
<span data-bind="text: label"></span>
</div>
</div>
var optionsList = [
{"value": "a","label": "apple"},
{"value": "b","label": "banana"},
{"value": "c","label": "carrot"}
];
function viewModel() {
var self = this;
self.options = optionsList;
self.selected = ko.observable("a");
self.selected.subscribe(function(newValue) {
alert("new value is " + newValue);
});
}
ko.applyBindings(new viewModel());
If my array is part of the html then it works fine, see this (or jsfiddle):
<div>
<input type="radio" name="optionsGroup" value="a" data-bind="checked: selected" />Apple
</div>
<div>
<input type="radio" name="optionsGroup" value="b" data-bind="checked: selected" />Banana
</div>
<div>
<input type="radio" name="optionsGroup" value="c" data-bind="checked: selected" />Carrot
</div>
<div data-bind="text: selected">
</div>
function viewModel() {
var self = this;
self.selected = ko.observable("a");
self.selected.subscribe(function(newValue) {
alert("new value is " + newValue);
});
}
ko.applyBindings(new viewModel());
I got this to work by generating the all of the html within my javascript and have this working using checkboxes, but am stumped generating a group of radiobuttons using the foreach iterator.
Has anyone gotten an example like my first one to work?
Defining Radio Group in HTML We can define a group for radio buttons by giving each radio button the same name. As and when the user selects a particular option from this group, other options are deselected. Following is an example of radio buttons with different names within a form.
Only one radio button in a group can be selected at the same time. Note: The radio group must have share the same name (the value of the name attribute) to be treated as a group.
You group radio buttons by drawing them inside a container such as a Panel control, a GroupBox control, or a form. All radio buttons that are added directly to a form become one group. To add separate groups, you must place them inside panels or group boxes.
We can put different radio buttons in a group using the name attribute. All the buttons in a group must have the same name attribute.
Here's one way to do this. Note that the attr
binding should come before the checked
binding.
var optionsList = [
{"value": "a", "label": "apple"},
{"value": "b", "label": "banana"},
{"value": "c", "label": "carrot"}
];
function viewModel() {
this.options = optionsList;
this.selected = ko.observable("a");
}
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h3>Fruits</h3>
<div data-bind="foreach: options" >
<label>
<input type="radio"
name="optionsGroup"
data-bind="attr: {value: value}, checked: $root.selected" />
<span data-bind="text: label"></span>
</label>
</div>
<h3>Selected value:</h3>
<pre data-bind="text: ko.toJSON($root.selected)"></pre>
Your code is giving this error:
Message: ReferenceError: selected is not defined;
Bindings value: checked: selected
You defined selected
on the view model level, but you are referencing it inside foreach
so Knockout.js is looking for it on the options level.
Change:
<div><input type="radio" name="optionsGroup" data-bind="checked: selected" />
to:
<div><input type="radio" name="optionsGroup" data-bind="checked: $root.selected" />
$root.selected
will look for the selected
property on the view model level.
HERE is the modified code.
For more information about pseudo-variables (like $root
) see 3. Access to parent binding contexts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With