Choose a Color: Adding a Color Picker to Product Pages
Welcome to Episode IV of Matt's Musings. This month finds us looking at the product page...specifically the product attributes.
Let's say we have a clothing store selling t-shirts. Chances are, on the product page, we will offer two sets of attributes: color and size. Within Miva Merchant, there are several options on how the attributes can be displayed. Most commonly, for multi-variant attributes like these, we would choose drop-down list as our display type (although radio buttons are a good second choice). So after we set up our product attributes and view the product page, we see this familiar layout: 
Now that's all fine and dandy, but what do those color names really mean? Wouldn't it be great if our shoppers could see the actual colors to make their decision easier? Maybe something like this: 
Well I'm here to say, "Good news everybody...it can be done!" That's right, you can add swatches to your attributes with a minimal amount of coding changes. The beauty in this whole process is an often overlooked option that is available within a product's attribute settings.
Here is how a typical attribute's settings screen would look for a color drop-down list:
Notice the blank column of Image: this is where the magic starts. If this were a radio button set instead of a drop-down list, the image uploaded here would appear in place of the prompt on the product screen. However, by default, if you have a drop-down list and upload an image, nothing changes on the product screen. We will correct that in the next step by editing the product attribute template. For now, let's upload some images to the attribute list:
Now that we have the images uploaded and all our attributes set, let's make those code changes and get some images up on the product page. Copy the contents of the Product Attribute Template tab and paste it into your HTML editor. Your code should look similar to this:
<table>
<mvt:foreach iterator="attribute" array="attributes">
<tr>
<td class="prompt">
<input type="hidden" name="Product_Attributes[ &mvt:attribute:index; ]:code" value="&mvte:attribute:code;" />
<mvt:if expr="l.settings:attribute:template_code NE 0">
<input type="hidden" name="Product_Attributes[ &mvt:attribute:index; ]:template_code" value="&mvte:attribute:template_code;" />
</mvt:if>
<mvt:if expr="l.settings:attribute:type NE 'checkbox'">
<mvt:if expr="l.settings:attribute:image">
<img src="&mvte:attribute:image;" alt="&mvte:attribute:prompt;" />
<mvt:else>
<mvt:if expr="l.settings:attribute:required">
<span class="required">
<mvt:else>
<span>
</mvt:if>
&mvt:attribute:prompt;
</span>
</mvt:if>
<mvt:else>
</mvt:if>
</td>
<td class="field">
<mvt:if expr="l.settings:attribute:type EQ 'text'">
<input type="text" name="Product_Attributes[&mvt:attribute:index;]:value" value="&mvte:attribute:value;" class="textfield" />
<mvt:elseif expr="l.settings:attribute:type EQ 'memo'">
<textarea name="Product_Attributes[&mvt:attribute:index;]:value">&mvte:attribute:value;</textarea>
<mvt:elseif expr="l.settings:attribute:type EQ 'radio'">
<mvt:foreach iterator="option" array="attribute:options">
<div>
<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 )">
<input type="radio" name="Product_Attributes[&mvt:attribute:index;]:value" value="&mvte:option:code;" checked />
<mvt:else>
<input type="radio" name="Product_Attributes[&mvt:attribute:index;]:value" value="&mvte:option:code;" />
</mvt:if>
<mvt:if expr="l.settings:option:image">
<img src="&mvte:option:image;" alt="&mvte:option:prompt;" />
<mvt:else>
&mvte:option:prompt;
</mvt:if>
</div>
</mvt:foreach>
<mvt:elseif expr="l.settings:attribute:type EQ 'select'">
<select 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;</option>
<mvt:else>
<option value="&mvte:option:code;">&mvte:option:prompt;</option>
</mvt:if>
</mvt:foreach>
</select>
<mvt:elseif expr="l.settings:attribute:type EQ 'checkbox'">
<mvt:if expr="g.Product_Attributes[l.settings:attribute:index]:value">
<input type="checkbox" name="Product_Attributes[&mvt:attribute:index;]:value" value="Yes" checked />
<mvt:else>
<input type="checkbox" name="Product_Attributes[&mvt:attribute:index;]:value" />
</mvt:if>
<mvt:if expr="l.settings:attribute:image">
<img src="&mvte:attribute:image;" alt="&mvte:attribute:prompt;" />
<mvt:else>
<mvt:if expr="l.settings:attribute:required">
<span class="required">
<mvt:else>
<span>
</mvt:if>
&mvt:attribute:prompt;
</span>
</mvt:if>
</mvt:if>
</td>
</tr>
</mvt:foreach>
</table>
<div class="clear"></div>
Now we just need to add in an array to pull all the attribute images we uploaded to our product and place the output above the drop-down box.
<mvt:elseif expr="l.settings:attribute:type EQ 'select'">
<mvt:foreach iterator="option" array="attribute:options">
<img src="&mvte:attribute:image;" alt="&mvte:option:prompt;" title="&mvte:option:prompt;" class="swatches" />
</mvt:foreach>
<select name="Product_Attributes[&mvt:attribute:index;]:value">
In this example you'll see the images will be displayed inline by default but have a class of "swatches" applied to them to make styling an easy process. That's all there is to it. You will now have your attribute images appear above your drop-down list attributes. Now a customer will know what you mean when you're offering a shirt in a color called "pond."
Until next time, Happy Coding
P.S. Here's the full Product Attribute Template with the new code in place.
Code: Adding a Color Picker to Product Pages
<table>
<mvt:foreach iterator="attribute" array="attributes">
<tr>
<td class="prompt">
<input type="hidden" name="Product_Attributes[ &mvt:attribute:index; ]:code" value="&mvte:attribute:code;" />
<mvt:if expr="l.settings:attribute:template_code NE 0">
<input type="hidden" name="Product_Attributes[ &mvt:attribute:index; ]:template_code" value="&mvte:attribute:template_code;" />
</mvt:if>
<mvt:if expr="l.settings:attribute:type NE 'checkbox'">
<mvt:if expr="l.settings:attribute:image">
<img src="&mvte:attribute:image;" alt="&mvte:attribute:prompt;" />
<mvt:else>
<mvt:if expr="l.settings:attribute:required">
<span class="required">
<mvt:else>
<span>
</mvt:if>
&mvt:attribute:prompt;
</span>
</mvt:if>
<mvt:else>
</mvt:if>
</td>
<td class="field">
<mvt:if expr="l.settings:attribute:type EQ 'text'">
<input type="text" name="Product_Attributes[&mvt:attribute:index;]:value" value="&mvte:attribute:value;" class="textfield" />
<mvt:elseif expr="l.settings:attribute:type EQ 'memo'">
<textarea name="Product_Attributes[&mvt:attribute:index;]:value">&mvte:attribute:value;</textarea>
<mvt:elseif expr="l.settings:attribute:type EQ 'radio'">
<mvt:foreach iterator="option" array="attribute:options">
<div>
<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 )">
<input type="radio" name="Product_Attributes[&mvt:attribute:index;]:value" value="&mvte:option:code;" checked />
<mvt:else>
<input type="radio" name="Product_Attributes[&mvt:attribute:index;]:value" value="&mvte:option:code;" />
</mvt:if>
<mvt:if expr="l.settings:option:image">
<img src="&mvte:option:image;" alt="&mvte:option:prompt;" />
<mvt:else>
&mvte:option:prompt;
</mvt:if>
</div>
</mvt:foreach>
<mvt:elseif expr="l.settings:attribute:type EQ 'select'">
<mvt:foreach iterator="option" array="attribute:options">
<img src="&mvte:attribute:image;" alt="&mvte:option:prompt;" title="&mvte:option:prompt;" class="swatches" />
</mvt:foreach>
<select 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;" id="&mvte:option:code;" title="&mvte:option:prompt;" selected>&mvte:option:prompt;</option>
<mvt:else>
<option value="&mvte:option:code;" id="&mvte:option:code;" title="&mvte:option:prompt;">&mvte:option:prompt;</option>
</mvt:if>
</mvt:foreach>
</select>
<mvt:elseif expr="l.settings:attribute:type EQ 'checkbox'">
<mvt:if expr="g.Product_Attributes[l.settings:attribute:index]:value">
<input type="checkbox" name="Product_Attributes[&mvt:attribute:index;]:value" value="Yes" checked />
<mvt:else>
<input type="checkbox" name="Product_Attributes[&mvt:attribute:index;]:value" />
</mvt:if>
<mvt:if expr="l.settings:attribute:image">
<img src="&mvte:attribute:image;" alt="&mvte:attribute:prompt;" />
<mvt:else>
<mvt:if expr="l.settings:attribute:required">
<span class="required">
<mvt:else>
<span>
</mvt:if>
&mvt:attribute:prompt;
</span>
</mvt:if>
</mvt:if>
</td>
</tr>
</mvt:foreach>
</table>
<div class="clear"></div>
Join the Discussion
- December 22, 2010
Hello.
We have followed the instructions and it appears to work expect that the image url appears to be broken. The url to all images when I look at the properties seems to be http://www.hinckleyworkwear.com/mm5/ with path to the file. Can anyone help us here?
- December 27, 2010
Hi Paul,
Could you try copying the code again? I have made some small updates that might help you get the images to show up. If not, let me know and we’ll dig a little deeper.
Thanks!
- January 05, 2011
Hello, I have recopied the code and have the same problem, the images appear broken. I added the link here
- January 05, 2011
It seems my link didn’t show up. Trying again http://www.hinckleyworkwear.com/mm5/merchant.mvc?Screen=PROD&Store_Code=HWOS&Product_Code=001&Category;_Code=
- January 05, 2011
Hi Paul,
I looked at your code and it doesn’t seem to be rendering a url for the images at all. This could come from a couple things, either 1. the images are not uploaded as attribute images, or 2. the entities we are trying to output have incorrect syntax. Could you double check on the images for me? See if the paths are correct to the attribute images.
Since nothing is being rendered and you have copied this code, my first thought is that there is something wrong with the image upload.
Let me know the results.
Alex
- January 07, 2011
Yes, there doesn’t appear to be a path to the images. They WERE uploaded as attribute images in the dropdown options for that product. The image url seems short, it doesn’t give the name of the image in the path. Just http://hinckleyworkwear.com/mm5/ and no more. Just for your info, it DOES work if I upload images for the options in a radio button attribute
Any suggestions?
- January 07, 2011
I have just checked in the admin and looked at the attribute options for the dropdown. The url for the images in there are like the following:
graphics/00000001/ab-white.gif
It seems that the code isn’t picking up this info
Paul
- January 11, 2011
Just wondering if you have seen my last couple of posts Alex, I need to get this sorted, have a client waiting for his website and this is the ideal method to use for his customers to select colour options.
- January 12, 2011
Hi Paul, that’s really weird that the entities aren’t rendering. If you want to send me admin I can take a look, there isn’t much more I can tell you without seeing what’s going on in the back end unfortunately.
My email is .(JavaScript must be enabled to view this email address)
- January 12, 2011
I can’t seem to get this to work. I have tried it on one product:
http://www.dawgwear.net/page/D/PROD/LT_50_226
I would love some help!Thanks,
Jeanna
- January 12, 2011
Jeanna, I don’t see the images being called on your page at all, do you think you missed a step by chance?
- January 21, 2011
Hello Alex,
That is working ok now if we only have ONE row of colour images. However, if a product has more than one row, the images move UP and cover the price information. You can see this at:
Could you please advise?
- January 21, 2011
Also, as you can see from that product page, the drop down box appears to the right of the colour images and NOT below as in your example. I suppose this depends on how many colours we have.
- January 25, 2011
I really need some advice on this, have an impatient customer waiting for his website to be completed and this is the only thing stopping us.
- January 25, 2011
Hey Paul, the easiest way to make the select box drop down is to wrap a div tag around it. The select box starts at line 51 and ends at line 59.
By default, the select box does not display block (on it’s own line), so you can solve it by wrapping the block level div tag around it.
Hope that helps
Alex
- January 25, 2011
Thanks Alex, I will try that

