Skip to content

Instantly share code, notes, and snippets.

@Fi1osof

Fi1osof/basket.js Secret

Created Aug 22, 2017
Embed
What would you like to do?
'use strict';
let FrontBasketTemplates = class {
constructor(basket){
this.basket = basket;
}
componentDidMount(){
// console.log('componentDidMount', this);
// Навешиваем обработчик на добавление товаров в корзину
$(document).on('click', 'form.ms2_form [type=submit]', (event) => {
let $this = $(event.target);
let form = $this.closest("form");
this.addProduct(form);
return false;
});
}
renderHtmlElement(node, props){
return this.basket.renderHtmlElement(node, props);
}
getTotalCost(){
return this.basket.state.total_cost || 0;
}
gettotalCount(){
return this.basket.state.total_count || 0;
}
forceUpdate(){
this.basket.forceUpdate();
}
addProduct(form){
return this.sendForm('orders/products/add', form, (data, errors) => {
if(data.success){
this.basket.setState(data.object);
}
});
}
updateProduct(product, data){
}
updateProductQuantity(product, count){
let {
state: {
products,
},
} = this.basket;
if(!products || !products.length){
return;
}
let productItem = products.find(n => n === product);
if(!productItem){
return;
}
productItem.count = count;
let {
key,
} = product;
this.basket.request(null, true, 'orders/products/update', {
key,
count,
}, {
callback: (data, errors) => {
if(data.success && data.object){
this.basket.setState(data.object);
}
else{
this.forceUpdate();
}
}
});
}
removeProduct(product){
let {
key,
} = product;
this.basket.request(null, true, 'orders/products/remove', {
key,
}, {
callback: (data, errors) => {
if(data.success && data.object){
this.basket.setState(data.object);
}
else{
this.forceUpdate();
}
}
});
}
sendForm(action, form, callback){
if(!form || !form.length || !form.serializeArray){
console.error("Не была получена форма");
return false;
}
let data = {};
form.serializeArray().map(function(field){
let {
name,
value
} = field;
if(name && value !== undefined){
data[name] = value;
}
});
this.basket.request(null, true, action, data, {
callback,
});
}
miniBasket(){
let miniBasketBlock = this.getMiniBasketBlock();
let orderDetailsBlock = this.getOrderDetailsBlock();
let orderFormBlock = this.getOrderFormBlock();
return [miniBasketBlock, orderDetailsBlock, orderFormBlock];
}
getMiniBasketBlock(){
let {
basket,
} = this;
let {
total_count,
total_cost,
} = basket.state;
let element;
let total_count_str = total_count.toLocaleString();
let total_cost_str = total_cost.toLocaleString();
let basketNode = $(`<div></div>`);
if(total_count > 0){
let notEmptyCart = $(`<div class="not_empty" style="display:block;">
<a href="/cart.html" class="nav-link">
<i class="ec ec-shopping-bag"></i>
<span class="cart-items-count count ms2_total_count" data-type="total-count">
${total_count_str}
</span>
<span class="cart-items-total-price total-price"><span class="amount ms2_total_cost">
</span> ${total_cost_str} руб.</span>
</a>
</div>`);
basketNode.html(notEmptyCart);
}
else{
let emptyCart = $(`<div class="empty">
<a href="/cart.html" class="nav-link">
<i class="ec ec-shopping-bag"></i>
<span class="cart-items-total-price total-price"><span class="amount">0</span> руб.</span>
</a>
</div>`);
emptyCart.show();
basketNode.html(emptyCart);
}
return this.renderHtmlElement(basketNode, {
key: "miniBasketBlock",
onMount: (onMount) => {
}
})
}
getOrderDetailsBlock(){
let {
basket,
} = this;
let {
total_count,
products,
} = basket.state;
let total_cost = this.getTotalCost();
let totalCount = this.gettotalCount();
let content;
let orderDetails;
if(!this.detailsBlockInited){
orderDetails = '<div></div>';
content = $(orderDetails);
}
else{
let table = $(`<table class="table table-striped"></table>`);
let tbody = $(`<tbody></tbody>`);
let table2 = $(`<table class="shop_table shop_table_responsive cart"></table>`);
let tbody2 = $(`<tbody></tbody>`);
tbody.append($(`<tr class="header">
<th class="">&nbsp;</th>
<th class="title">Наименование</th>
<th class="count">Количество</th>
<th class="weight">Вес</th>
<th class="price">Цена</th>
<th class="price">Сумма</th>
<th class="remove">Удалить</th>
</tr>`));
if(products && products.length){
products.map(product => {
let {
key,
thumb,
pagetitle,
uri,
count,
weight,
price,
} = product;
count = parseInt(count) || 0;
var tr = $(`<tr id="${key}">
<td class="">
<img src="${thumb}" alt="${pagetitle}" >
</td>
<td class="title">
<a href="${uri}">${pagetitle}</a>
</td>
<td class="count">
<div class="" style="display:flex;align-items:center;">
<input type="number" name="count" value="${count}" class="input-sm form-control" data-type="count">
<span class="hidden-xs">шт.</span>
</div>
</td>
<td class="weight">
${weight > 0 ? `<span>${weight}</span> кг. ` : ''}
</td>
<td class="price">
<span>${price.toLocaleString()}</span> руб.
</td>
<td class="">
${count > 0 && price > 0? `<span>${(price * count).toLocaleString()}</span> руб.` : ''}
</td>
<td class="remove">
</td>
</tr>`);
tr.find('[data-type="count"]').on('change', (event) => {
let {
value,
} = event.target;
this.updateProductQuantity(product, value || 0);
return false;
});
let removeButton = $(`<button class="btn btn-danger">Удалить</button>`);
removeButton.on('click', (event) => {
this.removeProduct(product);
return false;
});
tr.find('.remove').append(removeButton);
tbody.append(tr);
let tr2 = $(`<tr class="cart_item" id="">
<td class="product-remove">
<button class="remove" name="ms2_action" value="cart/remove" data-type="remove">X
</button>
</td>
<td class="product-thumbnail">
<a href="http://old.demo1.shopmodx.local/smartphones/smartfon-apple-iphone-6-64gb,-serebristyij.html">
<img src="${thumb}" alt="${pagetitle}" >
</a>
</td>
<td data-title="Product" class="product-name">
<a href="${uri}">${pagetitle}</a>
<br><br>
</td>
<td data-title="Quantity" class="product-quantity" data-type="quantity">
</td>
<td data-title="Total" class="product-subtotal">
<span class="amount">70 000</span>
</td>
</tr>`);
let quantityEditor = $(`<div class="quantity buttons_added">
<input type="button" class="minus" value="-">
<label>Количество:</label>
<input type="number" size="4" class="input-text qty text" title="Qty" value="${count}" name="count" min="0" step="1">
<input type="button" class="plus" value="+">
</div>`);
quantityEditor.find('[name="count"]').on('change', (event) => {
let {
value,
} = event.target;
this.updateProductQuantity(product, value || 0);
return false;
});
quantityEditor.find('.plus').on('click', (event) => {
this.updateProductQuantity(product, count + 1);
return false;
});
quantityEditor.find('.minus').on('click', (event) => {
this.updateProductQuantity(product, count - 1);
return false;
});
tr2.find('[data-type=quantity]').append(quantityEditor);
tr2.find('[data-type=remove]').on('click', (event) => {
this.removeProduct(product);
return false;
});
tbody2.append(tr2);
});
}
total_count && tbody.append($(`<tr class="footer">
<th class="total" colspan="2">Итого:</th>
<th class="total_count">
<span class="ms2_total_count">${total_count.toLocaleString()}</span>
шт. </th>
<th class="total_weight"> </th>
<th class="total_cost">
<span class="ms2_total_cost">${total_cost.toLocaleString()}</span> руб.
</th>
<th>&nbsp;</th>
</tr>`));
table.append(tbody);
orderDetails = $(`<div id="" class="content-area">
<main id="main" class="site-main">
<article class="page type-page status-publish hentry">
<header class="entry-header"><h1 itemprop="name" class="entry-title">Корзина</h1></header>
<!-- .entry-header -->
<div id="msCart">
<div class="table-responsive">
<div data-type="products-table"></div>
</div>
</div>
<div id="" data-type="products-table2">
</div>
</article></main></div>`);
table2.append($(`<thead>
<tr>
<th class="product-remove">&nbsp;</th>
<th class="product-thumbnail">&nbsp;</th>
<th class="product-name">Наименование</th>
<th class="product-quantity">Количество</th>
<th class="product-price">Цена</th>
</tr>
</thead>`));
table2.append(tbody2);
if(total_count > 0){
let footer2 = $(`<tr class="footer">
<th class="total" colspan="3">Итого:</th>
<th class="total_count">
<span class="ms2_total_count">${total_count.toLocaleString()}</span>
шт. </th>
<th class="total_cost">
<span class="ms2_total_cost">${total_cost.toLocaleString()}</span>
руб.
</th>
</tr>`);
table2.append(footer2);
}
orderDetails.find('[data-type="products-table"]').append(table);
orderDetails.find('[data-type="products-table2"]').append(table2);
content = orderDetails;
}
return this.renderHtmlElement($(content), {
key: "orderDetailsBlock",
onMount: (block) => {
let element = block.getNode();
let ordersBlock = $('[data-type="order-details"]');
if(ordersBlock.length){
ordersBlock.html(element);
this.detailsBlockInited = true;
this.forceUpdate();
}
}
})
}
/*
Блок формы заказа
*/
getOrderFormBlock(){
let {
basket,
} = this;
let {
total_count,
total_cost,
} = basket.state;
let form = $(`<div></div>`);
return this.renderHtmlElement($(form), {
key: "orderFormBlock",
onMount: (block) => {
let element = block.getNode();
let ordersBlock = $('#msOrder');
if(ordersBlock.length){
ordersBlock.replaceWith(element);
}
}
})
}
componentDidUpdate(prevProps, prevState){
// Здесь можно перехватить изменения в состоянии корзины
}
}
window.FrontBasketTemplates = FrontBasketTemplates;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment