UMIhelp

Разработка сайта на UMI.CMS => JS и AJAX => Тема начата: Molti от 08 Октября 2012, 15:48:16

Название: [РЕШЕНО] Отредактировать basket.js
Отправлено: Molti от 08 Октября 2012, 15:48:16
Итак, стоит следующая задача: в шаблон интернет-магазина (XSLT) надо при выводе раздела каталога вставить окошко выбора количества товара для добавления в корзину, так как магазин оптовый и по одной штуке там никто не покупает.
В карточке товара это решается добавлением строки:
<input type="text" name="amount" size="2" class="qty-input" value="1" />
В разделах каталога такое не прокатывает.

На старом форуме поддержки UMI было найдено шикарное решение:
Этап первый.
В catalog\common.xsl в шаблоне где выводятся продукты добавляем:
<div class="add_from_list">
<input type="input" value="1" id="amount_{@id}" o nchange="document.getElem entById('add_basket_{@id}').hr ef='{$lang-prefix}/emarket/bas ket/put/element/{@id}/?amount= '+ document.getElementById('amount_{@id}').value"/>
<a id="add_basket_{@id}"
class="basket_list options_{$is_options}"
href="{$lang-prefix}/emarket/basket/put/element/{@id}/">
Это получилось успешно, но вводимое в поле выбора количество число пока никак не влияет на то, сколько единиц отправляется в корзину - все еще товары добавляются по одной штуке.

Теперь цитирую этап второй:
Цитировать
Дальше пришлось редактировать файл js\site\basket.js. Доработал ф-цию site.basket.list (эта ф-ция вызывается обработчиком jQuery при нажатии на нашу кнопку). В ней получаю значение amount - параметра, в котором кол-во штук товара. Далее вызывается переписанная ф-ция аналог site.basket.add (которая добавляет продукт в корзину). Ее модификация заключалась лишь в options['amount'] = amount; - т.е. передаче в ф-цию basket.putElement массива options c значением amount.

Вот тут получается большая засада, так как я не программист. Совсем. Поэтому описание второго этапа, касающееся редактирования файла basket.js вводит меня в абсолютное замешательство. Может быть, найдется здесь добрый человек, который напишет, как должен выглядеть код файла basket.js с изменениями, описанными выше?
Вот исходник basket.js:
site.basket = {};

site.basket.replace = function(id) {
return function(e) {
var text, discount, goods_discount_price, goods_discount, item_total_price, item_discount, cart_item, basket, i, item,
cart_summary = jQuery('.cart_summary'),
cart_discount = jQuery('.cart_discount'),
goods_discount_price = jQuery('.cart_goods_discount'),
add_basket_button_text = 'Добавить в корзину',
rem_item = true,
detect_options = {};

if (e.summary.amount > 0) {
text = e.summary.price.actual + ' ' + e.summary.price.suffix;
goods_discount = ((typeof e.summary.price.original == 'undefined') ? e.summary.price.actual : e.summary.price.original) + ' ' + e.summary.price.suffix;
discount = ((typeof e.summary.price.discount != 'undefined') ? e.summary.price.discount : '0') + ' ' + e.summary.price.suffix;
for (i in e.items.item) {
item = e.items.item[i];
if (item.id == id) {
rem_item = false;
item_total_price = item["total-price"].actual + ' ' + item["total-price"].suffix;
item_discount = ((typeof item.discount != 'undefined') ? item.discount.amount : '0') + ' ' + item["total-price"].suffix;
}
if (item.page.id == id) {
if (detect_options.amount) {
detect_options.amount = detect_options.amount + item.amount;
}
else detect_options = {'id':id, 'amount':item.amount};
}
}
if (detect_options.amount) {
var add_basket_button = jQuery('#add_basket_' + detect_options.id);
if (add_basket_button[0].tagName.toUpperCase() == 'A') {
add_basket_button.text(add_basket_button_text + ' (' + detect_options.amount + ')');
}
else add_basket_button.val(add_basket_button_text + ' (' + detect_options.amount + ')');
}
if (rem_item) {
if (cart_item = jQuery('.cart_item_' + id)) {
cart_item.remove();
cart_summary.text(text);
cart_discount.text(discount);
goods_discount_price.text(goods_discount);
}
}
else {
jQuery('.cart_item_price_' + id).text(item_total_price);
jQuery('.cart_item_discount_' + id).text(item_discount);
cart_summary.text(text);
cart_discount.text(discount);
goods_discount_price.text(goods_discount);
}
text = e.summary.amount + ' шт товаров на сумму ' + text;
}
else {
text = 'В корзине нет ни одного товара.';
if (basket = jQuery('.basket')) {
basket.text(text);
}
}
jQuery('.basket_info_summary').text(text);
};
};

