MOBservable + jquery demo

by quangcanh2975

HTML

<script src="https://npmcdn.com/[email protected]/lib/mobx.umd.js"></script>
<!DOCTYPE HTML>
<body>
    <div id="container">
        <div id="header">
            <h1>MobX shopping cart demo</h1>
            <a href="https://github.com/mobxjs/mobx">Github repo</a>
        </div>
        <table>
            <tr>
                <td>
                    <h2>Availale items<button id="new-article">New article</button></h2>
                    <ul id="articles">

                    </ul>
                    
                </td>
                <td>
                    <h2>Your shopping cart</h2>
                    <ul id="cart">

                    </ul>
                    <div><b>Total: <span id="total"></span></b></div>
                </td>
            </tr>
        </table>
    </div>
</body>

CSS

body {
	font-family: 'Georgia';
	background: #555;
    background-size: cover;
}

h1 {
	font-family: 'Arial Black';
}

h2 {
	font-family: 'Arial Black';
	font-size: 12pt;	
}

#header {
	text-align: center;
}

#container {
	margin-left: auto;
	margin-right: auto;
	margin-top: 40px;
	width: 800px;
	padding: 40px;
	border-radius: 8px;
	background:rgba(255,255,255,1);
	box-shadow: 3px 3px 5px 0px rgba(50, 50, 50, 0.7);
}

#container table {
	width: 100%;
}

#container table td {
	width: 50%;
	vertical-align: top;
	padding: 20px;
}

ul {
	list-style: none;
    padding-left: 0px;
}

li {
	display: inline-block;
	width: 100%;
	border-bottom: 1px solid #e2e2e2;
	padding: 10px 0;
}

button {
	float: right;
}

.price {
	float: right;
	font-style: italic;
	margin-right: 10px;
}

JavaScript

/** Data model */
function Article(name, price) {
    mobx.extendObservable(this, {
        name: name,
        price: price
    });
}

function ShoppingCartEntry(article) {
    mobx.extendObservable(this, {
        article: article,
        amount: 1,
        price: function() {
            return this.article ? this.article.price * this.amount : 0;
        }
    });
}

function ShoppingCart() {
    mobx.extendObservable(this, {
        entries: [],
        total: function() {
            return this.entries.reduce(function(sum, entry) {
                return sum + entry.price;
            }, 0);
        }
    });
}

// Some available articles
var articles = mobx.observable([
    ["Funny Bunnies", 17.63],
    ["Awesome React", 23.95],
    ["Second hand netbook", 50.00]
].map(function(e) {
    return new Article(e[0], e[1]);
}));

// Our shopping cart
var shoppingCart = new ShoppingCart();
// With a demo item inside
shoppingCart.entries.push(new ShoppingCartEntry(articles[0]));

$.fn.insertAt = function(index, $parent) {
    return this.each(function() {
        if (index === 0) {
            $parent.prepend(this);
        } else {
            $parent.children().eq(index - 1).after(this);
        }
    });
};

/** UI Logic */
var $articles = $("#articles");

// Make the articles list follow the array
articles.observe(function(change) {
    // items where added or removed
    if (change.type === "splice") {
        $articles.children().slice(change.index, change.index + change.removed.length).remove();
        for(var i = 0; i < change.addedCount; i++) {
            renderArticle(articles[change.index + i])
            .insertAt(change.index + i, $articles);
        }
    }
}, true); // true makes sure the observe function is invoked immediately

// Render an article in the articles overview, and watch or changes
function renderArticle(article) {
    var $name = $("<span>").text(article.name);
    var $price = $("<span>").addClass("price").text(article.price);
  ...