JSFiddle - React, Tailwind, and code Playground

by sturtevant

HTML

<!DOCTYPE html>
<html>
<body>
<div id="container">
    <table border="1">
    <thead>
        <tr>
            <th>Subject</th>
            <th>Contents</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: posts">
        <tr>
            <td data-bind='text: subject' /></td>
            <td data-bind='text: contents' /></td>
            <td><button data-bind='click: $root.removePost'>Remove</button></td>
        </tr>
    </tbody>
    </table>
    <div id="loading" data-bind="visible: empty">
        Loading...
    </div>
    <hr />
    <button data-bind='click: addPost'>Add Post</button><br />
    <table>
        <tr>
            <td>Subject</td>
            <td><input data-bind='value: newPost().subject' /></td>
        </tr>
        <tr>
            <td>Contents</td>
            <td><input data-bind='value: newPost().contents' /></td>
        </tr>
    </table>
</div>
</div>
</body>
</html>

CSS

#loading {
    color: red;
}

JavaScript

var postViewModel = function(subject, contents) {
    var self = this;
    self.subject = ko.observable(subject);
    self.contents = ko.observable(contents);
};

var viewModel = function() {
    var self = this;
    self.posts = ko.observableArray();
    self.newPost = ko.observable(new postViewModel('New Subject', 'New Contents'));
    self.empty = ko.computed(function() {
        return this.posts().length == 0;
    }, this);
    self.addPost = function() {
        self.posts.push(self.newPost());
        self.newPost(new postViewModel('New Subject', 'New Contents'));
    };
    self.removePost = function(post) {
        self.posts.remove(post);
    };
};

ko.applyBindings(new viewModel());