Jump to content

[FREE TUTORIAL]1click multi add combination to cart


Recommended Posts

Hi, I am an one-month newbie in prestashop. I have read lots of topics here for solving my problems, so here is my contribution.

I found there is no such topic talking about multiple add combinations/attributes of products to cart in ps1.7 version, after one week trying and failure, I finally found the solution. The steps are: first listing the combination, then replacing the default qty input, and add js to make it effect. Then I will explain more specifically.

446027836_.thumb.png.b00c9d475ad04ee8c5c31deeaeb06633.png

In the following steps I will use the classic theme to show, please adjust it by your theme.

1. Edit the add-to-cart.tpl in yourtheme/templates/catalog/_partials/, after this code

 <span class="control-label">{l s='Quantity' d='Shop.Theme.Catalog'}</span>

we add a condition, which only show if the product has combination or we use the default. Here we delete the qty <div> and we will use ourselves and change data-button-action="add-to-cart" to data-button-action="multi-add-to-cart".

{if $product.id_product_attribute > 0}
    {block name='product_quantity'}
      <div class="product-quantity clearfix">
        <div class="add">
          <button
            class="btn btn-primary add-to-cart"
            data-button-action="multi-add-to-cart"
            type="submit"
            {if !$product.add_to_cart_url}
              disabled
            {/if}
          >
            <i class="material-icons shopping-cart">&#xE547;</i>
            {l s='Add to cart' d='Shop.Theme.Actions'}
          </button>
        </div>

        {hook h='displayProductActions' product=$product}
      </div>
    {/block}

    {block name='product_availability'}
      <span id="product-availability" class="js-product-availability">
        {if $product.show_availability && $product.availability_message}
          {if $product.availability == 'available'}
            <i class="material-icons rtl-no-flip product-available">&#xE5CA;</i>
          {elseif $product.availability == 'last_remaining_items'}
            <i class="material-icons product-last-items">&#xE002;</i>
          {else}
            <i class="material-icons product-unavailable">&#xE14B;</i>
          {/if}
          {$product.availability_message}
        {/if}
      </span>
    {/block}

    {block name='product_minimal_quantity'}
      <p class="product-minimal-quantity js-product-minimal-quantity">
        {if $product.minimal_quantity > 1}
          {l
          s='The minimum purchase order quantity for the product is %quantity%.'
          d='Shop.Theme.Checkout'
          sprintf=['%quantity%' => $product.minimal_quantity]
          }
        {/if}
      </p>
    {/block}
{else}

do not forget add another {/if} besides the {/if} in the end of this file.

2. we add ourselves' qty input after the color input. Edit  yourtheme/templates/catalog/_partials/product-variants.tpl

{elseif $group.group_type == 'color'}
        <ul id="group_{$id_attribute_group}">
          {foreach from=$group.attributes key=id_attribute item=group_attribute}
            <li class="float-xs-left input-container">
              <label aria-label="{$group_attribute.name}">
                {*you could change the radio type to checkbox and delete {if $group_attribute.selected} checked="checked"{/if}*}
                <input class="input-color" type="checkbox" data-product-attribute="{$id_attribute_group}" name="group[{$id_attribute_group}]" value="{$id_attribute}" title="{$group_attribute.name}">
                <span
                  {if $group_attribute.texture}
                    class="color texture" style="background-image: url({$group_attribute.texture})"
                  {elseif $group_attribute.html_color_code}
                    class="color" style="background-color: {$group_attribute.html_color_code}" 
                  {/if}
                ><span class="sr-only">{$group_attribute.name}</span></span>
              </label>
              <div class="num">
				<span type="button" class="reduc btn btn-md"><i class="icon-minus" id="reduc"></i></span>
				<input type="text" class="multi_product_quantity" value="0"/>
				<span type="button" class="add btn btn-md"><i class="icon-plus" id="add"></i></span>
			</div>
            </li>
          {/foreach}

or if you wan to add it to other attributes, just paste it before another </li></foreach>

