Дочерние товары списком или таблицей в Virtuemart 3

Задача вывести дочерние товары в карточке родительского, у меня появляется довольно часто, иногда получается обойтись стандартным вывод настраиваемого поля «Общий дочерний вид» в виде Select, но иногда этого не хватает, и необходимо вывести товары списком с возможностью покупки каждого товара отдельно.  Сразу хочу сказать, что в большинстве случаев мне помогает в этом плагин Catproduct, но иногда он не совсем подходит для решения задачи.

Предложенное мною решение не слетит после обновления Virtuemart, по-этому нахожу его наиболее практичным для использования. Давайте начнём!

Редактировать мы будем всего один файл — customfield.php, именно этот файл отвечает за отображение настраиваемых полей. Мы изменим стандартный вывод поля «Общий дочерний вид».

Не буду вдаваться в подробности, просто скажу, что предварительно Вам необходимо создать товар, в нём создать дочерние и для родительского товара во вкладке «Настраиваемые поля» отобразить поле типа «Общий дочерний вид» (которое конечно предварительно нужно создать в разделе «Настраиваемые поля».)

1. Открываем файл: /templates/ваша_тема/html/com_virtuemart/sublayouts/customfield.php (если у Вас такого нет, тогда идите сюда: /components/com_virtuemart/sublayouts/ — скопируйте всю папку sublayouts по адресу /templates/ваша_тема/html/com_virtuemart/sublayouts/)

2. Редактируем файл:

Находим строчку:

$productChild = $productModel->getProduct((int)$child,true);

И сразу под ней вставляем:

$weight = round($productChild->product_weight); //Округляем вес товара
$stock = $productChild->product_in_stock; //Получаем остатки товара
if (JRequest::getVar('view')=='productdetails') { //Если находимся в карточке, то показывается этот код
$html .='<div class="childs-area">';
$html .='<div class="sku">Артикул: '. $productChild->product_sku .'</div>'; //Отображает артикул
if ($weight > 0) { //Если вес товара больше 0 то вес отображается
$html .='<div class="weight">Вес: '. $weight .' '. $productChild->product_weight_uom .'</div>'; //Отображаем вес если он больше 0
}
$html .='<div class="name">Наимменование: '. $productChild->product_name .'</div>'; //Отображаем название товара
$html .='<div class="price">Цена: '. $productChild->allPrices['0']['salesPrice'] .' руб.</div>'; //Отображаем цену
if ($stock > 0) { //Если остаток больше 0 то отображаем нажпись "1-2 дня (в наличии)"
$html .='1-2 дня (в наличии)';
}
if ($stock == 0) { //Если остаток 0 выводим надпись "3-5 дней (нет в наличии)"
$html .='3-5 дней (нет в наличии)';
}
//Выводим кнопку добавления в корзину и регулятор количества
$html .='<form method="post" class="product js-recalculate" action="#">
<div class="addtocart-bar">
<span class="quantity-box">
<input type="text" class="quantity-input js-recalculate" name="quantity[]" data-errstr="You can buy this product only in multiples of %s pieces!" value="0" init="0" step="1">
</span>
<span class="quantity-controls js-recalculate">
<input type="button" class="quantity-controls quantity-plus">
<input type="button" class="quantity-controls quantity-minus">
</span>
<span class="addtocart-button">
<input type="submit" name="addtocart" class="addtocart-button" value="Add to Cart" title="Add to Cart"> </span> <input type="hidden" name="virtuemart_product_id[]" value="'. $productChild->virtuemart_product_id .'">
<noscript>&amp;lt;input type="hidden" name="task" value="add"/&amp;gt;</noscript></div>
<input type="hidden" name="option" value="com_virtuemart">
<input type="hidden" name="view" value="cart">
<input type="hidden" name="virtuemart_product_id[]" value="'. $productChild->virtuemart_product_id .'">
<input type="hidden" name="pname" value=". $productChild->product_name .'">
<input type="hidden" name="pid" value="'. $productChild->virtuemart_product_id .'">
<input type="hidden" name="Itemid" value="101"> </form>';
$html .='</div>';

//По умолчанию этот код выводится не там, с помощью JQuery я перемещаю его его #childs в div addtocart-area, а также, при необходимости скрываю кнопку "Выберите вариант"
$html .='<script>jQuery(document).ready(function() {
jQuery("#childs").appendTo(".addtocart-area");
jQuery(".addtocart-button-disabled").hide();
});</script>';
}
//Ну и здесь тоже самое, только для отображения в категории. Что бы этот код отображался в категории, в настройках Virtuemart (Внешний вид) должна стоять галочка "Показывать произвольные поля товаров в представлении списков"
if (JRequest::getVar('view')=='category') {
$html .='<div class="childs-area">';

if ($weight > 0) {
$html .='<div class="weight">Вес: '. $weight .' '. $productChild->product_weight_uom .'</div>';
}
$html .='<div class="price">Цена: '. $productChild->allPrices['0']['salesPrice'] .' руб.</div>';
$html .='<a href="'. $product->link.$ItemidStr .'">Ссылка</a>';
$html .='<form method="post" class="product js-recalculate" action="#">
<div class="addtocart-bar">
<span class="quantity-box">
<input type="text" class="quantity-input js-recalculate" name="quantity[]" data-errstr="You can buy this product only in multiples of %s pieces!" value="1" init="1" step="1">
</span>
<span class="quantity-controls js-recalculate">
<input type="button" class="quantity-controls quantity-plus">
<input type="button" class="quantity-controls quantity-minus">
</span>
<span class="addtocart-button">
<input type="submit" name="addtocart" class="addtocart-button" value="Add to Cart" title="Add to Cart"> </span> <input type="hidden" name="virtuemart_product_id[]" value="'. $productChild->virtuemart_product_id .'">
<noscript>&amp;lt;input type="hidden" name="task" value="add"/&amp;gt;</noscript>
</div> <input type="hidden" name="option" value="com_virtuemart">
<input type="hidden" name="view" value="cart">
<input type="hidden" name="virtuemart_product_id[]" value="'. $productChild->virtuemart_product_id .'">
<input type="hidden" name="pname" value=". $productChild->product_name .'">
<input type="hidden" name="pid" value="'. $productChild->virtuemart_product_id .'">
<input type="hidden" name="Itemid" value="101"> </form>';
$html .='</div>';
$html .='<script>jQuery(document).ready(function() {
jQuery(".addtocart-button-disabled").hide();
});</script>';
}

