Динамическое отображение цены в карточке товара

Здравствуйте. Сделал дополнительные параметры для товара. В корзину все добавляется и цена там считается нормально, но вот в карточке товара цена не обновляется, при клике по чекбоксу. В консоли пишет - SHK is not defined.

Код карточки товара

<div class="card_image">
  <img src="[[*product_image]]" alt="">
</div>
<div class="card_info">
  <form action="[[~[[*id]]? &scheme=`abs`]]" method="post" class="card_form" style="display: block;">
      	<table class="card_params shk-item" border="0">
           <tr>
               <td>Номер в каталоге</td>
               <td>[[*product_id]]</td>
           </tr>
           <tr>
               <td>Материал</td>
               <td>[[*product_material]]</td>
           </tr>
           <tr>
               <td>Стоимость</td>
               <td><span class="card_price shk-price">[[*product_price]]</span></td>
           </tr>       
       	</table>

      </div>
      <div class="card_option">
          <span>Дополнительные опции</span><br />
          <div class="opt">
              [[*params:replace=`[[+id]]==[[*id]]`]]
          </div>
      </div>
        
        <input type="hidden" name="shk-id" value="[[*id]]" />
        <input type="hidden" name="shk-name" value="[[*pagetitle]]" />
        <input type="hidden" name="shk-count" value="1" />
                                
        <div class="card_button">
            <button type="submit" class="shk-but details" style="padding: 7px 15px !important"><i class="fa fa-shopping-cart" aria-hidden="true"></i></button>
          <a class="fancybox" href="#callback">
              <button>Заказать в 1 клик</button>
          </a>
        </div>
  </form>

</div>

доп. параметр - params
параметры ввода - param-edit
параметры вывода:

  • shk_chekbox
  • SHK.additOpt(this)
  • shk_param
  • div
  • нет
  • params

в опциях ввода параметров все указываю верно - перед параметром цены ставлю + или * (в зависимости от требований)