{elseif $group.group_type == 'radio'}
        <ul id="group_{$id_attribute_group}">
          {foreach from=$group.attributes key=id_attribute item=group_attribute}
            <li class="input-container float-xs-left">
              <label>
                {*if it not work here please change the input class to input-color or change your css*}
                <input class="input-radio" type="radio" data-product-attribute="{$id_attribute_group}" name="group[{$id_attribute_group}]" value="{$id_attribute}" title="{$group_attribute.name}"{if $group_attribute.selected} checked="checked"{/if}>
                <span class="radio-label">{$group_attribute.name}</span>
              </label>
              <div class="num">
				<span type="button" class="reduc btn btn-md"><i class="icon-minus" id="reduc"></i></span>
				<input type="text" class="multi_product_quantity" value="0"/>
				<span type="button" class="add btn btn-md"><i class="icon-plus" id="add"></i></span>
			</div>
            </li>
          {/foreach}

3. Add the css like this or whatever you wish:

.num{
padding-left:10px;
display: inline-block;
float: right;
}
.icon-plus .icon-minus{
font-size: 1.5rem;
}

4. The last and most important is add the js. You could put it in yourthemes/assets/js/custom.js or just put it in the end of product-variants.tpl(Not recommended).

$(document).ready(function () {
//sum the qty input
    $(".icon-plus").each(function () {
        $(this).click(function () {
            var $multi = 0;
            var vall = $(this).parent().prev().val();
            vall++;
            $(this).parent().prev().val(vall);
            $multi = parseFloat(vall);
            if ($multi > 0) {
//if you use it for other type attributes please add '.input-radio' into the find('.input-color'). The below as same.
                $(this).parent().parent().prev().find('.input-color').prop('checked', true);
            }
            $(this).parent().prev().find('.multi_product_quantity').val(Math.round($multi));
        })
    })
//reduc the qty input
    $(".icon-minus").each(function () {
        $(this).click(function () {
            var $multi1 = 0;
            var vall1 = $(this).parent().next().val();
            vall1--;
            if (vall1 <= 0) {
                vall1 = 0;
                $(this).parent().parent().prev().find('.input-color').prop('checked', false);
            }
            $(this).parent().next().val(vall1);
            $multi1 = parseFloat(vall1);
            $(this).parent().next().val(Math.round($multi1));
        })

    })
const $body = $('body');
$body.on('click', '[data-button-action="multi-add-to-cart"]', (event) => {
    event.preventDefault();
    const $form = $(event.target.form);
    const actionURL = $form.attr('action');
              //make the quantity to int
            var wanted_items = $('.multi_product_quantity').filter(function() {
                                    return parseInt($(this).val(), 10) > 0;
                                });
              //if all the qty input is 0, we give customer a alert
            if(wanted_items.length == 0)
                alert("No Selection any product!");
            else {
              // foreach the qty input
                for(let item of wanted_items){
              //if one of these is 0, we go to next
                if($(item).val()===0){return;}
                $(item).parent().prev().find('.input-color').prop("checked");
                let qty = $(item).val();
                let idProduct = document.getElementsByName('id_product')[0].value;
                let idProductAttribute = $(item).parent().prev().find('.input-color').val();
                let group = $(item).parent().prev().find('.input-color').attr('data-product-attribute');
                let query = `${$form.serialize()}&add=1&action=update&id_product=${idProduct}&qty=${qty}&group[${group}]=${idProductAttribute}&ipa=${idProductAttribute}`;
                                $.post(actionURL, query, null, 'json')
                  .then((resp) => {
                        prestashop.emit('updateCart', {
                        reason: {}, resp,
                  });
                }).fail((resp) => {
                        prestashop.emit('handleError', {eventType: 'addProductToCart', resp,});
                                });
              //after add to cart, set all the qty input to 0 and make the input color or input radio to unchecked.
                $(item).parent().parent().find('.multi_product_quantity').val("0");
                $(item).parent().prev().find('.input-color').prop("unchecked");
                };
        }
        });
});

This is my first post on the prestashop forum, maybe this is not good solution but it is free! Hopely it will be useful for you.

Hava fun!

For other version and solutions you could see here:

 

 

Edited by Greconan (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...