Shopping cart

Example of JS shopping cart implementation

by Ilia Lesnykh

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">Купить товар №1</a>
    <a class="item" data-id="2">Купить товар №2</a>
    <a class="item" data-id="3">Купить товар №3</a>
    <a class="item" data-id="4">Купить товар №4</a>
    <a class="item" data-id="5">Купить товар №5</a>
    <a class="item" data-id="6">Купить товар №6</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;
};

/**
 * Вывод данных о товарах в корзине и их общего числа
 *
 * @todo сделать подобие MVC и вынести отсюда верстку
 */
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');
    // TODO: сделать проверку на наличие itemId
    if (typeof this.itemsCollection[itemId] === 'undefined') {
        this.itemsCollection[itemId] = 0;
    }
    this.itemsCollection[itemId] += 1;
    this.totalItems += 1;
    observer('cart.view').publish();
};

// TODO: написать метод удаления товара из корзины

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

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