JSFiddle - React, Tailwind, and code Playground

by mavdhana

HTML

<script src="https://cdn.jsdelivr.net/pouchdb/5.4.5/pouchdb.min.js"></script>

<div ng-controller="TestCtrl">
<div class="appbar">
    <button ng-click="addCustomer()">Add Customer</button>
    <button ng-click="syncDB()">Synchronize</button> <span data-bind='text: customers().length'>&nbsp;</span> customers <span id="msg"></span>

</div><div>

<table>
    <thead>
        <tr>
            <th class="column">First name</th>
            <th class="column">Last name</th>
            <th class="column">Email address</th>
            <th class="column">Telephone</th>
            <th class="column">City</th>
            <th></th>
            <th></th>
        </tr>
    </thead>
    <tbody ng-repeat="value in customers">
        <tr>
            <td>
                <input ng-model="value.firstname"/>
            </td>
            <td>
                <input ng-model="value.lastname"/>
            </td>
            <td>
                <input ng-model="value.email"/>
            </td>
            <td>
                <input ng-model="value.telephone"/>
            </td>
            <td>
                <input ng-model="value.city"/>
            </td>
            <td>
                <button ng-click="updateCustomer()">Update</button>
            </td>
            <td>
                <button ng-click="removeCustomer()">Delete</button>
            </td>
        </tr>
    </tbody>
    </table></div>
</div>

CSS

body {
    font-family: Arial;
    margin: 60px;
}
table {
    border-spacing:0;
    border-collapse:collapse;
}
input {
    margin:0;
    border:0;
    font-size: 14px;
    padding: 4px;
    width: 150px;
}
tr {
    border-bottom: 1px solid #000;
}
th.column {
    width: 150px;
}
.appbar button {
    border: 2px solid;
    height: 30px;
    cursor: pointer;
}
tbody button {
    border: 1px solid #ccc;
    font-size: 14px;
    cursor: pointer;
}
.appbar {
    margin-bottom: 20px;
}
#msg {
    background: #c00;
    color: #fff;
    padding: 5px;
    float: right;
    display: none;
}

JavaScript

function TestCtrl($scope) {

$scope.db = new PouchDB('customers');

db.changes({
    continuous: true,
    onChange: updateVM
});

$scope.updateVM = function() {
    db.allDocs({
        include_docs: true,
        descending: false
    }, function (err, doc) {
        viewModel.customers.removeAll();
        doc.rows.forEach(function (row) {
            viewModel.customers.push(row.doc);
        });
    });
}

$scope.CustomerModel = function () {
    var self = this;
    self.customers = ko.observableArray();

    self.addCustomer = function () {

        var customer = {
            _id: new Date().toISOString(),
            firstname: "",
            lastname: "",
            email: "",
            telephone: "",
            city: ""
        };

        db.put(customer, function callback(err, result) {
            if (!err) {
                console.log('Customer added.');
            } else {
                console.log(err);
            }
        });

    };

    self.updateCustomer = function (customer) {
        db.put(customer, function callback(err, result) {
            if (!err) {
                console.log('Customer updated.');
            } else {
                console.log(err);
            }
        });
    };

    self.removeCustomer = function (customer) {
        db.remove(customer);
    };

    self.syncDB = function () {

        showMsg('Synchronizing...');

        var remoteCouchDB = 'http://localhost:5984/customers';
        var options = {
            complete: syncDBCompleted
        };

        db.replicate.to(remoteCouchDB, options);
        db.replicate.from(remoteCouchDB, options);
    }
};

function syncDBCompleted() {
    showMsg('Synchronization completed!', true);
}

function showMsg(text, autohide) {
    var msg = document.getElementById("msg");
    msg.innerText = text;
    msg.style.display = 'block';

    if (autohide) {
        setTimeout(function () {
            msg.style.display = 'none';
        }, 3000);
   ...