Announcement

Collapse
No announcement yet.

How to make swatches show up next to their respective attribute

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    How to make swatches show up next to their respective attribute

    If you have every worked with swatches and have tried to setup a product where there are multiple swatch drop downs on a single product (color, material, etc) you will know that by default Miva groups all swatches into a single "swatches" container.

    Here is how you can change it so each swatch group displays next to its corresponding drop down:

    1. Add a swatches div for each attribute
    - Go to PROD, edit the Product Attribute Template
    - Look for the code that starts the swatches drop down:

    Code:
    <mvt:elseif expr="( l.settings:attribute:type EQ 'select' ) OR ( l.settings:attribute:type EQ 'swatch-select' )">
    add this line below the line above:
    Code:
    <mvt:elseif expr="( l.settings:attribute:type EQ 'select' ) OR ( l.settings:attribute:type EQ 'swatch-select' )">
    <div id="swatch-&mvt:attribute:id;" class="swatches"></div>
    2. Modify the Generate Swatch Function:
    -Go to PROD, then Attribute Machine Tab
    - In the Head section replace what is there with this (new code in red):

    Code:
    <script>
    AttributeMachine.prototype.Generate_Swatch = function( product_code, attribute, option )
    {
    	this.swatches   =  document.getElementById('swatch-' + attribute.id);
            var swatch	= document.createElement( 'li' );
    	var span	= document.createElement( 'span' ); // to vertically center the swatch images
    	var img		= document.createElement( 'img' );
    	img.src		= option.image;
    
    
    	swatch.appendChild( span );
    	swatch.appendChild( img );
    
    
    	return swatch;
    }
    AttributeMachine.prototype.oninitializeswatches = function( attributes, possible )
    {
    	$(".swatches").empty();
    	this.Initialize_Swatches( attributes, possible );
    }
    </script>
    The code above uses jQuery to empty the swatches div when you change a selection. In order for that to work correctly you also need to have jQuery being called in:

    Add this to your Head Tag if you are currently not using jQuery:

    Code:
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    Brennan Heyde
    VP Product
    Miva, Inc.
    [email protected]
    https://www.miva.com

    #2
    Re: How to make swatches show up next to their respective attribute

    Can you use this with the inventory variants?

    Comment


      #3
      Re: How to make swatches show up next to their respective attribute

      Yeah you can use this with or without variants. It shouldn't matter either way.
      Brennan Heyde
      VP Product
      Miva, Inc.
      [email protected]
      https://www.miva.com

      Comment


        #4
        Re: How to make swatches show up next to their respective attribute

        Thank you Brennan for sharing that code. I was able to get the multiple swatches to display next to their respective attributes.

        I made thumbnails for the swatches and included a popover of a larger swatch preview when the user mouse over the thumbnail.

        Here are the additional changes to the attribute template in blue:

        Code:
        <mvt:elseif expr="( l.settings:attribute:type EQ 'select' ) OR ( l.settings:attribute:type EQ 'swatch-select' )">
        
        <div class="swatch-container">
        <mvt:foreach iterator="option" array="attribute:options">
        <div id="&mvte:option:id;_swatch_preview" class="swatch_preview" style="display: none;">
        <img src="&mvte:option:image;" alt="&mvte:option:prompt; preview swatch">
        <div class="swatch_caption">&mvt:option:prompt;</div>
        </div>
        </mvt:foreach>
        
        
        <div id="swatch-&mvt:attribute:id;" class="swatches"></div><div class="clear"></div> 
                   <div class="prompt">&mvt:attribute:prompt;</div>
                    <div class="optselect">
                        <select <mvt:if expr="l.all_settings:attribute:required">required="required"</mvt:if> name="Product_Attributes[&mvt:attribute:index;]:value">
                            <mvt:foreach iterator="option" array="attribute:options">
                                <mvt:if expr="( ( g.Product_Attributes[l.settings:attribute:index]:value EQ 0 ) AND ( l.settings:option:id EQ l.settings:attribute:default_id ) ) OR
                                                ( g.Product_Attributes[l.settings:attribute:index]:value EQ l.settings:option:code )">
                                    <option value="&mvte:option:code;" selected>&mvte:option:prompt; <mvt:if expr="l.settings:option:price GT 0">&nbsp;+&mvte:option:formatted_price;</mvt:if></option>
                                <mvt:else>
                                    <option value="&mvte:option:code;">&mvte:option:prompt; <mvt:if expr="l.settings:option:price GT 0">&nbsp;+&mvte:option:formatted_price;</mvt:if></option>
                                </mvt:if>
                            </mvt:foreach>
                        </select>
                    </div>
        </div> <!-- .swatch-container -->
        Then in the Attribute Machine Head Template I added the code in blue:

        Code:
        <script>
        AttributeMachine.prototype.Generate_Swatch = function( product_code, attribute, option )
        {
            this.swatches   =  document.getElementById('swatch-' + attribute.id);
                var swatch    = document.createElement( 'li' );
               var a = document.createAttribute('data-target');
               a.nodeValue = (option.id + '_swatch_preview');
               swatch.setAttributeNode(a);
            var span    = document.createElement( 'span' ); // to vertically center the swatch images
            var img        = document.createElement( 'img' );
            img.src        = option.image;
        
        
            swatch.appendChild( span );
            swatch.appendChild( img );
        
        
            return swatch;
        }
        AttributeMachine.prototype.oninitializeswatches = function( attributes, possible )
        {
           $(".swatches").empty();
           this.Initialize_Swatches( attributes, possible );
            $('.swatches li').hover(
                function () {
           $('#'+$(this).attr('data-target')).css({"display":"block"});
                }, 
                function () {
           $('#'+$(this).attr('data-target')).css({"display":"none"});
                }
            );
        }
        </script>
        I made my swatch thumbnails 16 x 16 px and the swatch-previews 120 x 120px. Each merchant can style to their taste but here is some CSS to start with for the popover effect:

        Code:
        .swatch-container {
            position:relative;
            width:100%;
            display:block;
            clear:both;
        }
        
        .swatch_preview {
            position: absolute;
            top: -140px;
            right: 50px;
            width: 120px;
            height: 140px;
            z-index: 1;
            border: 1px solid gray;
            text-decoration: none;
            text-align: center;
            font-size: 12px;
            font-weight: normal;
            background: #fff;
        }
        A caveat: I tested this in all four modern browsers and IE7+ without any problems. This code does not work on touch devices. A solution would be to add some javascript or touch library that will convert hover to click events. Another solution is to add code to be device responsive.

        I am using large variant images in the product-image div. The small swatch thumbnails with a large swatch-preview allows me to display the attribute swatch-selections above the fold and next to the product-image-variants. This makes it easier for a user to make a swatch-selection and see the product-variant image displayed without scrolling. It would also leave the user's mouse near the add-to-cart button.

        I have this on a test page template that may not stay active so PM me for a link if you need to see it in action.
        Last edited by alphabet; 10-17-13, 04:53 AM. Reason: fix some sloppy code
        http://www.alphabetsigns.com/

        Comment


          #5
          Re: How to make swatches show up next to their respective attribute

          Hey Everyone,

          I just wanted to make a quick addition to this post. We've seen some issues in using this code with attribute templates due to the fact that the IDs tend to work a little bit differently in cases where products are using an attribute template that contains swatch attributes.

          To fix this, You can update the code in your Product Attribute Template to account for the attribute templates when they exist.

          Replace

          Code:
          <mvt:elseif expr="( l.settings:attribute:type EQ 'select' ) OR ( l.settings:attribute:type EQ 'swatch-select' )"> 
          <div id="swatch-&mvt:attribute:id;" class="swatches"></div>


          With
          Code:
          <mvt:elseif expr="( l.settings:attribute:type EQ 'select' ) OR ( l.settings:attribute:type EQ 'swatch-select' )">
          <mvt:if expr="l.settings:attribute:attemp_id NE 0">
          <div id="swatch-&mvt:attribute:attmpat_id;" class="swatches"></div>
          <mvt:else>
          <div id="swatch-&mvt:attribute:id;" class="swatches"></div>
          </mvt:if>

          Comment


            #6
            Re: How to make swatches show up next to their respective attribute

            Thank you. That is a nice addition to the code.
            http://www.alphabetsigns.com/

            Comment


              #7
              Originally posted by Brennan View Post
              If you have every worked with swatches and have tried to setup a product where there are multiple swatch drop downs on a single product (color, material, etc) you will know that by default Miva groups all swatches into a single "swatches" container.

              Here is how you can change it so each swatch group displays next to its corresponding drop down:

              1. Add a swatches div for each attribute
              - Go to PROD, edit the Product Attribute Template
              - Look for the code that starts the swatches drop down:

              Code:
              <mvt:elseif expr="( l.settings:attribute:type EQ 'select' ) OR ( l.settings:attribute:type EQ 'swatch-select' )">
              add this line below the line above:
              Code:
              <mvt:elseif expr="( l.settings:attribute:type EQ 'select' ) OR ( l.settings:attribute:type EQ 'swatch-select' )">
              <div id="swatch-&mvt:attribute:id;" class="swatches"></div>
              2. Modify the Generate Swatch Function:
              -Go to PROD, then Attribute Machine Tab
              - In the Head section replace what is there with this (new code in red):

              Code:
              <script>
              AttributeMachine.prototype.Generate_Swatch = function( product_code, attribute, option )
              {
              this.swatches = document.getElementById('swatch-' + attribute.id);
              var swatch = document.createElement( 'li' );
              var span = document.createElement( 'span' ); // to vertically center the swatch images
              var img = document.createElement( 'img' );
              img.src = option.image;
              
              
              swatch.appendChild( span );
              swatch.appendChild( img );
              
              
              return swatch;
              }
              AttributeMachine.prototype.oninitializeswatches = function( attributes, possible )
              {
               $(".swatches").empty();
               this.Initialize_Swatches( attributes, possible );
              }
              </script>
              The code above uses jQuery to empty the swatches div when you change a selection. In order for that to work correctly you also need to have jQuery being called in:

              Add this to your Head Tag if you are currently not using jQuery:

              Code:
              <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
              I just realized that this snippet is for MM5.5 - I need to do this in MM9 Iron & Wool Ready Theme. Has anybody accomplished this?
              Leslie Kirk
              Miva Certified Developer
              Miva Merchant Specialist since 1997
              Previously of Webs Your Way
              (aka Leslie Nord leslienord)

              Email me: [email protected]
              www.lesliekirk.com

              Follow me: Twitter | Facebook | FourSquare | Pinterest | Flickr

              Comment

              Working...
              X