javascript - Related products by variant using metafields for Shopify Liquid -


i'm trying build on caroline's solution related products metafields build related product variants. i.e when click on white color variant desk, see white variant of chair related product. (as opposed linking desk product chair product regardless of variant.) caroline's solution here: https://gist.github.com/carolineschnapp/1003334 , below code. right it's putting same product twice on page load, , nothing happens when different vairant selected. way formatting metafield value each variant putting "related-product-handle-1, variant-id-1, related-product-handle-2,variant-id-2, related-product-handle-3, variant-id-3" instead of product handles.

{% assign image_size = 'compact' %} {% assign heading = 'related products' %}  {% if product.selected_or_first_available_variant.metafields.recommendations.producthandles %}  <h3>{{ heading }}</h3> <ul class="related-products"></ul>  {% endif %}  <script>!window.jquery && document.write('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"><\/script>')</script> {{ 'api.jquery.js' | shopify_asset_url | script_tag }}  <script type="text/javascript" charset="utf-8">    $(document).ready(function(){  settimeout(function() {     var dd = $('.single-option-selector#product-select-option-0');       var vid = location.search.substring(9);       switchrelated(vid);      dd.on('change', function() {       $('ul.related-products').empty();       var vid = location.search.substring(9);       switchrelated(vid);       });      function switchrelated(vid) {       var list = $('ul.related-products');       var vidd = parseint(vid);       {% variant in product.variants %}         {% if variantid == vidd %}           {% if variant.metafields.recommendations.producthandles %}             recommendations = jquery.trim({{ variant.metafields.recommendations.producthandles | json }}).split(/[\s,;]+/);             (var i=0; < (recommendations.length); i+=2 ) {               var j = (i + 1);               if (recommendations.length && recommendations[i] && recommendations[j] !== '') {                 jquery.getjson('/products/' + recommendations[i] + '.js', function(product) {                   product.variants.foreach(function(variant) {                     if (variant.id == parseint(recommendations[j])) {                       list.append('<li><div class="image"><a href="' + product.url + '?variant=' + recommendations[j] +'"><img src="' + variant.featured_image.src + '" /></a></div><h4><a href="' + product.url + '?variant=' + recommendations[j] + '">' + product.title + '</a></h4></li>');                      }                   });                 });               }             }            {% endif %}            {% endif %}       {% endfor %}     }       }, 1); }); </script> 

answer edited: first extremely helpful once made corrections syntax errors , couple of short additions. here edited version of answer may need it:

product.liquid:

 {% variant in product.variants %}                 {% capture metafield_data %}{% endcapture %}                 {% assign related_products = variant.metafields.recommendations.producthandles | split: '|' %}                 {% related_product in related_products %}                   {% assign metafield_items = related_product | split: ',' %}                   {% assign r_p = metafield_items[0] %}                   {% assign r_v = metafield_items[1] | plus: 0 %}                    {% assign r_n = all_products[r_p].title %}                   {% related_variant in all_products[r_p].variants %}                     {% if related_variant.id == r_v %}                        {% assign r_i = related_variant.image.src | img_url: 'small' %}                     {% endif %}                   {% endfor %}                   {% capture metafield_data %}{{metafield_data}}{{ r_p }},{{ r_v }},{{ r_i }},{{ r_n }}{% unless forloop.last %}|{% endunless %}{% endcapture %}                 {% endfor %}                 <option id="{{ variant.id }}" data-metafield="{{ metafield_data }}" {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money }}- {{ related_products.size }}</option>               {% endfor %} 

and related-variants javascript snippet:

$(document).ready(function(){    settimeout(function() {     var dd = $('.single-option-selector#product-select-option-0');     if(location.search.substring(9) != ''){       var vid = location.search.substring(9);      }      else {       var vid = {{ product.selected_or_first_available_variant.id }};      }     switchrelated(vid);       $('#product-select option').each(function(index, element){        $(".single-option-selector#product-select-option-0 option:eq(" + index + ")").attr('id', element.id);       $('.single-option-selector#product-select-option-0 option:eq(' + index + ')').attr('data-metafield', $(element).attr("data-metafield"));       $('#product-select option:eq(' + index + ')').attr('id', '');       });       dd.on('change', function() {       var list = $('ul.related-products');       $(list).children().remove();        $(list).empty();       if(location.search.substring(9) != ''){         var vid = location.search.substring(9);       }       else {        var vid = {{ product.selected_or_first_available_variant.id }};       }       switchrelated(vid);       });      function switchrelated(vid) {       var list = $('ul.related-products');       $(list).children().remove();       $(list).empty();       var vidd = parseint(vid);        console.log(vidd)       var variant_matches = $('#' + vid).attr('data-metafield').split('|');        (var i=0; < variant_matches.length; i++) {           var items = variant_matches[i].split(',');             list.append('<li><div class="image"><a href="/products/'+items[0]+'/?variant='+items[1]+'"><img src="'+items[2]+'" /></a></div><h4><a href="/products/' + items[0] + '?variant=' + items[2] + '">' + items[3].replace('_','') + '</a></h4></li>');        }     }      }, 1); }); 

the thing i'm nervous fact copying on data 'product-select' dropdown on 'single-option-selector' dropdown. doing because there no template rendering single-option-selector, seems getting added through javascript. if has insight manipulating single-option-selector in liquid, please let me know. thank you!!

the fastest way implement let shopify servers structure elements pull links , image urls ajax calls. here's how it.

from example of producthandles, i'm guessing 3 items in list related particular variant id xxxxxx. structure metafield value way

rph-1,rph-v-id-1|rph-2,rph-v-id-2|rph-3,rph-v-id-3

now in product liquid find section

<select class="product-select" id="product-select" name="id" .... </select>

change inside html 1 below -

{% variant in product.variants %}     {% assign related_products = variant.metafields.recommendations.producthandles | split: '|' %}     {% related_product in related_products %}       {% assign metafield_items = related_product | split: ',' %}       {% assign r_p = metafield_items[0] %}       {% assign r_v = metafield_items[1] | plus: 0 %} {% comment %} converting string number {% endcomment %}       {% assign r_n = all_products[r_p].title | replace: ' ','_' %}       {% related_variant in all_products[r_p].variants %}         {% if related_variant.id == r_v %} {% comment %} fails if r_v string {% endcomment %}           {% assign r_i = related_variant.image.src }}         {% endif %}       {% endfor %}       {% capture metafield_data %}{{metafield_data}}{{ r_p }},{{ r_v }},{{ r_i }},{{ r_n }}{% unless forloop.last %}|{% endunless %}{% endcapture %}     {% endfor %}     <option id="{{ variant.id }}" metafield-data={{ metafield_data }}{% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money }}</option> {% endfor %} 

"metafield_data" contain related products information (product,variant,variant image).

js replace "switchrelated(vid)"

function switchrelated(vid) {     var list = $('ul.related-products');     var vidd = parseint(vid);      list.children().remove()      var variant_matches = $('#vid').attr('metafield-data').split('|')      (var i=0; < variant_matches.length; i++) {         var items = variant_matches[i].split(',')         list.append('<li><div class="image"><a href="/products/'+items[0]+'/?variant='+items[1]+'"><img src="'+items[2]+'" /></a></div><h4><a href="/products/'+items[0]+'?variant='item[2]'">'+items[3].replace('_','')+'</a></h4></li>');      } }     

in layman terms, taking product handle , variant id metafields , adding title , image them using liquid (server side function). matching them variants , assigning data variable in element using again change html elements.

p.s. code long , not aligned , may have missed code punctuations here , there. please check them. logic simple , entire weight of ajax removed , shifted normal html calls.


Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -