1
votes

I am sort of new with Shopify and I´ve been playing around with it for the ast week or so without much success when trying to solve my issue.

I am currently using the Brooklyn template and the way they represent the Product Page doesn´t precisely give the best user experience. The way it´s representing the images by default is by having all the product variants images showed to the customer all the time even if he hasn´t actually picket that variant (i.e. a specific colour for the product). It also displays all the product images in a vertical way which makes navigation for the user quite frustrating if you have more than a couple of pictures per product variant.

I´ve found online a tutorial ( http://littlesnippets.ca/blogs/tutorials/15665261-grouping-images-with-variants )that addresses the part of my issue to hide the pictures of the variants that are not selected by the customer, and show them once the user click on it.(you can see an example of what I want here http://group-variant-images.myshopify.com/collections/frontpage/products/anson-chair ). This is more or less how it looks my site now (https://themes.shopify.com/themes/brooklyn/styles/brooklyn/preview).

The problem is that that tutorial is being applied to a website that is not using the exact theme/functionality that Ii do, although it´s similar. I´ve failed to apply those changes to my theme, can anybody give me a hand?

This is my product.liquid piece of code at the moment:

<!-- /templates/product.liquid -->

<div itemscope itemtype="http://schema.org/Product">

<meta itemprop="url" content="{{ shop.url }}{{ product.url }}">
<meta itemprop="image" content="{{ product.featured_image.src | img_url: 'grande' }}">

{% assign current_variant = product.selected_or_first_available_variant %}

<div class="grid product-single">
<div class="grid__item large--seven-twelfths medium--seven-twelfths text-center">
  <div class="product-single__photos">
    {% assign featured_image = current_variant.featured_image | default: product.featured_image %}

    {% comment %}
      Display current variant image, or default first
    {% endcomment %}
    <div class="product-single__photo-wrapper">
      <img class="product-single__photo" id="ProductPhotoImg" src="{{ featured_image | img_url: 'grande' }}" {% if settings.product_zoom_enable %}data-mfp-src="{{ featured_image | img_url: '1024x1024' }}"{% endif %} alt="{{ featured_image.alt | escape }}" data-image-id="{{ featured_image.id }}">
    </div>

    {% comment %}
      Display rest of product images, not repeating the featured one
    {% endcomment %}
    {% for image in product.images %}
      {% unless image contains featured_image %}
        <div class="product-single__photo-wrapper">
          <img class="product-single__photo" src="{{ image.src | img_url: 'grande' }}" {% if settings.product_zoom_enable %}data-mfp-src="{{ image.src | img_url: '1024x1024' }}"{% endif %} alt="{{ image.alt | escape }}" data-image-id="{{ image.id }}">
        </div>
      {% endunless %}
    {% endfor %}
  </div>
</div>

<div class="grid__item product-single__meta--wrapper medium--five-twelfths large--five-twelfths">
  <div class="product-single__meta">
    {% if settings.product_vendor_enable %}
      <h2 class="product-single__vendor" itemprop="brand">{{ product.vendor }}</h2>
    {% endif %}

    <h1 class="product-single__title" itemprop="name">{{ product.title }}</h1>

    <div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
      {% comment %}
        Optionally show the 'compare at' or original price of the product.
      {% endcomment %}

      {% if product.compare_at_price_max > product.price %}
        <span class="product-single__price--wrapper">
          <span class="visually-hidden">{{ 'products.general.regular_price' | t }}</span>
          <span id="ComparePrice" class="product-single__price--compare-at">
            {% if current_variant.compare_at_price > current_variant.price %}
              {{ current_variant.compare_at_price | money }}
            {% endif %}
          </span>
          <span class="visually-hidden">{{ 'products.general.sale_price' | t }}</span>
        </span>
      {% endif %}

      <span id="ProductPrice" class="product-single__price{% if product.compare_at_price > product.price %} on-sale{% endif %}" itemprop="price">
        {{ current_variant.price | money }}
      </span>

      <hr class="hr--small">

      <meta itemprop="priceCurrency" content="{{ shop.currency }}">
      <link itemprop="availability" href="http://schema.org/{% if product.available %}InStock{% else %}OutOfStock{% endif %}">

      <form action="/cart/add" method="post" enctype="multipart/form-data" class="product-single__form" id="AddToCartForm">
        <select name="id" id="ProductSelect" class="product-single__variants">
          {% for variant in product.variants %}
            {% if variant.available %}
              <option {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} data-sku="{{ variant.sku }}" value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money_with_currency }}</option>
            {% else %}
              <option disabled="disabled">
                {{ variant.title }} - {{ 'products.product.sold_out' | t }}
              </option>
            {% endif %}
          {% endfor %}
        </select>

        {% comment %}
        <div class="product-single__quantity">
          <label for="Quantity" class="product-single__quantity-label js-quantity-selector">{{ 'products.product.quantity' | t }}</label>
          <input type="number" hidden="hidden" id="Quantity" name="quantity" value="1" min="1" class="js-quantity-selector">
        </div>
        {% endcomment %}

        <div class="product-single__add-to-cart">
          <button type="submit" name="add" id="AddToCart" class="btn">
            <span id="AddToCartText">{{ 'products.product.add_to_cart' | t }}</span>
          </button>
        </div>
      </form>

    </div>

    <div class="product-single__description rte" itemprop="description">
      {{ product.description }}
    </div>

    {% if settings.social_sharing_products %}
      {% include 'social-sharing' %}
    {% endif %}
  </div>
</div>
</div>
{% if collection %}
<hr class="hr--clear">
<div class="text-center">
  <a href="{{ collection.url }}" class="return-link">&larr; {{ 'products.general.collection_return' | t: collection: collection.title }}</a>
</div>
{% endif %}

