Colores y talles en variantes

En el este artículo vamos a agregar nuevos botones para mostrar las variantes de colores y talles de la siguiente forma:

Esta funcionalidad soporta colores básicos como “azul, verde, rojo, etc”.  En el caso de que el producto tenga colores más personalizados como “salmón”, en lugar de mostrarse el botón con el fondo de ese color, se mostrará el texto con el nombre del color.

HTML

1. Dentro de la carpeta snipplets crear otra carpeta con el nombre product, dentro agregamos un nuevo snipplet llamado product-variants.tpl (si ya tenés este snipplet simplemente reemplazálo) con el siguiente código:

<div class="js-product-variants form-row">
    
    {# Color and size variants buttons #}
      
      {% for variation in product.variations if variation.name in ['Color', 'Cor', 'Talle', 'Tamanho', 'Size'] %}
          <div class="col-12">
            <div data-variant="{{ variation.name }}" class="js-btn-variation-container mb-2 text-center text-sm-left">
              <label for="variation_{{loop.index}}" class="form-label mb-3">{{variation.name}}: 
                <strong class="js-insta-variation-label">{{ product.default_options[variation.id] }}</strong>
              </label>
              <div class="row justify-content-center justify-content-sm-start no-gutters">
                {% for option in variation.options if option.custom_data %}
                <div class="col-auto">
                    <a data-option="{{ option.id }}" class="js-btn-variation btn btn-square mr-2 mb-3 {{ variation.name }} {% if product.default_options[variation.id] == option.id %} selected {% endif %}" style="background: {{ option.custom_data }}" data-name="{{ option.name }}">
                    </a>
                </div>
                {% endfor %}
                {% for option in variation.options if not option.custom_data %}
                <div class="col-auto">
                    <a data-option="{{ option.id }}" class="js-btn-variation btn btn-square mr-2 mb-3 {{ variation.name }} {% if product.default_options[variation.id] == option.id %} selected {% endif %}" data-name="{{ option.name }}">
                        {{ option.name }}
                    </a>
                </div>
                {% endfor %}
              </div>
            </div>
        </div>
    {% endfor %}


    {# Variants selects (for color and sizes the select is still working but hidden)  #}


    {% for variation in product.variations %}
        <div class="{% if loop.length == 3 %} col-12 col-sm-4 {% elseif loop.length == 2 %} col-6 {% else %} col col-sm-6{% endif %}" {% if variation.name in ['Color', 'Cor', 'Talle', 'Tamanho', 'Size']%}style="display: none"{% endif %}>
            {% embed "snipplets/forms/form-select.tpl" with{select_label: true, select_label_name: '' ~ variation.name ~ '', select_for: 'variation_' ~ loop.index , select_id: 'variation_' ~ loop.index, select_name: 'variation' ~ '[' ~ variation.id ~ ']', select_custom_class: 'js-variation-option js-refresh-installment-data'} %}
                {% block select_options %}
                    {% for option in variation.options %}
                        <option value="{{ option.id }}" {% if product.default_options[variation.id] == option.id %}selected="selected"{% endif %}>{{ option.name }}</option>
                    {% endfor %}
                {% endblock select_options%}
            {% endembed %}
        </div>
    {% endfor %}
</div>

2. Luego tenemos que crear una nueva carpeta con el nombre forms, ubicada en la carpeta snipplets. Dentro agregamos el snipplet con el nombre form-select.tpl,  que vamos a usar para todos los componentes “select” dentro del theme (en el theme Base ya está agregado).

{# /*============================================================================
  #Form select
==============================================================================*/
#Properties

#Group
    //select_group_custom_class for custom CSS classes
#Label 
    // select_label_name for name
    // select_label_id for ID
    // select_for for label for
    // select_label_custom_class for custom CSS classes
#Select 
    // select_id for id
    // select_name for name
    // select_custom_class for custom CSS classes 
    // input_rows for textarea rows
    // select_options to insert select options

#}

<div class="form-group {{ select_group_custom_class }}">
    {% if select_label %}
        <label {% if select_label_id%}id="{{ select_label_id }}"{% endif %} class="form-label {{ select_label_custom_class }}" {% if select_for %}for="{{ select_for }}"{% endif %}>{{ select_label_name }}</label>
    {% endif %}
    <select 
        {% if select_id %}id="{{ select_id }}"{% endif %}
        class="form-select {{ select_custom_class }} {% if select_inline %}form-control-inline{% endif %}"
        {% if select_name %}name="{{ select_name }}"{% endif %}>
        {% block select_options %}
        {% endblock select_options %}
    </select>
    <div class="form-select-icon">
        {% include "snipplets/svg/chevron-down.tpl" with {svg_custom_class: "icon-inline icon-w-14 icon-lg svg-icon-text"} %}
    </div>
</div>

3. Por último para la parte de HTML, necesitamos agregar una carpeta SVG dentro de la carpeta snipplets. Acá vamos sumar el SVG que usamos para la flecha dentro de los select de variantes con el nombre chevron-down.tpl

<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M441.9 167.3l-19.8-19.8c-4.7-4.7-12.3-4.7-17 0L224 328.2 42.9 147.5c-4.7-4.7-12.3-4.7-17 0L6.1 167.3c-4.7 4.7-4.7 12.3 0 17l209.4 209.4c4.7 4.7 12.3 4.7 17 0l209.4-209.4c4.7-4.7 4.7-12.3 0-17z"/></svg>

CSS

Requisito:

Tener agregados en tu diseño las clases helpers. Podés seguir este este pequeño tutorial para hacerlo (simplemente es copiar y pegar algunas clases, no toma más de 1 minuto).

1. Agregar los estilos dentro del archivo static/style-colors.scss.tpl 

Agregamos el siguiente SASS de colores en style-colors.scss.tpl (o la hoja de tu diseño que tenga los colores y tipografías de la tienda). Recordá que las variables de colores y tipografías pueden variar respecto a tu diseño:

@mixin prefix($property, $value, $prefixes: ()) {
  @each $prefix in $prefixes {
      #{'-' + $prefix + '-' + $property}: $value;
  }
    #{$property}: $value;
}


{# /* // Buttons */ #}


.btn{
  text-decoration: none;
  text-align: center;
  border: 0;
  cursor: pointer;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  text-transform: uppercase;
  background: none;
  @include prefix(transition, all 0.4s ease, webkit ms moz o);
  &:hover,
  &:focus{
    outline: 0;
    opacity: 0.8;
  }
  &[disabled],
  &[disabled]:hover{
    opacity: 0.5;
    cursor: not-allowed;
    outline: 0;
  }
  &-square{
    display: block;
    min-width: 25px;
    min-height: 25px;
    padding: 4px 10px;
    border: 1px solid $main-background;
    outline: 1px solid rgba($main-foreground, .2);
    &:hover{
      outline: 1px solid rgba($main-foreground, .2);
    }
    &.selected{
      outline: 2px solid rgba($primary-color, .5);
    }
  }
}


{# /* // Forms */ #}


input,
textarea {
  font-family: $body-font;
}


.form-control {
  display: block;
  padding: 10px 8px;
  width: 100%;
  border: 0;
  border-bottom: 1px solid rgba($main-foreground, .5);
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  color: $main-foreground;
  background-color: $main-background;
  &:focus{
    outline: 0;
  }
  &-inline{
    display: inline;
  }
}


.form-control::-webkit-input-placeholder { 
  color: $main-foreground;
}
.form-control:-moz-placeholder {
  color: $main-foreground;
}
.form-control::-moz-placeholder {
  color: $main-foreground;
}
.form-control:-ms-input-placeholder {
  color: $main-foreground;
}


.form-select{
  display: block;
  padding: 10px 0;
  width: 100%;
  border: 0;
  border-bottom: 1px solid rgba($main-foreground, .5);
  border-radius: 0;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  color: $main-foreground;
  background-color: $main-background;
  &-icon{
    background: $main-background;
  }
}

2. Agregar los estilos dentro del archivo static/style-critical.tpl 

Si en tu diseño usas una hoja de estilos para el CSS crítico, vamos a necesitar agregar el código debajo dentro de la misma, pero si no es el caso podés unificar el CSS de los pasos 2 y 3. en un solo archivo.

{# /* // Forms */ #}


.form-group {
  position: relative;
  width: 100%;
}
.form-group .form-select-icon{
  position: absolute;
  bottom: 12px;
  right: 0;
  pointer-events: none;
}
.form-row {
  width: auto;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  margin-right: -5px;
  margin-left: -5px;
  clear: both;
}


.form-row > .col,
.form-row > [class*=col-]{
  padding-right: 5px;
  padding-left: 5px;
}


.form-label {
  display: block;
  font-size: 10px;
  text-transform: uppercase;
}

3. Agregar los estilos dentro del archivo static/style-async.tpl 

Si en tu diseño usas una hoja de estilos para CSS asíncrono, vamos a necesitar agregar el siguiente código debajo dentro de la misma, pero si no es el caso podés unificar el CSS de los pasos 3 y 4 en un solo archivo.

{# /* // Forms */ #}


.form-group{
  .form-label{
    float: left;
    width: 100%;
    margin-bottom: 10px;
  }
  .alert{
    margin: 10px 0 0 0;
  }
}

JS

1. El JavaScript necesitamos agregarlo en el archivo store.js.tpl (o donde tengas tus funciones de JS).  Agregamos el siguiente código :

    {# /* // Color and size variations */ #}
    
    $(document).on("click", ".js-btn-variation", function (e) {
        e.preventDefault();
        $this = $(this);
        $variation_container = $this.closest(".js-btn-variation-container");
        $variation_container.find(".js-btn-variation").removeClass("selected");
        $this.addClass("selected");


        var option_id = $this.data('option');
        $selected_option = $this.closest('.js-product-variants').find('.js-variation-option option').filter(function () {
            return this.value == option_id;
        });
        $selected_option.prop('selected', true).trigger('change');


        $variation_container.find('.js-insta-variation-label').html(option_id);
    });

Traducciones

Para terminar agregamos los textos para las traducciones en el archivo config/translations.txt

es "Talle"
pt "Tamanho"
en "Size"
es_mx "Talla"

es "S"
pt "P"
en "S"
es_mx "S"

es "M"
pt "M"
en "M"
es_mx "M"

es "L"
pt "G"
en "L"
es_mx "L"

es "XL"
pt "GG"
en "XL"
es_mx "XL"

es "Color"
pt "Cor"
en "Color"
es_mx "Color"

es "Azul"
pt "Azul"
en "Blue"
es_mx "Azul"

es "Blanco"
pt "Branco"
en "White"
es_mx "Blanco"

es "Rojo"
pt "Vermelha"
en "Red"
es_mx "Rojo"

es "Material"
pt "Material"
en "Material"
es_mx "Material"

es "Algodón"
pt "Algodão"
en "Cotton"
es_mx "Algodón"

es "Denim"
pt "Denim"
en "Denim"
es_mx "Denim"

Listo, ya tenés en tu diseño la funcionalidad aplicada ¡Excelente!