JSFiddle - React, Tailwind, and code Playground

by tyrsius

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.3.5/knockout.mapping.js"></script>
<!-- ko foreach: people -->
    <div style="margin-bottom: 20px">
        <input type="text" data-bind="value: name" />
        <h2>Gender:</h2>
        <input type="radio" data-bind="checked: gender, attr: { name: 'gender-' + id() }, uniqueId: gender, uniqueMod: 'male'" value="1" /><label data-bind="uniqueFor: gender, uniqueMod: 'male'">Male</label>
        <input type="radio" data-bind="checked: gender, attr: { name: 'gender-' + id() }, uniqueId: gender, uniqueMod: 'female'" value="2" /><label data-bind="uniqueFor: gender, uniqueMod: 'female'">Female</label>
    </div>
<!-- /ko -->

JavaScript

ko.bindingHandlers.uniqueId = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        var value = valueAccessor();
        var idMod = 'id-' + (allBindingsAccessor().uniqueMod || 0);
        value[idMod] = value[idMod] || ko.bindingHandlers.uniqueId.prefix + (++ko.bindingHandlers.uniqueId.counter);

        element.id= value[idMod];
    },
    counter: 0,
    prefix: "unique"
};

ko.bindingHandlers.uniqueFor = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        var value = valueAccessor();
        var idMod = 'id-' + (allBindingsAccessor().uniqueMod || 0);
        value[idMod] = value[idMod] || ko.bindingHandlers.uniqueId.prefix + (++ko.bindingHandlers.uniqueId.counter);

        element.setAttribute("for", value[idMod]);
    } 
};

var PersonVM = function(data) {
    var self = this;

    self.id = ko.observable(data.id);
    self.name = ko.observable(data.name);
    self.gender = ko.observable(data.gender);
};

var MasterVM = function(data) {
    var self = this;

    var mapping = {
        'people': {
            create: function (options) {
                return new PersonVM(options.data);
            }
        }
    };

    ko.mapping.fromJS(data, mapping, self); 
};

var data = {
    people: [
        { id: 1, name: 'Fred', gender: 1 },
        { id: 2, name: 'Jane', gender: 2 },
        { id: 3, name: 'Bob', gender: 1 }
        ]   
};

var masterVM = new MasterVM(data);
ko.applyBindings(masterVM);