Дальше нам необходимо закомментировать стандартный вывод, для этого находим:

$html .='</div>';
$html .= JHtml::_ ('select.genericlist', $options, $fieldname, $attribs);

И меняем на:

//$html .='</div>';
//$html .= JHtml::_ ('select.genericlist', $options, $fieldname, $attribs);

Вот и всё! От себя добавлю, что код получился очень простой и понятный для «допила». Все данные о товарах хранит в себе массив $productChild, вы можете вывести любую информацию о товаре, обращаясь к нему.

Несколько примеров:

$productChild->mf_name; //производитель
$productChild->product_s_desc; //краткое описание
$productChild->categoryItem->category_name; //название категории

Комментариев: 6 на Дочерние товары списком или таблицей в Virtuemart 3

Дочерние товары выводятся, но не добавляются в корзину. И еще небольшой недостаток — в строке с дочерними товарами выводится и родительский товар.

Нет, родительский товар там не отображается, разве только ты сам поставил галку в настраиваемом поле, что бы он там отображался.
Насчет кнопки купить — надо смотреть, для оригинального шаблона всё работает.

Отключила меню — заработало.
смотрится отлично.
Вопрос не совсем в эту тему, а можно в категории на странице «categories» вывести название пяти первых товаров со ссылками на них?

А можно в корзине выводить родительский товар в том числе? Сейчас отражается только дочерний.

Обьясни зачем?
Как видишь в статье идет речь о дочерних товарах, если поковыряться то я думаю можно что-то придумать, просто хочу понимать какие обстоятельства тебя вынуждают это делать.

Допустим, у меня есть родительский товар — сальники и есть дочерние товары — варианты этих сальников с размерами (их очень много). Помимо сальников и тд в магазине указана еще пачка других уплотнений, часть размеров которых совпадает. Артикулов нет. соответственно, в корзине в идеале бы видеть и родителя и дочку (с размерами). Плюс при возврате на страницу товара в идеале возвращаться на страницу родителя, чтобы продолжить выбор уже на этой странице.
Это один из вариантов, когда такое исполнение может сократить количество работы

Комментировать