site.basket.add = function(id, form, popup) {
var e_name, options = {};
if (form) {
var elements = jQuery(':radio:checked', form);
for (var i = 0; i < elements.length; i++) {
e_name = elements[i].name.replace(/^options\[/, '').replace(/\]$/, '');
options[e_name] = elements[i].value;
}
}
basket.putElement(id, options, this.replace(id));
if (popup) jQuery('#add_options_' + id).remove();
};

site.basket.list = function(link) {
var id = (link.id.indexOf('add_basket') != -1) ? link.id.replace(/^add_basket_/, '') : link;
if (!id) return false;
if (jQuery(link).hasClass('options_true')) {
if (jQuery('#add_options_' + id).length == 0) {
jQuery.ajax({
url: '/upage//' + id + '?transform=modules/catalog/popup-add-options.xsl',
dataType: 'html',
success: function (data) {
site.message({
id: 'add_options_' + id,
header: 'Выбор опций',
width: 400,
content: data
});
}
});
}
}
else this.add(id);
};

site.basket.modify = function(id, amount_new, amount_old) {
if (amount_new.replace(/[\d]+/) == 'undefined' && amount_new != amount_old) {
basket.modifyItem(id, {amount:amount_new}, this.replace(id));
}
};

site.basket.remove = function(id) {
if (id == 'all') basket.removeAll(this.replace(id));
else basket.removeItem(id, this.replace(id));
};

site.basket.init = function() {
jQuery('.basket_list').click(function(){
site.basket.list(this);
return false;
});
jQuery('div.basket a.del').click(function(){
site.basket.remove(this.id);
return false;
});
jQuery('div.basket a.basket_remove_all').click(function(){
site.basket.remove('all');
return false;
});
};

jQuery(document).ready(function(){site.basket.init()});

