Search code examples
javascriptknockout.jsradio-buttonform-control

Knockout.js: Set radio button value onload


Please see my fiddle here

I have a couple of radio buttons and depending if one of them is selected I want a text box to then show. I have been able to achieve this using knockout.

What I want to happen is when the page loads, if the value of the "Timesheet" radio button is checked I want the text box to show. But I've been unable to work out how to do this. Thanks is advance.

See below my knockout code:

function K2ConsultantApprovalViewModel() {
  var self = this;
  self.timeSheetSelected = ko.observable("");
}
ko.applyBindings(new K2ConsultantApprovalViewModel());

Solution

  • If the checked binding is applied to a radio button, it will set the element to be checked when the parameter value equals that of the radio button element's value attribute. So you need to slightly change your way of thinking and create a "payment type" observable that stores the chosen payment type, rather than the boolean "is timesheet selected?" observable that you have now. You can then initially give this observable the value "Timesheet", and that will be what is selected on page load. It also makes it trivial to show or hide any other elements based on the current selection.

    function K2ConsultantApprovalViewModel() {
      var self = this;
      self.paymentType = ko.observable("Timesheet");
    }
    
    ko.applyBindings(new K2ConsultantApprovalViewModel());
    

    And binding would look like this:

    <input id="DisbursementsOrTimeSheet_ChoiceField0" type="radio" name="DisbursementsOrTimeSheetChoice" value="Disbursements" data-bind="checked: paymentType">
    

    Update Fiddle here.

    Update

    I would not recommend this since it's a backwards way of working, but if the initial value of your checked binding has to come from the input element itself, you could create a small binding handler that is executed before the checked binding.

    ko.bindingHandlers['initChecked'] = {
        init: function (element, valueAccessor, allBindings) {
            var checked = valueAccessor();
            if (element.checked) {
                checked(element.value);
            }
      }
    };
    

    Then bind like this:

    <input id="DisbursementsOrTimeSheet_ChoiceField1" type="radio" name="DisbursementsOrTimeSheetChoice" value="Timesheet" data-bind="initChecked: paymentType, checked: paymentType" checked="checked">
    

    It will work (proof). But the proper way to do this would be to get the data in the view model and, as someone well put it in the comments, cut out the middle man.