JSFiddle - React, Tailwind, and code Playground

by mitaka

HTML

<div>
    <h2>Mark Preferred Customers<h2/>
    <h3>1- JSON string from server</h3>
<p data-bind="text: jSONdataFromServer"></p>
        
   <h3>2- Converted to an object with ko.parseJSON</h3>
    <p data-bind="text: ko.toJSON(dataFromServer)"></p>
    <h3>3- Mapped to use observables and add a dependentObservable</h3>
    <p data-bind="text: ko.toJSON(mappedData)"></p>        
<div/>

    <table>
        <thead>
            <tr>
                <th>Full Name</th>
                <th>Preferred</th>
                <th>Is Preferred?</th>
                <th>Mark as Preferred</th>                
            </tr>
        </thead>
            <tbody data-bind="foreach: customers">
                <tr>
                    <td data-bind="text: fullName"></td>
                    <td data-bind="text: preferred"></td>
                    <td data-bind="text: isPreferred"></td>
                    <td><input type="checkbox" data-bind="checked: isPreferred" /></td>
                </tr>
            </tbody>    
    <table/>

CSS

body, a, p { font-size: .85em; }
input { width: 100px; }
table { border: 1px solid black; }
h3, p, td, th { padding: 3px; }
h3 { font-weight: bold; }

JavaScript

// Writeable computed observables
function Customer(id, firstName, lastName, preferred) {
    var self = this;
    self.id = id;
    self.firstName = firstName;
    self.lastName = lastName;
    self.fullName = ko.computed(function() {
        var fn = self.firstName;
        var ln = self.lastName;
        return ln ?  fn + ' ' + ln : fn;
    }, self);
    self.preferred = ko.observable(preferred);
    self.isPreferred = ko.computed({
        read: function() {
            var preferredStr = self.preferred() || '';
            var isPreferredComputed = preferredStr.toUpperCase();
            return (isPreferredComputed === 'Y') ?  true : false;
        },
        write: function(value) {
            self.preferred( (!value) ? '' : (value ? 'Y' : ''));            
        },
        owner: self        
    });    
}

var viewModel = {
    jSONdataFromServer: ko.observable(),
    customers: ko.observableArray([])
};

// metadata replica of EF5 customerList
var JSONdataFromServer = '[{ "id": "1","firstName": "Joe","lastName": "Doe","preferred": "Y"  },{"id": "2","firstName": "Jane","lastName": "Dill","preferred": ""  },{"id": 3,"firstName": "ABC Inc.","lastName": "","preferred": "" }]';

//parse into an object
var dataFromServer = ko.utils.parseJson(JSONdataFromServer);
// result
//var dataFromServerResult = [
//    { "id": "1",
//     "firstName": "Joe",
//     "lastName": "Doe",
//     "preferred": "Y"  },
//    {"id": "2",
//     "firstName": "Jane",
//     "lastName": "Dill",
//    "preferred": ""  },
//    {"id": 3,
//     "firstName":"ABC Inc.",
//     "lastName": "",
//     "preferred": "" }];

//do some basic mapping (without mapping plugin)
var mappedData = ko.utils.arrayMap(dataFromServer, function(customer) {
    return new Customer(customer.id, customer.firstName, customer.lastName, customer.preferred);
});

viewModel.jSONdataFromServer(JSONdataFromServer);
viewModel.dataFromServer = dataFromServer;
viewModel.mappedData =...