Shopping cart

Example of JS shopping cart implementation

by rhudecaviar

HTML

<div class="fl_r">
    <div id="cart"></div>
    <div id="cart-info"></div>
</div>
<div class="fl_l items">
    <a class="item" data-id="1">eggs №1</a>
    <a class="item" data-id="2">brocoli №2</a>
    <a class="item" data-id="3">ham №3</a>
    <a class="item" data-id="4">music №4</a>
    <a class="item" data-id="5">girls №5</a>
</div>

CSS

#cart {
    border: 1px solid #ccc;
    width: 200px;
    line-height: 30px;
    vertical-align: middle;
    padding-left: 10px;
}
#cart-info { margin: 20px 5px; }
.fl_l { float: left; }
.fl_r { float: right; }
.items {
    float: left;
    width: 70%;
}
.item {
    display: inline-block;
    margin: 5px 10px;
    padding: 10px;
    border: 1px solid #ccc;
    cursor: pointer;
}
.item:hover {
    border-color: #000;
}

JavaScript

function shoppingCart() {}

shoppingCart.prototype.init = function($cartContainer, $cartInfoContainer, emptyMessage, text) {
    this.cart = $cartContainer;
    this.cartInfo = $cartInfoContainer;
    this.cart.text(this.emptyMessage = emptyMessage);
    this.text = text;
    
    this.itemsCollection = [];
    this.totalItems = 0;
};

shoppingCart.prototype.render = function() {
    if (this.totalItems) {
        this.cart.html(declensionNumerals(this.totalItems, this.text).replace(/%d/, this.totalItems));
        var html = '<ul>';
        for (var i in this.itemsCollection) if (this.itemsCollection.hasOwnProperty(i)) {
             html += '<li>Товар №' + i + ' в кол-ве ' + this.itemsCollection[i] + ' шт.</li>';
        }
        html += '</ul>';
        this.cartInfo.show().html(html);
    } else {
        this.cart.html(this.emptyMessage);
        this.cartInfo.hide();
    }
};

shoppingCart.prototype.buy = function($this) {
    var itemId = $this.data('id');
    if (typeof this.itemsCollection[itemId] === 'undefined') {
        this.itemsCollection[itemId] = 0;
    }
    this.itemsCollection[itemId] += 1;
    this.totalItems += 1;
    observer('cart.view').publish();
};

$(function(){
    var cart = new shoppingCart();

    cart.init(
        $('#cart'),
        $('#cart-info'),
        'Корзина пуста',
        ['В корзине %d товар','В корзине %d товара','В корзине %d товаров']
    );
    
    observer('cart.buy').subscribe(cart.buy.bind(cart));
    observer('cart.view').subscribe(cart.render.bind(cart));

    $('.items').on('click', '.item', function() {
        observer('cart.buy').publish( $(this) );
    });
});

declensionNumerals = function(count, values) {
    if(typeof values == 'undefined'){
        return;
    }
    var _cases = [2, 0, 1, 1, 1, 2];
    return values[ (count % 100 > 4 && count % 100 < 20) ? 2 : _cases[(count % 10 < 5) ? count % 10 : 5] ];
};

/* Observer pattern */
var topics = [];
var observer = function(id) {
    var topic = id &&...