- February 07, 2011
Hello Alex,
This is working great now. Ot at least it WAS, until I added a size option. I don’t want an image to display for the size dropdown, but it appears that the attribute template is looking for an image and displays broken images when I don’t upload one. Is there any way that the code could tell the page to display an image for the Color options, but NOT for the size options?
- February 07, 2011
Hello again Alex, I just tested a workaround which works. Adding a 1 pixel white image to each size option. But I am sure there is a cleaner way to do it in the code. What would you suggest?
- February 07, 2011
Hi Paul,
You could add a conditional statement around the img output like so: http://pastie.org/1537922
Make sure you replace the ‘code_for_the_color_attribute’ with the actual code for your color attribute in the admin
- February 07, 2011
Hello Alex, thanks.
Could you just tell me which line this needs to go on or at least around about where in the code as line numbers have changed with the div tags Iadded.
If I know the line before and the line after the place where I need to add the conditional statement that would be helpful and then hopefully I can leave you in peace

- February 08, 2011
It’s line 49 in the code above, I don’t know what line it is on your code. You should be able to just read the lines around #49 and find the image tag on it’s new line
- February 20, 2011
Hello Alex. Just one last thing we need to resolve, the subsequent attributes are vertically misaligned after adding the Colour Swatch. Have a look at:
You will see that the size box drops down slightly and the subseqent ‘Upload Image’ button is also higher than the text box to its left. I have looked at the attribute template and been unable to see how I could fix this, I’m sure it is something very simple once you know where to look.
- February 20, 2011
Ignore the above, I worked it out



