JSFiddle - React, Tailwind, and code Playground

by sas_sam

HTML

<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
<ul class="summary">
    <!-- ko foreach: Summary.items -->
        <p data-bind="text: name"></p>
        <button class="btn btn-danger btn-mini remove-item">
            <i class="icon-remove" data-bind="click: $root.Summary.remove">×</i>
        </button>
    <!-- /ko -->
</ul>

<h1>What would you to buy?</h1>

<ul class="products">
    <!-- ko foreach: Product.products -->
    <li>
        <h3 data-bind="text: name"></h3>
        <p data-bind="text: desc"></p>
        <!-- ko if:isAdded -->
        <button data-bind="if: isAdded" class="btn btn-small btn-success action remove">
            <i data-bind="click: $root.Summary.remove" class="icon-ok">Remove</i>
        </button>
        <!-- /ko -->
        <!-- ko ifnot:isAdded -->
        <form data-bind="submit: function() { $root.Summary.add($data); }">
            <button data-bind="ifnot: isAdded" class="btn btn-small action add">
                <i class="icon-plus">Add</i>
            </button>
        </form>
        <!-- /ko -->
    </li>
    <!-- /ko -->
</ul>

CSS

body {
    font-family: "Tahoma"
}

p {
    font-size: 12px;
}

li {
    list-style: none;
}

ul.summary {
    width: 200px;
    background-color: #e6e6e6;
    float: right;
    padding: 10px;
}

ul.summary li {
    width: 100%;
    float: left;
}

ul.summary li p {
    float: left;
}

ul.summary li button {
    float: right;
}

ul.products {
    width: 50%;
}

ul.products li {
    width: 150px;
    float: left;
    padding: 10px;
    margin-right: 10px;
    border: 1px solid #e5e5e5;
}

ul.products li:nth-child(odd) {
    background-color: #e5e5e5;
}

JavaScript

function Product(id, name, desc) {
    var self = this;

    self.id = ko.observable(id);
    self.name = ko.observable(name);
    self.desc = ko.observable(desc);
    self.isAdded = ko.observable(false);
}

function Item(id, name) {
    var self = this;
    
    self.id = ko.observable(id);
    self.name = ko.observable(name);
}

function SummaryViewModel() {
    var self = this;
    self.items = ko.observableArray([]);

    self.add = function (item) {
        self.items.push(new Item(item.id(), item.name()));
        
        console.log(item);
        
        item.isAdded(true);
    };

    self.remove = function (item) {
        var i = self.items().filter(function(elem){
            return elem.id() === item.id();
        })[0];
        self.items.remove(i);
        item.isAdded(false);
    };
};

function ProductViewModel(products) {
    var self = this;
    
    self.products = ko.observableArray(products);
};

var products = [
    new Product(1, "GTA V", "by Rockstar"), 
    new Product(2, "Watch_Dogs", "by Ubisoft")
];

ViewModel = {
    Summary: new SummaryViewModel(),
    Product: new ProductViewModel(products)
}

ko.applyBindings(ViewModel);