Понимаю, что это может быть кажется очень нагло, вот так просить прям готовое решение на блюдечке, но моих знаний действительно вообще никак не хватает для решения этого вопроса. А добавить работающее окошко выбора количества товара в каталоге надо позарез. И тем более обидно отыскать реально работающее решение, но не иметь возможности довести работу до конца.
Название: Re:Отредактировать basket.js
Отправлено: Rodogor от 08 Октября 2012, 21:28:52
js/site/basket.js
меняем функцию
site.basket.add = function(id, form, popup) {
var e_name, options = {};
var amount=$('#amount_'+id).val();

if (form) {
var elements = jQuery(':radio:checked', form);
for (var i = 0; i < elements.length; i++) {
e_name = elements[i].name.replace(/^options\[/, '').replace(/\]$/, '');
options[e_name] = elements[i].value;
}
}
options['amount'] = amount;
basket.putElement(id, options, this.replace(id));
if (popup) jQuery('#add_options_' + id).remove();
};
Если не будет поля amount_ID для товара, то кнопка "Добавить в корзину" добавит 1 товар. На скриншоте видно, что количество неопределено, но благо такие косяки предусмотрены заранее.
(http://my.jetscreenshot.com/12061/20121008-hlzw-13kb.jpg)
Название: Re:Отредактировать basket.js
Отправлено: Molti от 08 Октября 2012, 22:42:35
Работает! Ура-ура-ура :D
Rodogor, спасибо огромное!
Название: Re:[РЕШЕНО] Отредактировать basket.js
Отправлено: dina от 10 Ноября 2012, 12:45:54
Здравствуйте!
вот такая же точно проблема с пересчётом суммы в корзине при введении пользователем количества товаров. Вот тут нашла решение http://www.digitalart.by/articles/change_goods/. Да , можно вводить количество, но сумма не пересчитывается. я так поняла, надо править basket.js. Но он у меня путь не js\site\basket.js, а js\client\basket.js. Каталога site вообще нет. да и по содержанию он другой
basket = {
get : function(callback) {
basket.__request("/udata/emarket/basket.json", {}, callback);
},
putElement : function(id, options, callback) {
basket.__request("/udata/emarket/basket/put/element/" + id + ".json", options, callback);
},
modifyItem : function(id, options, callback) {
if(options.amount == 0) {
this.removeItem(id, callback);
return;
}
basket.__request("/udata/emarket/basket/put/item/" + id + ".json", options, callback);
},
removeElement : function(id, callback) {
basket.__request("/udata/emarket/basket/remove/element/" + id + ".json", {}, callback);
},
removeItem    : function(id, callback) {
basket.__request("/udata/emarket/basket/remove/item/" + id + ".json", {}, callback);
},
removeAll     : function(callback) {
basket.__request("/udata/emarket/basket/remove_all.json", {}, callback);
},
__cleanupHash : function(input) {
var output = {
customer : input.customer.object.id,
items    : input.items,
summary  : input.summary,
id :input.id
};
return output;
},
__transformOptions : function(options) {
var o = {};
for(var i in options) {
var k;
if(i.toLowerCase() != "amount") k = "options[" + i + "]";
else k = i;
o[k] = options[i];
}
return o;
},
__request : function(url, options, callback) {
jsonp(url, basket.__transformOptions(options),
  function(data){
  if(callback) callback( basket.__cleanupHash(data) );
  });
}
};

вот, кстати, тут тоже есть решение http://wiki.umisoft.ru/%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%BE%D0%B2%D0%B0%D1%80%D0%B0_%D0%B2_%D0%BA%D0%BE%D1%80%D0%B7%D0%B8%D0%BD%D1%83_%D1%81_%D1%83%D0%BA%D0%B0%D0%B7%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%9A%D0%BE%D0%BB%D0%B8%D1%87%D0%B5%D1%81%D1%82%D0%B2%D0%B0 , но опять таки не могу понять, как сделать пересчёт суммы. Помогите, пожалуйста разобраться, т.к. функционал очень нужный. спасибо.
Название: Re:[РЕШЕНО] Отредактировать basket.js
Отправлено: dina от 10 Ноября 2012, 12:51:30
а, вот ещё вариант нашла
http://wiki.umisoft.ru/%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D1%91%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D0%BB%D0%B8%D1%87%D0%B5%D1%81%D1%82%D0%B2%D0%B0_%D1%82%D0%BE%D0%B2%D0%B0%D1%80%D0%BE%D0%B2_%D0%B2_%D0%BA%D0%BE%D1%80%D0%B7%D0%B8%D0%BD%D1%83 с кастомным модулем
Прописываю ссылку /emarket/basket_custom/put/element/%id% -выдаёт ошибку, страница не найдена.
В общем, буду очень признательна за помощь, т.к. я начинающий разработчик и только начинаю осваивать umi cms.
Название: Re:[РЕШЕНО] Отредактировать basket.js
Отправлено: Rodogor от 10 Ноября 2012, 21:50:33
Файл, который Вы указываете, он лишь реализует функции-методы корзины.
Самих функций выполняющих действия тут нет. Нужно найти где они
Посмотрите на кнопку отправляющую товар в корзину, там будет имя функции и т.п...
Название: Re:[РЕШЕНО] Отредактировать basket.js
Отправлено: dina от 11 Ноября 2012, 01:34:30
вот, кажется нашла..umiBasket.js
// Object umiBasket ===============================================================

// contructor
function umiBasket() {

}

umiBasket.instance = null;

umiBasket.getInstance = function () {
if(!umiBasket.instance) {
umiBasket.instance = new umiBasket();
}
return umiBasket.instance;
}

// default event handlers
umiBasket.prototype.onAfterAddElement = function (iElementId, iCount) {
var oButtons = document.getElementsByName("addtobasket_area_" + iElementId);
for (iI = 0; iI < oButtons.length; iI++) {
oButtons[iI].innerHTML = "<a href=\"/eshop/basket/\">В корзине " + iCount +
" шт.</a> | <a href=\"javascript:umiBasket.getInstance().addElement("+iElementId+");\">+1</a>";
}

var oAddedItemRows = document.getElementsByName("basketrow_"+iElementId);

if (!oAddedItemRows.length) {
// add new row in basket
var arrTempNewItems = new Array();
var arrTempNewItemsParents = new Array();
var oNewRows = document.getElementsByName('basketnewrow');
var iCountNewRows = oNewRows.length;
for (iI = oNewRows.length - 1; iI >=0; iI--) {
arrTempNewItems[iI] = oNewRows[iI].cloneNode(true);

var oNextObj = oNewRows[iI];
oNewRows[iI].id = "basketrow_"+iElementId;
if (oNewRows[iI]) {
oNewRows[iI].setAttribute("name", "basketrow_"+iElementId, 0);
}

arrTempNewItemsParents[iI] = oNextObj.parentNode;
}

if (iCountNewRows) {

var oSelf = this;

var oControls = document.getElementsByName('cnewitm_id');

for (iI = oControls.length - 1; iI >= 0; iI--) {
oControls[iI].id = "citm_"+iElementId+"_id";
if (oControls[iI]) {
oControls[iI].setAttribute("name", "citm_"+iElementId+"_id", 0);
}
}

var oControls = document.getElementsByName('cnewitm_path');
for (iI = oControls.length - 1; iI >= 0; iI--) {
oControls[iI].id = "citm_"+iElementId+"_path";
if (oControls[iI]) {
oControls[iI].setAttribute("name", "citm_"+iElementId+"_path", 0);
}
}

var oControls = document.getElementsByName('cnewitm_name');
for (iI = oControls.length - 1; iI >= 0; iI--) {
oControls[iI].id = "citm_"+iElementId+"_name";
if (oControls[iI]) {
oControls[iI].setAttribute("name", "citm_"+iElementId+"_name", 0);
}
}

var oControls = document.getElementsByName('cnewitm_price');
for (iI = oControls.length - 1; iI >= 0; iI--) {
oControls[iI].id = "citm_"+iElementId+"_price";
if (oControls[iI]) {
oControls[iI].setAttribute("name", "citm_"+iElementId+"_price", 0);
}

}

var oControls = document.getElementsByName('cnewitm_count');
for (iI = oControls.length - 1; iI >= 0; iI--) {
var oControl = oControls[iI];
oControls[iI].id = "citm_"+iElementId+"_count";
if (oControls[iI]) {
oControls[iI].setAttribute("name", "citm_"+iElementId+"_count", 0);
}

oControl.onchange = function() {
oSelf.updateCount(iElementId, this.value);
return false;
}
}

var oControls = document.getElementsByName('cnewitm_price_total');
for (iI = oControls.length - 1; iI >= 0; iI--) {
oControls[iI].id = "citm_"+iElementId+"_price_total";
if (oControls[iI]) {
oControls[iI].setAttribute("name", "citm_"+iElementId+"_price_total", 0);
}
}

var oControls = document.getElementsByName('cnewitm_remove');
for (iI = oControls.length - 1; iI >= 0; iI--) {
var oControl = oControls[iI];
oControls[iI].id = "citm_"+iElementId+"_remove";
if (oControls[iI]) {
oControls[iI].setAttribute("name", "citm_"+iElementId+"_remove", 0);
}

oControl.onclick = function() {
oSelf.removeBasketItem(iElementId);
return false;
}
}

// append saved rows
for (iI = 0; iI < arrTempNewItems.length; iI++) {
var oParent = arrTempNewItemsParents[iI];
if (oParent) {
oParent.appendChild(arrTempNewItems[iI]);
}
}
}
}

this.updateBasket();
}


umiBasket.prototype.onUpdate = function(oBasketInfo) {
var iI = 0;
if (oBasketInfo.basket_items.length == 0) {
var oSbtns = document.getElementsByName('basket-submit');
for (iI = 0; iI < oSbtns.length; iI++) {
if (oSbtns[iI].tagName === "INPUT") {
oSbtns[iI].disabled = 1;
}
}
}
for (var iJ = 0; iJ < oBasketInfo.basket_items.length; iJ++) {
var oNextItemInfo = oBasketInfo.basket_items[iJ];

var oItemRows = document.getElementsByName('basketrow_'+oNextItemInfo.id);

var oIdsCtrls = document.getElementsByName('citm_'+oNextItemInfo.id+'_id');
var oNameCtrls = document.getElementsByName('citm_'+oNextItemInfo.id+'_name');
var oCountCtrls = document.getElementsByName('citm_'+oNextItemInfo.id+'_count');
var oPriceCtrls = document.getElementsByName('citm_'+oNextItemInfo.id+'_price');
var oTotalPriceCtrls = document.getElementsByName('citm_'+oNextItemInfo.id+'_price_total');
var oElementPathCtrls = document.getElementsByName('citm_'+oNextItemInfo.id+'_path');

for (iI = 0; iI < oItemRows.length; iI++) {
if (oItemRows[iI].style.display === 'none') {
oItemRows[iI].style.display = '';
}
}

for (iI = 0; iI < oIdsCtrls.length; iI++) {
if (oIdsCtrls[iI].tagName === "INPUT") {
oIdsCtrls[iI].value = oNextItemInfo.id;
} else {
oIdsCtrls[iI].innerHTML = oNextItemInfo.id;
}
}

for (iI = 0; iI < oNameCtrls.length; iI++) {
if (oNameCtrls[iI].tagName === "INPUT") {
oNameCtrls[iI].value = oNextItemInfo.name;
} else {
oNameCtrls[iI].innerHTML = oNextItemInfo.name;
}
}

for (iI = 0; iI < oCountCtrls.length; iI++) {
if (oCountCtrls[iI].tagName === "INPUT") {
oCountCtrls[iI].value = oNextItemInfo.count;
} else {
oCountCtrls[iI].innerHTML = oNextItemInfo.count;
}
}

for (iI = 0; iI < oTotalPriceCtrls.length; iI++) {
if (oTotalPriceCtrls[iI].tagName === "INPUT") {
oTotalPriceCtrls[iI].value = oNextItemInfo.price_total;
} else {
oTotalPriceCtrls[iI].innerHTML = oNextItemInfo.price_total;
}
}

for (iI = 0; iI < oPriceCtrls.length; iI++) {
if (oPriceCtrls[iI].tagName === "INPUT") {
oPriceCtrls[iI].value = oNextItemInfo.price;
} else {
oPriceCtrls[iI].innerHTML = oNextItemInfo.price;
}
}

for (iI = 0; iI < oElementPathCtrls.length; iI++) {
if (oElementPathCtrls[iI].tagName === "A") {
oElementPathCtrls[iI].href = oNextItemInfo.element_path;
} else {
oElementPathCtrls[iI].innerHTML = oNextItemInfo.element_path;
}
}

}

var oCartTotalCtrls = document.getElementsByName('order_total');

for (iI = 0; iI < oCartTotalCtrls.length; iI++) {
if (oCartTotalCtrls[iI].tagName === "INPUT") {
oCartTotalCtrls[iI].value = oBasketInfo.order_total;
} else {
oCartTotalCtrls[iI].innerHTML = oBasketInfo.order_total;
}
}

var oCartGlobalDiscount = document.getElementsByName('global_discount');

for (iI = 0; iI < oCartGlobalDiscount.length; iI++) {
if (oCartGlobalDiscount[iI].tagName === "INPUT") {
oCartGlobalDiscount[iI].value = oBasketInfo.global_discount;
} else {
oCartGlobalDiscount[iI].innerHTML = oBasketInfo.global_discount;
}
}


var oCartTotalCntCtrls = document.getElementsByName('total_count');

for (iI = 0; iI < oCartTotalCntCtrls.length; iI++) {
if (oCartTotalCntCtrls[iI].tagName === "INPUT") {
oCartTotalCntCtrls[iI].value = oBasketInfo.total_count;
} else {
oCartTotalCntCtrls[iI].innerHTML = oBasketInfo.total_count;
}
}
}

umiBasket.prototype.onAfterRemoveBasketItem = function (iElementId) {
var oCartRows = document.getElementsByName('basketrow_'+iElementId);
for (iI = 0; iI < oCartRows.length; iI++) {
oCartRows[iI].style.display = 'none';
}
}


umiBasket.prototype.addElement = function(iElementId, iCount) {
if (typeof(iCount) == "undefined") iCount = 1;
if (typeof(iElementId) !== 'undefined') {
var __self = this;
var hdl = function(oResponce) {
iElementId = oResponce.iElementId;
iCount = oResponce.iCount;
__self.onAfterAddElement(iElementId, iCount);
}
lLib.getInstance().makeRequest("/eshop/json_add_to_basket/"+iElementId+"/"+iCount+"/?", hdl);
}
}

umiBasket.prototype.updateBasket = function() {
var __self = this;
var hdl = function(oResponce) {
__self.onUpdate(oResponce);
}
lLib.getInstance().makeRequest('/eshop/json_get_basket/?', hdl);
}

umiBasket.prototype.updateCount = function(iElementId, iCount) {
if (typeof(iCount) == "undefined") iCount = 1;
if (typeof(iElementId) !== 'undefined') {
var __self = this;
var hdl = function(oResponce) {
__self.updateBasket();
}
lLib.getInstance().makeRequest("/eshop/json_update_count/"+iElementId+"/"+iCount+"/?", hdl);
}
}



umiBasket.prototype.removeBasketItem = function(iElementId) {
if (typeof(iElementId) !== "undefined") {
var __self = this;
var hdl = function(oResponce) {
__self.onAfterRemoveBasketItem(iElementId);
__self.updateBasket();
}
lLib.getInstance().makeRequest("/eshop/json_remove_from_basket/"+iElementId+"/?", hdl);
}
}
тут нужно править?
Название: Re:[РЕШЕНО] Отредактировать basket.js
Отправлено: admin от 11 Ноября 2012, 21:14:02
зачем изобретать новый скрипт, почему не воспользоваться стандартным umi набором js для работы с корзиной?

смотрите статью http://umihelp.ru/forum/index.php/topic,1131.0.html и смотрите презентацию с курса, там первая же тема про корзину, где, как и что подключать http://www.umi-cms.ru/filemanager/download/83749

сами файлы /js/site есть в демо сайте demodizzy. На всякий случай, выкладываю папку site сюда