Nuevo diseño atributos - Bsale-IO/template-docs GitHub Wiki
Para dar nuevo diseño a la selección de atributos tanto en la vista de los productos como en los filtros de las colecciones. Se debe reemplazar el codigo actual por los presentados a continuación.
El dato json que llega al componente ahora se contiene dos nuevos atributos isColor y attrDetails. El primero indicando si el atributo es de tipo color (1 si, 0 no), y el segundo los colores del atributo (nombre y codigo hexadecimal).
{
color: {
name: "color",
code: "attr_color",
values: ["azul","rojo","verde"],
**isColor**: 1,
**attrDetails**: [
{ "name": "azul", "code": "#2661DE" },
{ "name": "rojo", "code": "#DE2C26" },
{ "name": "verde", "code": "#29DE26" }
]
},
talla: {
name: "Talla",
code: "attr_talla",
values: ["S","M","L"],
isColor: 0,
attrDetails: []
}
}
El dato json que llega al componente se ve modificado en attributes donde se agregan los atributos isColor y colors
attributes: [
{
name: "Color",
values: ["azul","rojo"],
isColor: 1,
required: 1
colors: [
{ "name": "azul", "code": "#2661DE" },
{ "name": "rojo", "code": "#DE2C26" },
{ "name": "verde", "code": "#29DE26" }
]
}, {
name: "Marca",
values: ["L", "M"],
isColor: 0,
required: 1,
colors: []
}
]
Crear este archivo dentro del menu archivos y copia el siguiente código
/*************************************
Pantalla de producto SELECTORES
**************************************/
/* variables de personalizacion
copia estas variables en variables.css
--disabled-color: silver;
--selected-color: var(--primary-color);
--selected-contrast: var(--primary-contrast);
--product-select-btn-padding: 0.75rem 1.25rem;
--product-select-btn-border: 2px silver solid;
--product-select-btn-bg: transparent;
--product-select-btn-border-selected: 2px solid var(--selected-color);
--product-select-btn-border-disabled: 2px dashed var(--disabled-color);
--select-attr-text: "selecciona una opción";
--disabled-attr-text: "No Disponible";
*/
:root{
--check-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e");
}
/*dropdown*/
.attr-dropdown{
border:1px solid silver;
border-radius:var(--default-border-radius);
margin-bottom:1rem;
}
.attr-dropdown .dropdown-toggle{
width:100%;
text-align:left;
display:flex;
align-items:center;
}
.attr-dropdown .dropdown-toggle::after{
display: inline-block;
margin-left: 0.255em;
vertical-align: 0.255em;
content: "";
border-top: 0.3em solid;
border-right: 0.3em solid transparent;
border-bottom: 0;
border-left: 0.3em solid transparent;
}
.attr-dropdown .bs-product__label__attr{
margin:0;
width:100%
}
.attr-dropdown .dropdown-menu{
max-height: 280px;
overflow-y: auto;
}
.attr-dropdown .dropdown-item{
display:flex;
align-items:center;
}
.attr-dropdown .dropdown-item.attr-none-stock,
.attr-dropdown .dropdown-item.attr-disabled{
color: silver;
}
.attr-dropdown .dropdown-item.attr-none-stock::after,
.attr-dropdown .dropdown-item.attr-disabled::after{
content: var(--disabled-attr-text,"No Disponible");
display:inline-block;
padding:4px;
border-radius:var(--default-border-radius);
background:var(--disabled-color, silver);
color:white;
font-size:80%;
margin-left:auto;
}
.attr-dropdown .attr-color-ball{
margin-right:.5rem;
}
/* buttons */
.bs-product__label__attr{
display:block;
}
.bs-product__label__attr::after{
content: attr(data-info);
font-weight: var(--font-bold);
text-transform:capitalize;
}
.bs-product__label__attr[data-info=""]::after{
content: var(--select-attr-text,"");
font-weight:inherit;
text-transform:inherit;
opacity:.6;
}
.bs-product__label__attr.is-invalid{
color: var(--danger-color);
font-weight: var(--font-bold);
}
.btn-attr{
border:none;
position:relative;
display:flex;
justify-content:center;
padding: var(--product-select-btn-padding,0.75rem 1.25rem);
color:inherit;
border-radius: var(--default-border-radius);
border: var(--product-select-btn-border, 2px solid silver);
background: var(--product-select-btn-bg, transparent);
}
button.btn-attr.attr-selected,
button.btn-attr.attr-selected:focus{
border-color: var(--selected-color ,var(--primary-color)) !important;
}
.btn-attr.attr-selected::after{
content:"";
width:1rem;
height:1rem;
display:block;
position:absolute;
bottom:-2px;
right:-2px;
background-image: var(--check-icon);
background-repeat: no-repeat;
background-position:center center;
background-color:var(--selected-color ,var(--primary-color, black));
border-radius:var(--default-border-radius);
border: 2px solid white;
}
.btn-attr:not(.btn-color).attr-selected::after{
border-color:var(--selected-color ,var(--primary-color, black));
}
.btn-color{
padding:2px;
border-radius:3rem;
}
.attr-color-ball{
width:var(--product-attr-color-size, 3rem);
height:var(--product-attr-color-size, 3rem);
}
.attr-color-ball::after{
width:var(--product-attr-color-size, 3rem);
height:var(--product-attr-color-size, 3rem);
content:"";
background: var(--color-attr);
box-shadow: 0px 0px 0px 2px rgba(0,0,0,0.5) inset;
border-radius:3rem;
display:flex;
align-items:center;
justify-content:center;
}
.dropdown-item .attr-color-ball{
position:relative;
}
.dropdown-item .attr-color-ball,
.dropdown-item .attr-color-ball::after{
width:2rem;
height:2rem;
}
.attr-dropdown .dropdown-item.attr-selected.attr-selected{
background:var(--selected-color ,var(--primary-color, silver));
color:var(--selected-contrast ,var(--primary-contrast, black));
}
.dropdown-item.attr-selected .attr-color-ball::before{
content:"";
width:1rem;
height:1rem;
display:block;
position:absolute;
bottom:-2px;
right:-2px;
z-index:1000;
background-image: var(--check-icon);
background-repeat: no-repeat;
background-position:center center;
background-color:var(--selected-color ,var(--primary-color, black));
border-radius:var(--default-border-radius);
border: 2px solid white;
}
.btn-color.attr-none-stock::before,
.btn-color.attr-disabled::before{
content:"";
border-top: solid var(--disabled-color, silver); 2px;
display: block;
width:100%;
position:absolute;
transform: rotate(-45deg);
top:50%;
}
.btn-attr.attr-disabled,
.btn-attr.attr-none-stock{
border-style: dashed !important;
color:var(--disabled-color, silver);
}
.attr-disabled > .attr-color-ball::after,
.attr-none-stock > .attr-color-ball::after{
opacity:0.5;
}
/***********
tooltip
************/
.attr-color-ball{
position:relative;
display:flex;
justify-content:center;
}
.btn-color:hover .attr-color-ball::before,
.attr-disabled:not(.btn-color):hover::before,
.attr-none-stock:not(.btn-color):hover::before{
position:absolute;
top:100%;
font-size:80%;
background:black;
color:white;
z-index:1000;
white-space: pre;
padding:4px;
border-radius:var(--default-border-radius);
}
.btn-color:hover .attr-color-ball::before{
content:attr(tooltip);
}
.attr-disabled:not(.btn-color):not(.dropdown-item):hover::before,
.attr-none-stock:not(.btn-color):not(.dropdown-item):hover::before{
content:var(--disabled-attr-text,"No Disponible");;
}
.btn-color.attr-none-stock:hover .attr-color-ball::before,
.btn-color.attr-disabled:hover .attr-color-ball::before{
content:attr(tooltip) "\a" var(--disabled-attr-text,"No Disponible");;
}
.bs-error-stock{
display:inline-block;
}
/* selector de variante radio button */
.bs-variant-select{
display:inline-block;
}
.bs-variant-select .bs-variant-select__input{
display:none;
}
.bs-variant-select__label{
padding: var(--product-select-btn-padding,0.75rem 1.25rem);
border: var(--product-select-btn-border, 2px solid silver);
border-radius: var(--default-border-radius);
position:relative;
background: var(--product-select-btn-bg, transparent);
}
.bs-variant-select .bs-variant-select__input.disabled +.bs-variant-select__label{
color: var(--disabled-color, silver);
border: var(--product-select-btn-border-disabled,2px dashed var(--disabled-color, silver)) !important;
}
.bs-variant-select .bs-variant-select__input:checked +.bs-variant-select__label,
.bs-variant-select .bs-variant-select__input.disabled:checked +.bs-variant-select__label{
border-color:var(--selected-color ,var(--primary-color, black)) !important;
}
.bs-variant-select .bs-variant-select__input:checked +.bs-variant-select__label::after{
content:"";
width:1rem;
height:1rem;
display:block;
position:absolute;
bottom:-2px;
right:-2px;
background-image: var(--check-icon);
background-repeat: no-repeat;
background-position:center center;
background-color:var(--selected-color ,var(--primary-color, black));
border-radius:var(--default-border-radius);
}
/*************************************
Pantalla de coleccion: FILTROS
**************************************/
.bs-filter-color-input{
display:none;
}
.bs-filter-color-label{
max-width:300px;
display:flex;
position:relative;
align-items:center;
margin:0;
}
.bs-filter-color-label::before{
content:"";
background: var(--attr-code);/*lo define el componente*/
display:block;
width:var(--filter-attr-color-size, 2rem);
height:var(--filter-attr-color-size, 2rem);
border-radius:var(--filter-attr-color-size, 2rem);
position:relative;
box-shadow: 0px 0px 0px 2px rgba(0,0,0,0.5) inset;
margin-right:.5rem;
}
.bs-filter-color-input:checked+.bs-filter-color-label::after{
content:"";
width:1rem;
height:1rem;
display:block;
position:absolute;
bottom:0;
left:1rem;
background-image: var(--check-icon);
background-repeat: no-repeat;
background-position:center center;
background-color:var(--selected-color ,var(--primary-color, black));
outline:2px solid white;
border-radius:4px;
}
Copia este codigo dentro de componente style css
<!-- style attributes --><link rel="stylesheet" media="all" href="{{ 'style-attributes.css' | asset_url }}">
Copia y pega el siguiente codigo en el componente
{% assign mostrar_selector_atributos = true %} <!-- true = dibuja atributos, false = oculta atributos -->
{% assign mostrar_selector_atributos_desde = 1 %} <!-- para que se muestren siempre atributos dejar en 1, sino dejar en 2 -->
{% assign Button_selector_variante = true %}
{% assign Button_selector_atributos = true %}
{% assign Button_selector_colores = true %}
{% comment %} NO MODIFICAR ESTA VARIABLE {% endcomment %}
{% assign atributosRequeridos = 0 %}
{% for sizeAttr in product.attributes %}
{% if sizeAttr[1].required == 1 %}
{% comment %} si el atributo es requerido se suma {% endcomment %}
{% assign atributosRequeridos = atributosRequeridos | plus : 1 %}
{% endif %}
{% endfor %}
<div class="form mt-2" id="bs-product-form">
{% comment %} si tiene al menos un atributo requerido y tiene definido mostrar atributos {% endcomment %}
{%if atributosRequeridos >= mostrar_selector_atributos_desde and mostrar_selector_atributos == true %}
{% for pAttr in product.attributes%}
{% if pAttr[1].required > 0 %}
{% if pAttr[1].isColor == 1 %}
{% comment %} ES COLOR {% endcomment %}
{% if Button_selector_colores == false %}
<div class="dropdown attr-dropdown">
<button class="btn dropdown-toggle" data-toggle="dropdown">
<label class="bs-product__label__attr"
data-bs="{{pAttr[0]}}" data-info=""
class-labelError="is-invalid" >
{{pAttr[0] | capitalize}}:
</label>
</button>
<div class="dropdown-menu">
{% for val in pAttr[1].colors %}
<button
class="dropdown-item"
data-bs="product.attributes"
class-selected="attr-selected"
class-disable="attr-disabled"
data-info="{{pAttr[0]}}"
value='{{val.name}}'
>
<span class="attr-color-ball" style="--color-attr: {{val.code}};"></span> {{val.name | capitalize}}
</button>
{% endfor %}
</div>
</div>
{% else %}
<div class="form-group row mx-0 " >
<label class="bs-product__label__attr col-12 px-1 mb-1" data-bs="{{pAttr[0]}}" data-info="" class-labelError="is-invalid">
{{pAttr[0] | capitalize}}:
</label>
{% for val in pAttr[1].colors %}
<div class="col-auto px-1 pb-1 ">
<button
class="btn-attr btn-color"
data-bs="product.attributes"
class-selected="attr-selected"
class-disable="attr-disabled"
data-info="{{pAttr[0]}}"
value='{{val.name}}'
>
<span class="attr-color-ball" tooltip="{{val.name | capitalize }}" style="--color-attr: {{val.code}};"></span>
</button>
</div>
{% endfor %}
</div>
{% endif %}
{% else %}
{% comment %} NO ES COLOR {% endcomment %}
{% if Button_selector_atributos == false %}
<div class="dropdown attr-dropdown">
<button class="btn dropdown-toggle" data-toggle="dropdown">
<label class="bs-product__label__attr "
data-bs="{{pAttr[0]}}" data-info=""
class-labelError="is-invalid" >
{{pAttr[0] | capitalize}}:
</label>
</button>
<div class="dropdown-menu">
{% for val in pAttr[1].values %}
<button
class="dropdown-item"
data-bs="product.attributes"
class-selected="attr-selected"
class-disable="attr-disabled"
data-info="{{pAttr[0]}}"
value='{{val}}'
>
{{val}}
</button>
{% endfor %}
</div>
</div>
{% else %}
<div class="form-group row mx-0 " >
<label class="bs-product__label__attr col-12 px-1 mb-1" data-bs="{{pAttr[0]}}" data-info="" class-labelError="is-invalid">
{{pAttr[0] | capitalize}}:
</label>
{% for val in pAttr[1].values %}
<div class="col-auto px-1 pb-1 ">
<button
class="btn-attr"
data-bs="product.attributes"
class-selected="attr-selected"
class-disable="attr-disabled"
data-info="{{pAttr[0]}}"
value='{{val}}'
>
{{val}}
</button>
</div>
{% endfor %}
</div>
{%endif%}
{% endif %}
{% endif %}
{% endfor %}
{% elsif variant.size > 1 %}
{%comment%} ES VARIANTE {%endcomment%}
{% if Button_selector_variante == true %}
{%comment%} ES BOTON {%endcomment%}
{% for var in variant %}
<div class="bs-variant-select col-auto px-1 pb-1">
<input
data-bs="product.variant"
data-info="{{var.id}}"
type="radio"
value="{{ forloop.index }}"
id="var{{forloop.index}}"
name="variantes"
{% if var.id == product.variantId %} checked {% endif %}
class="bs-variant-select__input {% if products.classification != 1 %}{% unless var.unlimitedStock > 0 or var.allowNegativeStock > 0 %}{% assign st = var.id | get_stock_variant %}{% if st <= 0 %}disabled{% endif %}{% endunless %}{% endif %}"
>
<label class="bs-variant-select__label" for="var{{forloop.index}}">
{% if var.title.size > 0 %}{{var.title}}{% else %}{{var.sku}}{%endif%}
</label>
</div>
{% endfor %}
{% else %}
{%comment%} ES SELECT {%endcomment%}
<div class="form-group">
<label class="bs-product__label">Opciones</label>
<select data-bs="product.variant" class="form-control">
{% for var in variant %}
<option
{% assign outStock = false %}
{% if products.classification != 1 %}{% unless var.unlimitedStock > 0 or var.allowNegativeStock > 0 %}{% assign st = var.id | get_stock_variant %}{% if st <= 0 %}class="disabled"{% assign outStock = true %}{% endif %}{% endunless %}{% endif %}
data-info='{{var.id}}'
value="{{ forloop.index }}"
{% if var.id == product.variantId %} selected {% endif %}>
{% if var.title.size > 0 %}{{var.title}}{% else %}{{var.sku}}{%endif%}
{% if outStock %} × Sin Stock {%endif %}
</option>
{% endfor %}
</select>
</div>
{% endif %}
{% endif %}
</div>
{% assign deleteAttibutes = "atributo 1,atributo oculto 2" | split: ',' %}
{% comment %} VERSION DICIEMBRE 2022 {% endcomment %}
<aside class="bs-collection-filter col-lg-3">
<form id="bs-collection-filter-form">
<section class="row">
<div class="col-12 h3 d-none d-lg-block">
Filtros
</div>
<div class="col-12 d-flex d-lg-block align-items-center justify-content-between mb-1">
<a class="btn btn-secondary order-lg-2"
href="{{ paginate.link }}">
<i class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">Limpiar</span>
</a>
<a class="d-lg-none btn btn-link collapsed" href="#filter-toggle" data-toggle="collapse" role="button" title="Filtros">
Filtros
<i class="fas fa-caret-down"></i>
</a>
<button class="btn btn-secondary" type="submit">
<i class="d-none d-lg-inline fas fa-filter"></i>
Filtrar
</button>
</div>
</section>
<section class="collapse d-lg-block" id="filter-toggle" >
{% if collection.limitPrice.minPrice != collection.limitPrice.maxPrice %}
<div id="bs-collection-filter-price" class=" my-1">
<ul class="list-group">
<li class="list-group-item">
<div
data-bs="filter.range"
data-min="{{ collection.limitPrice.minPrice }}"
data-max="{{ collection.limitPrice.maxPrice }}"
>
</div>
</li>
</ul>
</div>
{% endif%}
{% for attr in collection.attributes %}
{%assign flagAttr = false %}
{% for del in deleteAttibutes %}
{% if attr[1].name == del %}
{%assign flagAttr = true %}
{{break}}
{% endif %}
{% endfor %}
<!-- elimina marca si esta en la url /brand/ -->
{% if attr[0] == "Brands" and current_url contains "/brand/" %}
{% assign flagAttr == true %}
{% endif %}
<!---------------------------->
{% if flagAttr == false %}
{% if attr[1].values.size > 0 %}
<div class="panel-heading my-1">
<a
class="btn d-flex justify-content-between align-items-center bs-filter-btn collapsed"
data-toggle="collapse"
href="#{{ attr[1].code }}{{ attr[0] }}">
{{ attr[1].name }}<i class="fas fa-angle-down"></i>
</a>
</div>
<div id="{{ attr[1].code }}{{ attr[0] }}" class="panel-collapse collapse my-1 {% if attr[1].isColor == 1 %} panel-color{%endif%}">
{% if attr[1].isColor == 1 %}
<ul class="list-group">
{% for color in attr[1].attrDetails %}
<li class="list-group-item py-2">
<input id="{{ attr[1].code | url_encode}}-{{ forloop.index }}"
class="bs-collection-filter-input bs-filter-color-input"
type="checkbox"
value="{{ color.name | url_encode }}"
title="{{ color.name | capitalize }}"
data-filter="{{ attr[1].code | url_encode }}[]">
<label class="bs-filter-color-label" style="--attr-code:{{color.code}}" for="{{ attr[1].code | url_encode}}-{{ forloop.index }}" data-tooltip="{{ color.name | capitalize }}">
{{ color.name | capitalize }} {{color.id_color}}
</label>
{% endfor %}
</li>
</ul>
{% else %}
<ul class="list-group">
{% assign data = attr[1].code %}
{% for item in attr[1].values %}
{% if item.size > 0 %}
<li class="list-group-item py-2">
<div class="custom-control custom-checkbox">
<input
id="{{ attr[1].code | url_encode}}-{{ forloop.index }}-{{ attr[0] }}"
class="custom-control-input bs-collection-filter-input"
type="checkbox"
value="{{ item | url_encode }}"
data-filter="{{ attr[1].code | url_encode }}[]">
<label class="custom-control-label" for="{{ attr[1].code | url_encode }}-{{ forloop.index }}-{{ attr[0] }}">
{{ item }}
</label>
</div>
</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
</div>
{% endif %}
{% endif %}
{%assign flagAttr = false %}
{%endfor%}
</section>
</form>
</aside>