Knockout JS Mappings

Example of my blogpost. http://marcofranssen.nl/2012-09-12/knockout-js-mappings

by marcofranssen

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.1.0/knockout-min.js"></script>
<script src="https://rawgithub.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.js"></script>
<div id="company">
    Data will show within 2 seconds (ajax delay is set to 2)
    <h1 data-bind="text: name"></h1>
    <h2>Employees</h2>
    <table>
        <thead>
            <tr>
                <th>Full name</th>
                <th>Last name</th>
                <th>First name</th>
                <th>Age</th>
            </tr>            
        </thead>
        <tbody data-bind="foreach: employees">
            <tr>
                <td data-bind="text: fullName"></td>
                <td data-bind="text: lastName"></td>
                <td data-bind="text: firstName"></td>
                <td data-bind="text: age"></td>
            </tr>            
        </tbody>
    </table>
</div>

CSS

th, td {
    padding: 5px;
}

h1 {
    font-size: 3em;
}

h2 {
    font-size: 2em;
}

JavaScript

var company;

function PersonViewModel(data) {
    var personMapping = {
        'ignore': ['twitter', 'webpage'],
        'copy': ['age'],
        'lastName': {
            'create': function(options) {
                return ko.observable(options.data.toUpperCase());
            }
        }
    };

    ko.mapping.fromJS(data, personMapping, this);

    this.fullName = ko.computed(function() {
        return this.firstName() + ' ' + this.lastName();
    }, this);
}

function CompanyViewModel(data) {
    var companyMapping = {
        'ignore': ['address', 'website'],
        'name': {
            'create': function(options) {
                return ko.observable(options.data.toUpperCase());
            }
        },
        'employees': {
            key: function(data) {
                return ko.utils.unwrapObservable(data.personId);
            },
            create: function(options) {
                return new PersonViewModel(options.data);
            }
        }
    };

    ko.mapping.fromJS(data, companyMapping, this);
}

$.ajax({
    url: '/echo/json/',
    type: 'POST',
    data: {
        json: JSON.stringify({
            name: 'Atos',
            website: 'http://atos.net',
            address: {
                street: 'River Ouest 80, Quai Voltaire',
                zipCode: '95877',
                city: 'Bezons, Paris'
            },
            employees: [{
                personId: 1223,
                firstName: 'Marco',
                lastName: 'Franssen',
                age: 26,
                webpage: 'http://marcofranssen.nl',
                twitter: '@marcofranssen'},
            {
                personId: 1,
                firstName: 'Thierry',
                lastName: 'Breton',
                age: null,
                webpage: '',
                twitter: ''},
            {
                personId: 1233213,
                firstName: 'John',
                lastName: 'Doe',
                age: 33,
                webpage:...