</div>

{% comment %}

*IMPORTANT:*
This theme uses a customized version of `option_selection.js` to support    using radio inputs for color and size variants. The custom version is in `variant_selection.js`.

If you wish to enable the default dropdowns for size and color
you can change the liquid asset tag below from:

{{ 'variant_selection.js' | asset_url | script_tag }}

to

{{ 'option_selection.js' | shopify_asset_url | script_tag }}

 If you use the default `option_selection.js` the labels for the dropdowns will  appear outside the dropdown.

You will also need to change `.radio-wrapper` to `.selector-wrapper` below.

{% endcomment %}
{{ 'variant_selection.js' | asset_url | script_tag }}
<script>
var selectCallback = function(variant, selector) {
timber.productPage({
  money_format: "{{ shop.money_format }}",
  variant: variant,
  selector: selector,
  translations: {
    addToCart : {{ 'products.product.add_to_cart' | t | json }},
    soldOut : {{ 'products.product.sold_out' | t | json }},
    unavailable : {{ 'products.product.unavailable' | t | json }}
  }
});
};

jQuery(function($) {
new Shopify.OptionSelectors('ProductSelect', {
  product: {{ product | json }},
  onVariantSelected: selectCallback,
  enableHistoryState: true
});

// Add label if only one product option and it isn't 'Title'. Could be 'Size'.
{% if product.options.size == 1 and product.options.first != 'Title' %}
  $('.radio-wrapper:eq(0)').prepend('<label for="ProductSelect-option-0"    class="single-option-radio__label">{{ product.options.first | escape }} </label>');
{% endif %}

// Hide drop-down selectors if we only have 1 variant and its title contains 'Default'.
{% if product.variants.size == 1 and product.variants.first.title contains 'Default' %}
  $('.selector-wrapper').hide();
{% endif %}
 });
</script>
2
It may help if you have a link to your current store and explain a little better what you're trying to achieve. Are you trying to have variant images show up and hide dynamically as the user adjusts the options, or do you want them not showing at all when the page loads?ohiodoug
Let´s say that my product page looks pretty much like these one themes.shopify.com/themes/brooklyn/styles/brooklyn/preview . Here you can see that there are several colors for the product (navy vlue, moss and nutmeg). What I want is to find a way to have several pictures for each of those colors, and once the user selects one, it will show the pictures of the product for that colour only, so the pictures of the product in the other colours would be "hidden" until the user selects another colour for the product. So as you mentioned, I want the images to show up and hide dynamically :)Pablo Ávila Flores
Let me make sure I understand the question. Each variant has multiple images? Or the product itself has multiple images and the image on the product page switches out to the variant image when the options are selected on the page?ohiodoug
Each variant has multiple images. Let´s say I have a wallet that I sell in 3 different colours. For each colour I want to show pictures of the front, back and one of the sides of the wallet for the particular colour that is selected. So in this case for the 3 colour variants I would have a total of 9 pictures (3 per colour), and I only want to show the 3 pictures corresponding to the colour that is selected at each time.Pablo Ávila Flores

2 Answers

2
votes

Shopify's admin interface only allows for one product image per variant. For this reason, to do what you are trying to do isn't as easy as you are hoping. Through the Shopify API you can add metafields to products and product variants and in these metafields you can store whatever information you want -- including links to additional images. Here is a link to the documentation for the metafields on variants: https://docs.shopify.com/api/reference/product_variant

Since the admin interface doesn't really give you the ability to modify the metafields directly, you have a couple of choices:

  1. Spend the time and energy (or money) to hook up your own management tool to the API and modify it yourself.
  2. Purchase an app from the Shopify app store that already does this for you. Here is a link to some of these apps that should guide you in the right direction: https://apps.shopify.com/search/query?utf8=%E2%9C%93&q=variant

Either way, you'll need to come up with some sort of property name convention so you know you're dealing with images because the metafields accept whatever you feel like dropping into them.

Once you are able to define the images for your product variants, then you'll need to update the logic in your liquid/javascript to accomplish the desired functionality. You can do this a few different ways, and different people will have different opinions based on SEO but my suggestion for the path of least resistance is to do something like this:

{% for v in product.variants %}
  <div id="variant_{{ v.id }}">
    {% for m in v.metafields %}
      {% if m.key contains "WHATEVER_CONVENTION_YOU_USED_TO_DENOTE_IMAGES" %}
        {% comment %}
          OUTPUT THE IMAGE TAG - PROBABLY WRAPPED IN AN ANCHOR
        {% endcomment %}
      {% endif %}
    {% endfor %}
  </div>
{% endfor %}

You'll want to incorporate some logic to show and hide the div based on the variant. Note the <div id="variant_{{ v.id }}">

The reason for this approach rather than using the api to populate js objects is that your links are already in the DOM and you can create javascript handlers when the page loads. If you wait to populate your images and links until the user selects the variant, then you'll have to deal with the event handling of dynamically created nodes.

Hope all this guides you in a good direction. If you have questions or need help feel free to reach out to me via my profile.

Additional Note: Good software developers will note the O(n^2) time complexity in the code above. Shopify doesn't execute your backend code when the page loads, rather it is executed and cached when your theme is uploaded or modified. Because of this, the poor O(n^2) time complexity won't hurt your page load performance.

As a side fun fact, this is the reason Shopify cannot create Liquid tags for things like current_time or random. Their caching mechanism which keeps sites from crashing even when being presented on Shark Tank also relies on the fact that their liquid tags, filters, and blocks don't return variable results. So, they can cache the resulting HTML and serve it directly from their caching servers...thus tags like random or current_time would only ever have an opportunity to run once.

0
votes

you can try variant-image-automator paid app. this hides unnecessary images from the product page.