JSFiddle - React, Tailwind, and code Playground

by Luiz Augusto Volpi Nascimento

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.3.5/knockout.mapping.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<ul data-bind="template: { name: 'itemTmpl', foreach: $data.items }"></ul>

<script id="itemTmpl" type="text/html">
    <li>
        <span data-bind="text: name"></span>
        <input type='checkbox' data-bind="checked: checked"/>
        <ul data-bind="template: { name: 'itemTmpl', foreach: $data.items }">
        </ul>
    </li>
</script>

CSS

li {
    margin-left: 10px;
}

JavaScript

MyApp = {};
MyApp.TreeViewModel = function(data) {
    var mapping = {
        items: {
            create: function(options) {
                return new MyApp.TreeViewModel(options.data);
            }
        }
    };
    this.checked = ko.observable(false); 
    this.checked.subscribe(this.onChecked, this);
    
    this.items = ko.observableArray();
    
    ko.mapping.fromJS(data, mapping, this);     
};

MyApp.TreeViewModel.prototype = {
    constructor: MyApp.TreeViewModel,
    onChecked: function(checked) {
        ko.utils.arrayForEach(this.items(), function(item) {
            item.checked(checked);
        });
    }
};

var data = {
    items: [{
        "name": "MORPHED",
        "items": [{
            "name": "5 Day",
            "items": [{
                "CategoryId": 20,
                "name": "30 day countdown"
            }, {
                "CategoryId": 19,
                "name": "Staffing your program"
            }, {
                "CategoryId": 22,
                "name": "Emergency/Medical Information"
            }, {
                "CategoryId": 18,
                "name": "Promoting your program"
            }, {
                "CategoryId": 21,
                "name": "Week of camp"
            }]
        }, {
            "name": "4 Day",
            "items": []
        }, {
            "name": "1/2 Day",
            "items": []
        }, {
            "name": "Age Targeted",
            "items": []
        }]
    }, {
        "name": "CREATE",
        "items": [{
            "name": "5 Day",
            "items": []
        }, {
            "name": "4 Day",
            "items": []
        }, {
            "name": "1/2 Day",
            "items": []
        }]
    }, {
        "name": "INNOVATE",
        "items": [{
            "name": "5 Day",
            "items": []
        }, {
            "name": "4 Day",
            "items": []
        }, {
            "name": "1/2 Day",
            "items": []
        }]
    }, {
       ...