В чем проблема? Я понимаю что где-то в карточке товара что-то не так указал, но разглядеть не могу.(( Да и в корзине же считается все...

Помогите!

noJquery везде отключен.

Так из коробки и нет динамического обновления цены, нужно писать обработчик на js.
Для себя я написал маленький скрипт, который обрабатывает вывод любого кол-ва доп. параметров с ценой, для всех трех типов radio, checkbox, select-one.
Настройка:

  1. В настройках tv-параметра (в Параметрах вывода) заменил название обработчика событий SHK.additOpt(this) на свой selectParam(this)

  2. Значение цены должно быть в теге с id="cena", для цены по акции с id="cena_action"

<div class="price">Цена: <span id="cena">[[*price:num_format]]</span> <span id="currency">[[++shk3.currency]]</span></div>```
  1. В конец чанка, после вывода формы добавить скрипт.
    Получится как то так (глубоко объяснять свой чанк товара не буду, чтобы не засорять пространство.):
<form action="[[*uri]]" method="post">
		  <input type="hidden" name="shk-name" value="[[*pagetitle]]" />
		  <input type="hidden" name="shk-count" value="1" />
		  
		  [[*complectation:!empty=`<div class="dop-param-name">Дополнительная комплектация:</div><div class="param_select">[[*complectation:replace=`[[+id]]==[[*id]]`]]</div>`]]
		  [[*servis:!empty=`<div class="dop-param-name">Сервис:</div><div class="param_select">[[*servis:replace=`[[+id]]==[[*id]]`]]</div>`]]
		  [[*obsluj:!empty=`<div class="dop-param-name">Гарантия:</div><div class="param_select">[[*obsluj:replace=`[[+id]]==[[*id]]`]]</div>`]]

			[[*action:is=`*1*`:then=`<input type="hidden" name="act__[[*id]]__add"  value="акция" />
			<input type="hidden" name="shk-id" value="[[*id]]__price_action" />
			<div class="price action-no">Цена: <span id="cena">[[*price:num_format]]</span> <span id="currency">[[++shk3.currency]]</span></div>
			<div class="price-action">Цена по акции: <span id="cena_action">[[*price_action:num_format]]</span> <span id="currency_action">[[++shk3.currency]]</span></div>
			`:else=`<input type="hidden" value="[[*id]]" name="shk-id" />
			<div class="price">Цена: <span id="cena">[[*price:num_format]]</span> <span id="currency">[[++shk3.currency]]</span></div>
			`]]
		  <button type="submit" name="shk-submit"></button>
		</form>
<script>
  var addPrice=0; //Сумарная наценка за опции
  var options = {}; //Объект для хранения выбранных опций и их цены
  var PriceCarent = document.getElementById("cena").innerHTML; //получаю значение Цены в тегах с id cena;
  PriceCarent=Number(PriceCarent.replace(/\s+/g,''));//вырезаю пробелы и табуляции, и превращаю в число;
  
  //Тоже самое делаю для цены по акции
  var PriceCarentAction = document.getElementById("cena_action").innerHTML;
  PriceCarentAction=Number(PriceCarentAction.replace(/\s+/g,''));
  
  function selectParam(element) {
	//console.log(element);	
	var TypeParam = element.type; //получаю значение атрибута type -> Тип списка (radio, checkbox, select-one)
	//console.log("TypeParam=" + TypeParam);

	//получаю значение атрибута value
	if (TypeParam == "select-one") //для select-one (выпадающий список с одиночным выбором)
	{
	  var idSelect = element.id; //получаю значение атрибута id
	  //console.log("id=" + idSelect);
	  var sel = document.getElementById(idSelect); // Получаем наш список
	  var valueSelect = sel.options[sel.selectedIndex].value; // Получаем значение выделенного (selected="selected") элемента
	  //console.log("valueSelect=" + valueSelect);
	  var param = valueSelect;
	}
	else var param = element.value; //для переключателей radio и checkbox

	//Цена опции
	var pos = param.indexOf("__") + 2;
	var PriceParam = Number(param.substring(pos));
	//console.log("PriceParam=" + PriceParam);

	//Имя опции	
	var NameParam = element.name; //получаю значение атрибута name
	//console.log("NameParam=" + NameParam);


//Формирую объект (массив) с названиями выбранных опций и их цен
	if(TypeParam == "radio" || TypeParam == "select-one") { //console.log("Click for RADIO or SELECT");
	  options [NameParam] = PriceParam;
	}
	else { //console.log("Click for CHECKBOX");
	  if (options [NameParam] > 0) 	options [NameParam] = 0;
	  else options [NameParam] = PriceParam;
	  //console.log(options);
	} 
	
	var addPrice=0;
	for (var key in options) { // Перебор всех свойств объекта console.log( "Ключ: " + key + " значение: " + options[key] );
	  addPrice += options[key]; //Суммирую все цены доп. опций
	}

	// Вывожу в заданный блок с Id - Подменяю значения цен в блоке с ценой для покупателя
	if (PriceCarent > 0) {
	  var PriceSum = String(PriceCarent + addPrice); //Преобразовываю сумму цен в строку
	  PriceSum = PriceSum.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 '); //разделяю разряды цифры пробелом
	  document.getElementById("cena").innerHTML = PriceSum;
	}
	if (PriceCarentAction > 0) {
	  var PriceSumAction = String(PriceCarentAction + addPrice);
	  PriceSumAction = PriceSumAction.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 ');
	  document.getElementById("cena_action").innerHTML = PriceSumAction;
	}
  }
</script>

P.S. Много камней не кидайте, js вообще не знаю. Но скрипт рабочий :)

Если цена по акции не нужна, то все еще проще:

<form action="[[*uri]]" method="post">
		  <input type="hidden" name="shk-name" value="[[*pagetitle]]" />
		  <input type="hidden" name="shk-count" value="1" />
                  <input type="hidden" value="[[*id]]" name="shk-id" />
		  
		  [[*complectation:!empty=`<div class="dop-param-name">Дополнительная комплектация:</div><div class="param_select">[[*complectation:replace=`[[+id]]==[[*id]]`]]</div>`]]
		  [[*servis:!empty=`<div class="dop-param-name">Сервис:</div><div class="param_select">[[*servis:replace=`[[+id]]==[[*id]]`]]</div>`]]
		  [[*obsluj:!empty=`<div class="dop-param-name">Гарантия:</div><div class="param_select">[[*obsluj:replace=`[[+id]]==[[*id]]`]]</div>`]]
		  <div class="price">Цена: <span id="cena">[[*price:num_format]]</span> <span id="currency">[[++shk3.currency]]
		  <button type="submit" name="shk-submit"></button>
</form>
<script>
  var addPrice=0; //Сумарная наценка за опции
  var options = {}; //Объект для хранения выбранных опций и их цены
  var PriceCarent = document.getElementById("cena").innerHTML; //получаю значение Цены в тегах с id cena;
  PriceCarent=Number(PriceCarent.replace(/\s+/g,''));//вырезаю пробелы и табуляции, и превращаю в число;
  
  function selectParam(element) {
	//console.log(element);	
	var TypeParam = element.type; //получаю значение атрибута type -> Тип списка (radio, checkbox, select-one)
	//console.log("TypeParam=" + TypeParam);

	//получаю значение атрибута value
	if (TypeParam == "select-one") //для select-one (выпадающий список с одиночным выбором)
	{
	  var idSelect = element.id; //получаю значение атрибута id
	  //console.log("id=" + idSelect);
	  var sel = document.getElementById(idSelect); // Получаем наш список
	  var valueSelect = sel.options[sel.selectedIndex].value; // Получаем значение выделенного (selected="selected") элемента
	  //console.log("valueSelect=" + valueSelect);
	  var param = valueSelect;
	}
	else var param = element.value; //для переключателей radio и checkbox

	//Цена опции
	var pos = param.indexOf("__") + 2;
	var PriceParam = Number(param.substring(pos));
	//console.log("PriceParam=" + PriceParam);

	//Имя опции	
	var NameParam = element.name; //получаю значение атрибута name
	//console.log("NameParam=" + NameParam);

//Формирую объект (массив) с названиями выбранных опций и их цен
	if(TypeParam == "radio" || TypeParam == "select-one") { //console.log("Click for RADIO or SELECT");
	  options [NameParam] = PriceParam;
	}
	else { //console.log("Click for CHECKBOX");
	  if (options [NameParam] > 0) 	options [NameParam] = 0;
	  else options [NameParam] = PriceParam;
	  //console.log(options);
	} 
	
	var addPrice=0;
	for (var key in options) { // Перебор всех свойств объекта console.log( "Ключ: " + key + " значение: " + options[key] );
	  addPrice += options[key]; //Суммирую все цены доп. опций
	}

	// Вывожу в заданный блок с Id - Подменяю значения цен в блоке с ценой для покупателя
	if (PriceCarent > 0) {
	  var PriceSum = String(PriceCarent + addPrice); //Преобразовываю сумму цен в строку
	  PriceSum = PriceSum.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 '); //разделяю разряды цифры пробелом
	  document.getElementById("cena").innerHTML = PriceSum;
	}
  }
</script>

Чем больше узнаю людей, тем больше я люблю компьютер.

Это не критично, но увидел ошибку в варианте без цены по акции, не верно скопировал:
строка

<div class="price">Цена: <span id="cena">[[*price:num_format]]</span> <span id="currency">[[++shk3.currency]]

нужно закрыть span и div:

<div class="price">Цена: <span id="cena">[[*price:num_format]]</span> <span id="currency">[[++shk3.currency]]</span></div>

Чем больше узнаю людей, тем больше я люблю компьютер.

@Asderkdw а что за SHK.additOpt(this)?
я так понял что этот метод добавляет опции товара к цене динамически. И вот при его вызове ошибка. Думаю что в этом проблема, так как на видео, которое я смотрел все работало без "велосипедов" на JS.

Благодарю за помощь. Только вы откликнулись!

@finc_85 Возможно и было динамически раньше. Но у меня не заработал обработчик SHK.additOpt(this) и ответа на вопрос тоже не нашел. Потому и написал свой скриптик с обработкой.
Собственно это просто путь для решения других не стандартных задач, потому и предпочел свой обработчик, который я понимаю как работает.
И пожалуйста :)

Чем больше узнаю людей, тем больше я люблю компьютер.

@Asderkdw Ваш скрипт видимо умеет только складывать. А если требуются другие операции вычитание/умножение/деление?
Для моей задачи нужны проценты, но я решил обойтись умножением *0.ХХ, а скрипт написал NaN.

Простите, а то что на демо-сайте
http://demo.modx-shopkeeper.ru/katalog/planshetyi-i-telefonyi/msi-reiciendis-7893.html

чем вас не устроило?

@slaad не работает SHK.additOpt(this) в стоке, пришлось искать велосипед в виде этого скрипта.

@Ren посмотрите как на демо сайте это реализовано, там ведь все работает.

http://forum.modx-shopkeeper.ru/topic/50/демо-сайт-shopkeeper-3-x

@slaad с демкой так и не разобрался. В демке: тв-шка - params, в шаблоне вызывается [[*param1]]. У каждого товара есть два параметра 500 и 1000. Ставим галки, все плюсуется.
Делаю тоже самое у себя. Но при вызове [[*param1]] конечно пусто, ведь она называется paramS. А если вызвать одноименную то список выводится, а ничего не работает.
В итоге вопрос - почему в демке указано именно param1, и как это влияет, откуда берется?

p.s. в демке кстати у инпутов name="param1__138__0" и т.д., а у меня name="params__" на всех.

Эта запись удалена!

@Ren я понимаю, что проще вопросы задать, но для кого же доки пишут?))

почитайте раздел Дополнительные параметры товаров:
http://wiki.modx-shopkeeper.ru/doku.php?id=shopkeeper3
вот чувствую, что пришли не читая и задали вопрос, что ничего не работает, оно и не будет.

@slaad плохое у вас чутье. я с шопкипером еще с первой версии. доки эти уже наизусть знаю. но тут прям засада.
уже сделал, что параметры нормально отображаются:

<div><input class="shk_param" type="radio" name="params__101" value="0__1" id="params1010" onclick="SHK.additOpt(this)" /> <label for="params1010">Плюс 1</label></div>
<div><input class="shk_param" type="radio" name="params__101" value="1__1000" id="params1011" onclick="SHK.additOpt(this)" /> <label for="params1011">Плюс 1000</label></div>
<div><input class="shk_param" type="radio" name="params__101" value="2__*2" id="params1012" onclick="SHK.additOpt(this)" /> <label for="params1012">Умножить на 2</label></div>

И нифига...

@slaad Разобрался. Оказывается все работает, в корзину прилетает правильная цена и появляется поле с "дополнительным параметром", но на странице товара обновление цены не происходит в связи с одной простой мелочью. Тег цены на сайте должен иметь класс "shk-price". В инструкции (ни в этой http://wiki.modx-shopkeeper.ru/doku.php?id=shk3_docs ни в этой http://wiki.modx-shopkeeper.ru/doku.php?id=shopkeeper3) вообще об этом ни слова.

Теперь у меня и конвертирует по курсу и обновляет цену плюсуя и умножая.

Участник @ren написал в Динамическое отображение цены в карточке товара:

shk-price

Имею такой код чанка, но стоимость товара в корзине не меняется
<form action="[[~[[*id]]? &scheme=abs]]" method="post">

                            <input type="hidden" name="shk-id" value="[[*id]]" />                                
                            <input type="hidden" name="shk-count" value="1" />
                            [[*col:replace=`[[+id]]==[[*id]]`]]
                            <div class="shk-price">[[!*price]]руб.</div>
                            
                            <div class="product-price">
                              <button type="submit" class="shk-but">В корзину <i></i></button>
                            </div> 
                            
                     </form>

Подскажите, где ошибка?

Так из коробки и нет динамического обновления цены, нужно писать обработчик на js.

Не правда, есть. Смотрите демо.

В консоли пишет - SHK is not defined.

Значит на странице не вызывается сниппет Shopkeeper или отключены его скрипты.

Похоже, подключение к Форум | MODX Shopkeeper было разорвано, подождите, пока мы пытаемся восстановить соединение.