> For the complete documentation index, see [llms.txt](https://partners.tray.com.br/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://partners.tray.com.br/themes/construindo-seu-template/referencias/componentes/adicionar-ao-carrinho-sem-sair-da-pagina.md).

# Adicionar ao carrinho sem sair da página

Snippet para adicionar o produto ao carrinho sem sair da página. O artigo tem por objetivo mostrar a utilização da API do carrinho para adição do produto.

**Modelo 1 - Simples**

Caso o produto possua variação, ao clicar em comprar é redirecionado para a página interna do produto.

{% tabs %}
{% tab title="HTML" %}

```html
{#
 # Snippets com botão de Comprar
 # elements/snippets/add-cart.html
#}

{% if product.available %}
  {% if product.stock > 0 %}
    <div class="addcart" id="variants">
      {% if product.has_variation %}
        <a href="{{ product.link }}"><input type="button" class="addCart" value="Comprar"/></a>
      {% else %}
        <input type="button" class="addCart" value="Comprar" onclick="addCart({{ product.id }})" />
      {% endif %}
    </div>
  {% else %}
    <span> Produto não Disponivel</span>
  {% endif %}
{% else %}
  <span> Produto não Disponivel</span>
{% endif %}
```

{% endtab %}

{% tab title="Javascript" %}

```javascript
function addCart(dataProductId){
    var dataSession = $("html").attr("data-session");
  $.ajax({
    method: "POST",
    url: "/web_api/cart/",
    contentType: "application/json; charset=utf-8",
    data: '{"Cart":{"session_id":"'+dataSession+'","product_id":"'+dataProductId+'","quantity":"1"}}'
  }).done(function( response, textStatus, jqXHR ) {
    console.log(response);
    var qtdCart = parseInt($("span[data-cart=amount]").html());
    $("span[data-cart=amount]").html(qtdCart + 1);
  }).fail(function( jqXHR, status, errorThrown ){
    var response = $.parseJSON( jqXHR.responseText );
    console.log(response);
  });
}
```

{% endtab %}
{% endtabs %}

**Modelo 2 - Completo**

Essas funções não suportam campos adicionais. Produtos com campos adicionais serão adicionados sem os devidos valores desses respectivos campos.

Também não é recomendado utilizar esse modelo quando o cliente tem a opção de B2B ativa na loja.

{% tabs %}
{% tab title="HTML" %}

```html
{% if product.available and (product.stock > 0 or settings.without_stock_sale) and not product.upon_request %}
    <div class="variants">

        {% set productVar = product.Variants|length ? product.Variants :  product.variants %}
        {% set listVariants = [] %}
        {% set listVariantsSecond = [] %}
        {% set variants = [] %}
        {% set variantName = '' %}
        {% set variantSecondName = '' %}

        {% for variant in productVar %}

            {% if loop.index == 1 %}

                {% if variant.Sku[1] %}
                    {% set variantSecondName = variant.Sku[1].type %}
                {% endif %}
                {% set variantName = variant.Sku[0].type %}

            {% endif %}

            {% set stock = variant.stock %}

            {% if variant.id|length == '0' %}

                {% set variants = '' %}

            {% elseif variant.Sku[1] %}

                {% set variants = variants|merge([{ "price": {"price": variant.price_offer != 0 ? variant.price_offer : variant.price, "payment": variant.payment_option }, "id": variant.id, "stock": stock, "option": variant.Sku[0].value, "option2": variant.Sku[1].value }]) %}

                {% set valueSecond = variant.Sku[1].value %}
                {% if not (valueSecond in listVariantsSecond) %}
                    {% set listVariantsSecond = listVariantsSecond|merge([valueSecond]) %}
                {% endif %}

            {% else %}

                {% set variants = variants|merge([{ "price": {"price": variant.price_offer != 0 ? variant.price_offer : variant.price, "payment": variant.payment_option }, "id": variant.id, "stock": stock, "option": variant.Sku[0].value }]) %}

            {% endif %}

            {% set value = variant.Sku[0].value %}
            {% if not (value in listVariants) %}
                {% set listVariants = listVariants|merge([value]) %}
            {% endif %}

        {% endfor %}

        <form class="list-variants" data-id="{{ product.id }}" data-variants='{{ variants ? variants|json_encode : "" }}' data-api-cart="1">

            {% if variantName %}
            <label>
                <span>{{ variantName }}</span>
                <select class="first" required>
                    <option value="" hidden>Selecione</option>
                    {% for value in listVariants %}
                        <option value="{{ value }}" data-price="{{ price }}">{{ value }}</option>
                    {% endfor %}
                </select>
            </label>
            {% endif %}

            {% if variantSecondName %}
            <label>
                <span>{{ variantSecondName }}</span>
                <select class="second" required>
                    <option value="" hidden>Selecione</option>
                    {% for value in listVariantsSecond %}
                        <option value="{{ value }}" data-price="{{ price }}">{{ value }}</option>
                    {% endfor %}
                </select>
            </label>
            {% endif %}

            <div class="flex add-cart">
                <input required type="number" value="1" class="hidden">
                <button class="action">Adicionar ao carrinho</button>
            </div>

        </form>

    </div>
{% endif %} 
```

{% endtab %}

{% tab title="Javascript" %}

```javascript
var cart = {
    customerId: null,
    loadCustomerId: function(){
        if(!cart.customerId){
            const customerInfo = dataLayer.find(element => ('customerId' in element));
            cart.customerId = customerInfo ? customerInfo.customerId : null;   
            console.log('cart.customerId',cart.customerId); 
        }        
    },
    session: function () {
        return jQuery("html").attr("data-session");
    },
    filterVariant: function(variants, selects){
        var i = 0;      
        var select = selects.eq(0).val();
  
        if(!!select){
            var select2 = selects.eq(1).val();
            while(i < variants.length){
                if(variants[i].option == select && variants[i].option2 == select2){                    
                    return variants[i];
                }
                i++;
            }
        }
        return 500;
    },
    stockAlert: function(e){
        var variant = cart.filterVariant(jQuery(e).data('variants'), jQuery(e).find('select'));
        var quant = Number(e.find('input[type="number"]').val());
  
        e.find('input[type="number"]').attr('max', variant.stock).attr('data-variant', variant.id);
  
        var numberFormat = new Intl.NumberFormat('pt-br', { style: 'currency', currency: 'BRL' });
        var price = numberFormat.format(variant.price.price);
        var payment = variant.price.payment;
  
        e.closest('.product').find('.product-price').html('<div class="price-off new-price">'+ price +'</div><div class="product-payment">'+ payment +'</div>');
  
        if(Number(variant.stock) >= quant) {
            jQuery(e).removeClass('dont-stock');
        } else{
            jQuery(e).addClass('dont-stock');
        }
        
    },
    initAdd: function () {

        jQuery('body').on('change', '.add-cart input', function(){
            var total = Number(jQuery(this).val());
            jQuery(this).val(total > 0 ? total : 1);
        });

        jQuery('body').on('change', '.list-variants select', function() {
            
            if(jQuery(this).hasClass('first')){
                if(jQuery(this).parents('.list-variants').find('.second').val() || !jQuery(this).parents('.list-variants').find('.second').length){
                    cart.stockAlert(jQuery(this).parents('.list-variants'));
                }
            } else{
                if(jQuery(this).parents('.list-variants').find('.first').val()){            
                    cart.stockAlert(jQuery(this).parents('.list-variants'));
                }
            }
            
        });

        jQuery('body').on('submit', '.list-variants', function(e){
            e.preventDefault();

            if(jQuery(this).hasClass('dont-stock')) return false;            
            var id = jQuery(this).data('id');
            var quant = jQuery(this).find('input').val();
            var href = jQuery(this).parents('.product').find('> a').attr('href');
            var variant = jQuery(this).data('variants').length ? jQuery(this).find('input').attr('data-variant') : 0;
            var validaApi = jQuery(this).data('api-cart');

            cart.addToCart(id, quant, variant, href, validaApi);
        });
    },
    addToCart: function(productId, quantity, variant, href){                    

        cart.loadCustomerId();

        const data = {
            Cart: {
                session_id : cart.session(),
                product_id : productId,
                variant_id : variant ? variant : 0,
                quantity   : quantity
            }
        };

        if(cart.customerId){
            data.Cart.customer_id = cart.customerId;
        }

        jQuery.ajax({
            method: 'post',
            url: '/web_api/cart/',
            dataType: 'json',
            data: data,
            success: function(response) {
                // exibe o carrinho lateral ou faz a ação desejada pelo parceiro
                // Exemplo: cart.showCart();
            },
            error: function( ){
                window.location.href = href;
            }    
        });

    }
}    

cart.initAdd(); 
```

{% endtab %}
{% endtabs %}

### Como usar <a href="#como-usar" id="como-usar"></a>

Copie o código ***HTML*** e crie um arquivo separado, exemplo:\
&#x20;`elements/snippets/add-cart.html`

Faça a chamada desse arquivo onde desejar:

```twig
{% element 'snippets/add-cart' {"product": product} %} 
```

Insira o bloco de código ***Javascript*** em seu arquivo ***JS.***
