Neste tutorial, veremos como adicionar as sugestões ao campo de pesquisa. Como funciona? Quando um usuário está digitando um texto para pesquisar, são sugeridos até 6 produtos de acordo com as letras ou palavras escritas.
HTML
1. A primeira coisa que vamos fazer é criar a pasta header dentro da pasta snipplets e em seguida, adicionar os seguintes snipplets com seus respectivos conteúdos.
É importante manter as classes "js -..." para garantir seu funcionamento quando adicionamos JavaScript.
header-search.tpl
<form class="js-search-container js-search-form" action="{{ store.search_url }}" method="get"> <div class="form-group m-0"> <input class="js-search-input form-control search-input" autocomplete="off" type="search" name="q" placeholder="{{ 'Buscar' | translate }}"/> <button type="submit" class="btn search-input-submit" value=""> {% include "snipplets/svg/search.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %} </button> </div> </form> <div class="js-search-suggest search-suggest"> {# AJAX container for search suggestions #} </div>
header-search-results.tpl
<ul class="search-suggest-list"> {% set search_suggestions = products | take(6) %} {% for product in search_suggestions %} <li class="search-suggest-item container-fluid"> <a href="{{ product.url }}" class="search-suggest-link row justify-content-md-center"> <div class="search-suggest-image-container col-xs-auto"> {{ product.featured_image | product_image_url("tiny") | img_tag(product.featured_image.alt, {class: 'search-suggest-image'}) }} </div> <div class="search-suggest-text col"> <p class="search-suggest-name"> {{ product.name | highlight(query) }} </p> {% if product.display_price %} <p> {{ product.price | money }} {% set product_can_show_installments = product.show_installments and product.display_price and product.get_max_installments.installment > 1 %} {% if product_can_show_installments %} {% set max_installments_without_interests = product.get_max_installments(false) %} {% if store.country == 'AR' %} {% set max_installments_with_interests = product.get_max_installments %} {% if max_installments_with_interests %} <span>| {{ "Hasta <strong class='installment-amount'>{1}</strong> cuotas" | t(max_installments_with_interests.installment, max_installments_with_interests.installment_data.installment_value_cents | money) }}</span> {% endif %} {% else %} {% if max_installments_without_interests and max_installments_without_interests.installment > 1 %} <span>| {{ "<strong class='installment-amount'>{1}</strong> cuotas sin interés de <strong class='installment-price'>{2}</strong>" | t(max_installments_without_interests.installment, max_installments_without_interests.installment_data.installment_value_cents | money) }}</span> {% else %} {% set max_installments_with_interests = product.get_max_installments %} {% if max_installments_with_interests %} <span>| {{ "<strong class='installment-amount'>{1}</strong> cuotas de <strong class='installment-price'>{2}</strong>" | t(max_installments_with_interests.installment, max_installments_with_interests.installment_data.installment_value_cents | money) }}</span> {% endif %} {% endif %} {% endif %} {% endif %} </p> {% endif %} </div> <div class="col-xs-auto"> {% include "snipplets/svg/chevron-right.tpl" with {svg_custom_class: "icon-inline search-suggest-icon"} %} </div> </a> </li> {% endfor %} <a href="#" class="js-search-suggest-all-link btn btn-primary d-block">{{ 'Ver todos los resultados' | translate }}</a> </ul>
O número de produtos sugeridos é definido no início do código: {% set search_suggestions = products | take(6) %}. Se você quiser mostrar outro valor, você pode fazer isso alterando o número de "take (B)"
2. Além disso, precisamos adicionar uma pasta SVG dentro da pasta snipplets. Aqui vamos adicionar os SVGs que usamos para os ícones na calculadora.
search.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M508.5 468.9L387.1 347.5c-2.3-2.3-5.3-3.5-8.5-3.5h-13.2c31.5-36.5 50.6-84 50.6-136C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c52 0 99.5-19.1 136-50.6v13.2c0 3.2 1.3 6.2 3.5 8.5l121.4 121.4c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17zM208 368c-88.4 0-160-71.6-160-160S119.6 48 208 48s160 71.6 160 160-71.6 160-160 160z"/></svg>
chevron-right.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path d="M24.707 38.101L4.908 57.899c-4.686 4.686-4.686 12.284 0 16.971L185.607 256 4.908 437.13c-4.686 4.686-4.686 12.284 0 16.971L24.707 473.9c4.686 4.686 12.284 4.686 16.971 0l209.414-209.414c4.686-4.686 4.686-12.284 0-16.971L41.678 38.101c-4.687-4.687-12.285-4.687-16.971 0z"/></svg>
3. Finalmente, precisamos chamar o snipplet onde queremos exibir o mecanismo de busca, geralmente é no header. No layout Base, colocamos dentro de um modal.
{% snipplet "header/header-search.tpl" %}
CSS
Requisito:
Ter adicionado helper classes em seu layout. Você pode seguir este pequeno tutorial para fazer isso (é só copiar e colar algumas classes, não leva mais que 1 minuto).
1. Adicione estilos dentro do arquivo static/style-critical.tpl
Se em seu design você usar um stylesheet para o CSS crítico, precisaremos do código abaixo nele, mas se não for o caso, você poderá unificar o CSS dos passos 1 e 2 em um único arquivo.
{# /* // 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; }
2. Adicione os estilos dentro do arquivo static/style-async.tpl
Se você não usar um stylesheet assíncrono no layout, adicione-o a outro código CSS.
{# /* // Search */ #} .search-input { padding-right: 30px; } .search-input[type="search"]::-webkit-search-cancel-button { -webkit-appearance:none } .search-input-submit { position: absolute; top: 5px; right: 0; font-size: 18px; background: none; border: 0; } .search-suggest-list { margin: 0 0 10px 0; padding: 0; } .search-suggest-item { padding: 10px 15px; list-style: none; } .search-suggest-text, .search-suggest-name { margin-bottom: 5px; line-height: 18px; } .search-suggest-icon { margin: 0 10px; font-size: 14px; }
3. Adicionamos o seguinte SASS de cores em style-colors.scss.tpl (ou no stylesheet do seu layout que possui as cores e fontes da loja). Lembre-se de que as variáveis de cores e fontes podem variar em relação ao seu layout:
{# This mixin adds browser prefixes to a CSS property #} @mixin prefix($property, $value, $prefixes: ()) { @each $prefix in $prefixes { #{'-' + $prefix + '-' + $property}: $value; } #{$property}: $value; } {# /* // Search */ #} .search-suggest-item { border-bottom: 1px solid rgba($main-foreground, .1); } {# /* // 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; } &-default{ padding: 10px 15px; background-color: rgba($main-foreground, .2); color: $main-foreground; fill: $main-foreground; font-weight: bold; } &-primary{ padding: 15px; background-color: $primary-color; color: $main-background; fill: $main-background; letter-spacing: 4px; font-size: 12px; &:hover{ color: $main-background; fill: $main-background; } } }
JS
⚠️ A partir do dia 30 de janeiro de 2023, a biblioteca jQuery será removida do código de nossas lojas, portanto, a função "$" não poderá ser utilizada.
1. Precisamos adicionar o JavaScript no arquivo store.js.tpl (ou onde você tem suas funções JS). O código que precisamos é o seguinte:
{# /* // Search suggestions */ #} LS.search(jQueryNuvem(".js-search-input"), function (html, count) { $search_suggests = jQueryNuvem(this).closest(".js-search-container").next(".js-search-suggest"); if (count > 0) { $search_suggests.html(html).show(); } else { $search_suggests.hide(); } if (jQueryNuvem(this).val().length == 0) { $search_suggests.hide(); } }, { snipplet: 'header/header-search-results.tpl' }); if (window.innerWidth > 768) { {# Hide search suggestions if user click outside results #} jQueryNuvem("body").on("click", function () { jQueryNuvem(".js-search-suggest").hide(); }); {# Maintain search suggestions visibility if user click on links inside #} jQueryNuvem(document).on("click", ".js-search-suggest a", function () { jQueryNuvem(".js-search-suggest").show(); }); } jQueryNuvem(".js-search-suggest").on("click", ".js-search-suggest-all-link", function (e) { e.preventDefault(); $this_closest_form = jQueryNuvem(this).closest(".js-search-suggest").prev(".js-search-form"); $this_closest_form.submit(); });
Traduções
Nesta etapa, adicionamos os textos para as traduções no arquivo config/translations.txt
es "Buscar" pt "Buscar" en "Search" es_mx "Buscar" es "Ver todos los resultados" pt "Ver todos os resultados" en "See all results" es_mx "Ver todos los resultados" es "Hasta 12 cuotas" pt "Até 12x sem juros" en "Upto 12x without interests" es_mx "Hasta 12 cuotas" es "Hasta <strong class='js-installment-amount installment-amount'>{1}</strong> cuotas" pt "Até <strong class='js-installment-amount installment-amount'>{1}</strong>x" en "Up to <strong class='js-installment-amount installment-amount'>{1}</strong> installments" es_mx "Hasta <strong class='js-installment-amount installment-amount'>{1}</strong> meses" es "<strong class='js-installment-amount installment-amount'>{1}</strong> cuotas de <strong class='js-installment-price installment-price'>{2}</strong>" pt "<strong class='js-installment-amount installment-amount'>{1}</strong>x de <strong class='js-installment-price installment-price'>{2}</strong>" en "In up to <strong class='js-installment-amount installment-amount'>{1}</strong> installments of <strong class='js-installment-price installment-price'>{2}</strong>" es_mx "<strong class='js-installment-amount installment-amount'>{1}</strong> meses de <strong class='js-installment-price installment-price'>{2}</strong>" es "<strong class='js-installment-amount installment-amount'>{1}</strong> cuotas sin interés de <strong class='js-installment-price installment-price'>{2}</strong>" pt "<strong class='js-installment-amount installment-amount'>{1}</strong>x de <strong class='js-installment-price installment-price'>{2}</strong> sem juros" en "In up to <strong class='js-installment-amount installment-amount'>{1}</strong> installments of <strong class='js-installment-price installment-price'>{2}</strong> without interest" es_mx "<strong class='js-installment-amount installment-amount'>{1}</strong> meses sin intereses de <strong class='js-installment-price installment-price'>{2}</strong>" es "En hasta <strong class='js-installment-amount installment-amount'>{1}</strong> cuotas" pt "Em até <strong class='js-installment-amount installment-amount'>{1}</strong>x" en "In up to <strong class='js-installment-amount installment-amount'>{1}</strong> installments" es_mx "En hasta <strong class='js-installment-amount installment-amount'>{1}</strong> meses"