JSFiddle - React, Tailwind, and code Playground

by drojoke

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockback/0.20.3/knockback.min.js"></script>
<h2>Employee overview</h2>

<div id="task_list">
    <p>Select a task to add it to the selected tasks table.</p>
     <h3>All tasks</h3>

    <table>
        <thead>
            <tr>
                <th>Selected</th>
                <th>Name</th>
                <th>Location</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: tasks">
            <tr>
                <td>
                    <input data-bind="checked: isSelected" type="checkbox" />
                </td>
                <td data-bind="text: name"></td>
                <td data-bind="text: location"></td>
            </tr>
        </tbody>
    </table>
     <h3>Selected tasks</h3>

    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Location</th>
            </tr>
        </thead>
        <tbody data-bind="foreach: selectedTasks">
            <tr>
                <td data-bind="text: name"></td>
                <td data-bind="text: location"></td>
            </tr>
        </tbody>
    </table>
</div>

CSS

* {
    font-family: arial;
    font-size: 10pt;
}
h2 {
    font-size: 14pt;
}
h3 {
    font-size: 12pt;
}
table, th, td {
    border: solid #bbbbbb 1px;
    border-spacing: 0px;
    border-collapse: collapse;
    padding: 5px;
}
th {
    text-align: left;
}

JavaScript

// Model
var tasks = new kb.Collection([{
    name: 'Shop for ingredients',
    location: 'Supermarket'
}, {
    name: 'Cook a meal',
    location: 'Kitchen'
}, {
    name: 'Serve guests',
    location: 'Restaurant'
}]);

// View model for a single task
var TaskViewModel = kb.ViewModel.extend({
    constructor: function (task) {
        kb.ViewModel.prototype.constructor.call(this);

        this.name = ko.observable(task.get('name'));
        this.location = ko.observable(task.get('location'));
        this.isSelected = ko.observable(false); // Not selected by default.
    }
});

// View model for an employee, contains a collection of several view models of tasks.
var EmployeeViewModel = kb.ViewModel.extend({
    constructor: function (tasks) {
        kb.ViewModel.prototype.constructor.call(this);
        this.tasks = kb.collectionObservable(tasks, {
            view_model: function (task) {
                return new TaskViewModel(task);
            }
        });

        // selectedEmployees should filter the collection of EmployeeViewModels so that
        // it only contains the view models of employees that are currently selected.
        // Only one view model should exist.
        // If an employee is added to the employees collection, both the employees and
        // selectedEmployees observables should be affected.
        this.selectedTasks = this.tasks;
    }
});

// Bindings
var employeeViewModel = new EmployeeViewModel(tasks);
ko.applyBindings(employeeViewModel, $('#tast_list')[0]);