http://stackoverflow.com/questions/43243768/knockoutjs-radio-button-group-custom-binding-not-updating-on-selection

by jlspake

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>

  <div 
    data-bind="
      radioButtons: letters, 
      groupName: 'letters',        
      radioButtonValue: 'value',   
      radioButtonText: 'text',   
      value: value,         
  "></div>
  
  <span data-bind="text: ko.toJSON(value)"/>

JavaScript

ko.bindingHandlers.radioButtons = {
  init: function(element, valueAccessor, allBindings){
  	var unwrappedArray = ko.utils.unwrapObservable(valueAccessor());
    var value = allBindings().value;
    
    ko.utils.registerEventHandler(element, "click", function(event){
    	var target = event.target;
      if(target.nodeName.toLowerCase() == "input"){
    		value($(target).attr("value"));
      }
    });
  },
  update: function (element, valueAccessor, allBindings) {
    console.log("update: start"); 
    var unwrappedArray = ko.utils.unwrapObservable(valueAccessor());
    var previousSelectedValue = ko.utils.unwrapObservable(allBindings().value);


    // Helper function
    var applyToObject = function (object, predicate, defaultValue) {
      var predicateType = typeof predicate;
      if (predicateType == "function")    // Given a function; run it against the data value
        return predicate(object);
      else if (predicateType == "string") // Given a string; treat it as a property name on the data value
        return object[predicate];
      else                                // Given no optionsText arg; use the data value itself
        return defaultValue;
    };

    // Map the array to a newly created label and input.
    var isFirstPass = true;
    var radioButtonForArrayItem = function (arrayEntry, index, oldOptions) {
      if (oldOptions.length) {
        var item = oldOptions[0];
        if ($(item).is(":checked"))
          previousSelectedValue = item.value;

        isFirstPass = false;
      }

      var input = element.ownerDocument.createElement("input");
      input.type = "radio";

      var radioButtonGroupName = allBindings.get("groupName");
      input.name = radioButtonGroupName;

      if (isFirstPass) {
        var selectedValue = ko.utils.unwrapObservable(allBindings.get("value"));
        var itemValue = ko.utils.unwrapObservable(arrayEntry.value);
        if (selectedValue === itemValue) {
          input.checked = true;
     ...