Select variants by clicking their images
Caution
Vintage themes aren't available in the Theme Store. Vintage themes don't have the features included in Shopify's Online Store 2.0 themes , and Shopify free vintage themes don't receive updates except security fixes.
Note
This customization is for vintage Shopify themes, and doesn't apply to Online Store 2.0 themes.
Normally, variants are selected from a drop-down menu. You might want your customers to be able to select a product variant by clicking a variant image .
Caution
This solution won't work in the themes Boundless , Express or Narrative . If you use the Brooklyn theme, then the solution will work, but you will need to set the picker type to dropdown on your product page.
Each variant image must be unique for this solution to work.
Most themes update the main image when a variant with an image is selected. The update never happens in both directions though, because having a change of the main image automatically update a variant selection might confuse shoppers into adding the wrong variant to the cart. So, proceed with caution in applying this customization to your store.
Steps:
Desktop
From your Shopify admin, go to Online Store > Themes .
Find the theme you want to edit, click the … button to open the actions menu, and then click Edit code .
Open the theme.js
or theme.js.liquid
file in your Assets folder.
At the bottom of the file, paste the following code:
const selectVariantByClickingImage = {
// Create variant images from productJson object
_createVariantImage : function ( product ) {
const variantImageObject = {};
product . variants . forEach (( variant ) => {
if (
typeof variant . featured_image !== ' undefined ' &&
variant . featured_image !== null
) {
const variantImage = variant . featured_image . src
. split ( ' ? ' )[ 0 ]
. replace ( /http ( s )? :/ , '' );
variantImageObject [ variantImage ] =
variantImageObject [ variantImage ] || {};
product . options . forEach (( option , index ) => {
const optionValue = variant . options [ index ];
const optionKey = `option- ${ index } ` ;
if (
typeof variantImageObject [ variantImage ][ optionKey ] === ' undefined '
) {
variantImageObject [ variantImage ][ optionKey ] = optionValue ;
} else {
const oldValue = variantImageObject [ variantImage ][ optionKey ];
if ( oldValue !== null && oldValue !== optionValue ) {
variantImageObject [ variantImage ][ optionKey ] = null ;
}
}
});
}
});
return variantImageObject ;
},
_updateVariant : function ( event , id , product , variantImages ) {
const arrImage = event . target . src
. split ( ' ? ' )[ 0 ]
. replace ( /http ( s )? :/ , '' )
. split ( ' . ' );
const strExtention = arrImage . pop ();
const strRemaining = arrImage . pop (). replace ( /_ [ a-zA-Z0-9@ ] +$/ , '' );
const strNewImage = ` ${ arrImage . join ( ' . ' )} . ${ strRemaining } . ${ strExtention } ` ;
if ( typeof variantImages [ strNewImage ] !== ' undefined ' ) {
product . variants . forEach (( option , index ) => {
const optionValue = variantImages [ strNewImage ][ `option- ${ index } ` ];
if ( optionValue !== null && optionValue !== undefined ) {
const selects = document . querySelectorAll ( ' # ' + id + ' [class*=single-option-selector] ' );
const options = selects [ index ]. options ;
for ( let option , n = 0 ; ( option = options [ n ]); n += 1 ) {
if ( option . value === optionValue ) {
selects [ index ]. selectedIndex = n ;
selects [ index ]. dispatchEvent ( new Event ( ' change ' ));
break ;
}
}
}
});
}
},
_selectVariant : function () {
const productJson = document . querySelectorAll ( ' [id^=ProductJson- ' );
if ( productJson . length > 0 ) {
productJson . forEach (( product ) => {
const sectionId = product . id . replace ( " ProductJson- " , " shopify-section- " );
const thumbnails = document . querySelectorAll ( ' # ' + sectionId + ' img[src*="/cdn/"] ' );
if ( thumbnails . length > 1 ) {
const productObject = JSON . parse ( product . innerHTML );
const variantImages = this . _createVariantImage ( productObject );
// need to check variants > 1
if ( productObject . variants . length > 1 ) {
thumbnails . forEach (( thumbnail ) => {
thumbnail . addEventListener ( ' click ' , ( e ) =>
this . _updateVariant ( e , sectionId , productObject , variantImages ),
);
});
}
}
});
}
},
};
if ( document . readyState !== ' loading ' ) {
selectVariantByClickingImage . _selectVariant ();
} else {
document . addEventListener (
' DOMContentLoaded ' ,
selectVariantByClickingImage . _selectVariant (),
);
}
Click Save .
iPhone
From the Shopify app , tap the … button.
In the Sales channels section, tap Online Store .
Tap Manage themes .
Find the theme you want to edit, click the … button to open the actions menu, and then click Edit code .
Open the theme.js
or theme.js.liquid
file in your Assets folder.
At the bottom of the file, paste the following code:
const selectVariantByClickingImage = {
// Create variant images from productJson object
_createVariantImage : function ( product ) {
const variantImageObject = {};
product . variants . forEach (( variant ) => {
if (
typeof variant . featured_image !== ' undefined ' &&
variant . featured_image !== null
) {
const variantImage = variant . featured_image . src
. split ( ' ? ' )[ 0 ]
. replace ( /http ( s )? :/ , '' );
variantImageObject [ variantImage ] =
variantImageObject [ variantImage ] || {};
product . options . forEach (( option , index ) => {
const optionValue = variant . options [ index ];
const optionKey = `option- ${ index } ` ;
if (
typeof variantImageObject [ variantImage ][ optionKey ] === ' undefined '
) {
variantImageObject [ variantImage ][ optionKey ] = optionValue ;
} else {
const oldValue = variantImageObject [ variantImage ][ optionKey ];
if ( oldValue !== null && oldValue !== optionValue ) {
variantImageObject [ variantImage ][ optionKey ] = null ;
}
}
});
}
});
return variantImageObject ;
},
_updateVariant : function ( event , id , product , variantImages ) {
const arrImage = event . target . src
. split ( ' ? ' )[ 0 ]
. replace ( /http ( s )? :/ , '' )
. split ( ' . ' );
const strExtention = arrImage . pop ();
const strRemaining = arrImage . pop (). replace ( /_ [ a-zA-Z0-9@ ] +$/ , '' );
const strNewImage = ` ${ arrImage . join ( ' . ' )} . ${ strRemaining } . ${ strExtention } ` ;
if ( typeof variantImages [ strNewImage ] !== ' undefined ' ) {
product . variants . forEach (( option , index ) => {
const optionValue = variantImages [ strNewImage ][ `option- ${ index } ` ];
if ( optionValue !== null && optionValue !== undefined ) {
const selects = document . querySelectorAll ( ' # ' + id + ' [class*=single-option-selector] ' );
const options = selects [ index ]. options ;
for ( let option , n = 0 ; ( option = options [ n ]); n += 1 ) {
if ( option . value === optionValue ) {
selects [ index ]. selectedIndex = n ;
selects [ index ]. dispatchEvent ( new Event ( ' change ' ));
break ;
}
}
}
});
}
},
_selectVariant : function () {
const productJson = document . querySelectorAll ( ' [id^=ProductJson- ' );
if ( productJson . length > 0 ) {
productJson . forEach (( product ) => {
const sectionId = product . id . replace ( " ProductJson- " , " shopify-section- " );
const thumbnails = document . querySelectorAll ( ' # ' + sectionId + ' img[src*="/files/"] ' );
if ( thumbnails . length > 1 ) {
const productObject = JSON . parse ( product . innerHTML );
const variantImages = this . _createVariantImage ( productObject );
// need to check variants > 1
if ( productObject . variants . length > 1 ) {
thumbnails . forEach (( thumbnail ) => {
thumbnail . addEventListener ( ' click ' , ( e ) =>
this . _updateVariant ( e , sectionId , productObject , variantImages ),
);
});
}
}
});
}
},
};
if ( document . readyState !== ' loading ' ) {
selectVariantByClickingImage . _selectVariant ();
} else {
document . addEventListener (
' DOMContentLoaded ' ,
selectVariantByClickingImage . _selectVariant (),
);
}
Click Save .
Android
From the Shopify app , tap the … button.
In the Sales channels section, tap Online Store .
Tap Manage themes .
Find the theme you want to edit, click the … button to open the actions menu, and then click Edit code .
Open the theme.js
or theme.js.liquid
file in your Assets folder.
At the bottom of the file, paste the following code:
const selectVariantByClickingImage = {
// Create variant images from productJson object
_createVariantImage : function ( product ) {
const variantImageObject = {};
product . variants . forEach (( variant ) => {
if (
typeof variant . featured_image !== ' undefined ' &&
variant . featured_image !== null
) {
const variantImage = variant . featured_image . src
. split ( ' ? ' )[ 0 ]
. replace ( /http ( s )? :/ , '' );
variantImageObject [ variantImage ] =
variantImageObject [ variantImage ] || {};
product . options . forEach (( option , index ) => {
const optionValue = variant . options [ index ];
const optionKey = `option- ${ index } ` ;
if (
typeof variantImageObject [ variantImage ][ optionKey ] === ' undefined '
) {
variantImageObject [ variantImage ][ optionKey ] = optionValue ;
} else {
const oldValue = variantImageObject [ variantImage ][ optionKey ];
if ( oldValue !== null && oldValue !== optionValue ) {
variantImageObject [ variantImage ][ optionKey ] = null ;
}
}
});
}
});
return variantImageObject ;
},
_updateVariant : function ( event , id , product , variantImages ) {
const arrImage = event . target . src
. split ( ' ? ' )[ 0 ]
. replace ( /http ( s )? :/ , '' )
. split ( ' . ' );
const strExtention = arrImage . pop ();
const strRemaining = arrImage . pop (). replace ( /_ [ a-zA-Z0-9@ ] +$/ , '' );
const strNewImage = ` ${ arrImage . join ( ' . ' )} . ${ strRemaining } . ${ strExtention } ` ;
if ( typeof variantImages [ strNewImage ] !== ' undefined ' ) {
product . variants . forEach (( option , index ) => {
const optionValue = variantImages [ strNewImage ][ `option- ${ index } ` ];
if ( optionValue !== null && optionValue !== undefined ) {
const selects = document . querySelectorAll ( ' # ' + id + ' [class*=single-option-selector] ' );
const options = selects [ index ]. options ;
for ( let option , n = 0 ; ( option = options [ n ]); n += 1 ) {
if ( option . value === optionValue ) {
selects [ index ]. selectedIndex = n ;
selects [ index ]. dispatchEvent ( new Event ( ' change ' ));
break ;
}
}
}
});
}
},
_selectVariant : function () {
const productJson = document . querySelectorAll ( ' [id^=ProductJson- ' );
if ( productJson . length > 0 ) {
productJson . forEach (( product ) => {
const sectionId = product . id . replace ( " ProductJson- " , " shopify-section- " );
const thumbnails = document . querySelectorAll ( ' # ' + sectionId + ' img[src*="/files/"] ' );
if ( thumbnails . length > 1 ) {
const productObject = JSON . parse ( product . innerHTML );
const variantImages = this . _createVariantImage ( productObject );
// need to check variants > 1
if ( productObject . variants . length > 1 ) {
thumbnails . forEach (( thumbnail ) => {
thumbnail . addEventListener ( ' click ' , ( e ) =>
this . _updateVariant ( e , sectionId , productObject , variantImages ),
);
});
}
}
});
}
},
};
if ( document . readyState !== ' loading ' ) {
selectVariantByClickingImage . _selectVariant ();
} else {
document . addEventListener (
' DOMContentLoaded ' ,
selectVariantByClickingImage . _selectVariant (),
);
}
Click Save .