JSFiddle - React, Tailwind, and code Playground

by tjerabek

HTML

<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.js"></script>
<h2>
    Index</h2>
<table data-bind="foreach: tasks" data-rebind="initial: initTasks">
    <tr>
        <td>
            <span data-bind="text: Name"></span>
        </td>
        <td>
            <span data-bind="text: IsDone"></span>
        </td>
        <td>
            <input type="checkbox" data-bind="checked: IsDone" />
        </td>
    </tr>
    <tr data-rebind="item({ Name: 'Task0', IsDone: o(true) })">
        <td>
            <span>Můj task</span> 
        </td>
        <td>
            <span>false</span>
        </td>
        <td>
            <input type="checkbox" value="" />
        </td>
    </tr>
    <tr data-rebind="item({ Name: 'Task1', IsDone: o(false) })">
        <td>
            <span>Můj task</span> 
        </td>
        <td>
            <span>false</span>
        </td>
        <td>
            <input type="checkbox" value="" />
        </td>
    </tr>
    <tr data-rebind="item({ Name: 'Task2', IsDone: o(true) })">
        <td>
            <span>Můj task 2</span>
        </td>
        <td>
            <span>true</span>
        </td>
        <td>
            <input type="checkbox" value="" checked="checked" />
        </td>
    </tr>
</table>
<a href="#" data-bind="click: addNew">Add new</a>

CSS

table{
    width: 100%;
}

JavaScript

// KNOCKOUT INIT PLUGIN

$('[data-rebind^="initial"]').each(function () {

    var $this = $(this);
    var arrayName = $this.data("rebind").replace("initial:", "").trim();
    var bindings = new Array();

    $this.find('[data-rebind^="item"]').each(function () {
        $item = $(this);
        var raw = $item.data("rebind").replace("item(", "").replace(/'/g,"").replace(/ /g,"").replace(/{/g,"{\"").replace(/:/g,"\":\"").replace(/,/g,"\",\"").replace(/}/g,"\"}");
        
        var isTrueSet = (raw.toLowerCase() === 'true');
        if(isTrueSet){ raw = true; } else {
        var isFalseSet = (raw.toLowerCase() === 'false');
        if(isFalseSet){ raw = false; }
    }
        
        bindings.push(raw.substring(0, raw.length - 1).trim());
        $item.remove();
    });

    window[arrayName] = new Array();

    for (var i = 0; i < bindings.length; i++) {
        var jsonItem = jQuery.parseJSON(bindings[i]);                
        $.each(jsonItem, function(key, valueItem){  
            if(valueItem.indexOf("o(")==0){
                var oValue = valueItem.replace("o(","").replace(")","");
                var isTrueSet = (oValue.toLowerCase() === 'true');
                if(isTrueSet){ oValue = true; } else {
                var isFalseSet = (oValue.toLowerCase() === 'false');
                if(isFalseSet){ oValue = false; }}
                jsonItem[key]= ko.observable(oValue);
            }                
        });
        window[arrayName].push(jsonItem);
    }
});

// VIEW MODEL

function AppViewModel() {
    self = this;
    
    self.tasks = ko.observableArray(initTasks);
    self.tasks.push({ Name: "Hello", IsDone: ko.observable(false) });

    self.addNew = function () {
        self.tasks.push({ Name: "New task", IsDone: ko.observable(false) });
    }
}

var viewModel = new AppViewModel();

ko.applyBindings(viewModel);