Basic Setup
For the purposes of this tutorial, I’m using an extension, but there’s no reason why this functionality couldn’t be a standard SuiteCommerce Advanced customization. It does, however, rely on the extensibility API, so you’ll need to be running Aconcagua or newer.
When setting up this extension or module, make it only available to the shopping application (it’s not required in the checkout or customer account applications).
The structure is simple and looks like this:
PLPColorImages
- Modules
- Configuration
- PLPColorImages.json
- JavaScript
- PLPColorImages.js
- Configuration
- manifest.json
And with that, we can start the coding process by creating the entrypoint file.
Create the Entrypoint
In JavaScript, create PLPColorImages.js. In it, put:
define('PLPColorImages'
, [
]
, function
(
)
{
'use strict';
return {
mountToApp: function mountToApp (container)
{
var PLP = container.getComponent('PLP')
, Environment = container.getComponent('Environment')
, Layout = container.getComponent('Layout')
, customColorId = Environment.getConfig('plpColorImages.customColorId') ? Environment.getConfig('plpColorImages.customColorId') : '';
if (customColorId)
{
Layout.addToViewContextDefinition('Facets.ItemCell.View', 'thumbnail', 'string', function thumbnail (context)
{
var model = _.find(PLP.getItemsInfo(), function (item)
{
return item.internalid == context.itemId
})
, thumbnail = context.thumbnail
, images = model.itemimages_detail ? model.itemimages_detail : ''
, filters = _.find(PLP.getFilters(), function (filter)
{
return filter.id == customColorId
});
// Note the `media` property/object is due to how my test account handles image naming -- this may be different on your site
if (images && images.media && filters && filters.value[0] && images.media[filters.value[0]])
{
_.each(filters.value, function (filter)
{
if (images.media[filter] && images.media[filter].urls)
{
thumbnail = images.media[filter].urls[0]
}
});
}
return thumbnail
});
Layout.addToViewContextDefinition('Facets.ItemCell.View', 'url', 'string', function url (context)
{
var model = _.find(PLP.getItemsInfo(), function (item)
{
return item.internalid == context.itemId
})
, filters = _.find(PLP.getFilters(), function (filter)
{
return filter.id == customColorId
})
, existingUrl = context.url
, fields = model.itemoptions_detail ? model.itemoptions_detail.fields : ''
, fieldColors = fields ? _.find(fields, function (option)
{
return option.sourcefrom == customColorId
}) : ''
, fieldColorValues = fieldColors ? fieldColors.values : '';
if (fieldColorValues && filters && filters.value[0])
{
var url = '';
_.each(filters.value, function (filter)
{
if (!url)
{
url = _.find(fieldColorValues, function (value)
{
return value.label == filter
})
}
});
/* If you want to match the behavior of the above images, then you could implement something like this (this way the URL colors match the color of the thumbnails)
_.each(fieldColorValues, function (value)
{
_.each(filters.value, function (filter)
{
if (value.label == filter)
{
url = value
}
})
});
*/
if (url) {return url.url}
}
else {return existingUrl}
});
}
}
}
});
You’ll see that after defining our variables for the components, we call on plpColorImages.customColorId using getConfig(). The method takes a path to the property you want, or you can pass nothing to get the entire configuration object. We’re going to use this field to find the active filters on our site, but you’ll notice that we’re also using it as a check before running the code to make sure it exists. Note that this is going to be different from the custom column field PDPs use when you add an item to cart. On my site, this is custitem31. We need to specify this because we’re going to look at the active filters and see if any of them are color related.
Layout.addToViewContextDefinition('Facets.ItemCell.View', 'thumbnail', 'string', function thumbnail (context)
{
...
});
We’re passing it four things:
- The view we want to tinker with
- The property we want to add (or overwrite if it exists already)
- The type of value our function (callback) is going to return
- The function or callback itself — note that it is called with the existing context object as an argument (super handy)
Whatever the function returns will be set as the value for the specified property. In our example, we know that the context object already has a thumbnail property, so by using this method we know that we’re going to overwrite it with whatever we return in our function.