Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed jQuery dependencies from swatches in RWD theme #3824

Merged
merged 7 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,20 @@
?>

<script type="text/javascript">
$j(document).on('product-media-loaded', function() {
if(!(typeof $j == 'function' && $j === jQuery)) {
ConfigurableMediaImages.init('<?php echo $this->getImageType(); ?>');
<?php foreach ($this->getProductImageFallbacks() as $imageFallback): ?>
ConfigurableMediaImages.setImageFallback(<?php echo $imageFallback['product']->getId(); ?>, $j.parseJSON('<?php echo $imageFallback['image_fallback']; ?>'));
ConfigurableMediaImages.setImageFallback(<?php echo $imageFallback['product']->getId(); ?>, JSON.parse('<?php echo $imageFallback['image_fallback']; ?>'));
<?php endforeach ?>
$j(document).trigger('configurable-media-images-init', ConfigurableMediaImages);
});
document.dispatchEvent(new Event('configurable-media-images-init'));
} else {
// compatibility with rwd theme ProductMediaManager in app.js
$j(document).on('product-media-loaded', function() {
ConfigurableMediaImages.init('<?php echo $this->getImageType(); ?>');
<?php foreach ($this->getProductImageFallbacks() as $imageFallback): ?>
ConfigurableMediaImages.setImageFallback(<?php echo $imageFallback['product']->getId(); ?>, $j.parseJSON('<?php echo $imageFallback['image_fallback']; ?>'));
<?php endforeach ?>
$j(document).trigger('configurable-media-images-init', ConfigurableMediaImages);
});
empiricompany marked this conversation as resolved.
Show resolved Hide resolved
}
</script>
145 changes: 100 additions & 45 deletions skin/frontend/rwd/default/js/configurableswatches/product-media.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,25 @@ var ConfigurableMediaImages = {
}

//second, get any product which is compatible with currently selected option(s)
$j.each(fallback['option_labels'], function(key, value) {
var image = value['configurable_product'][ConfigurableMediaImages.imageType];
var products = value['products'];

if(image) { //configurable product has image in the first place
//if intersection between compatible products and this label's products, we found a match
var isCompatibleProduct = ConfigurableMediaImages.arrayIntersect(products, compatibleProducts).length > 0;
if(isCompatibleProduct) {
return image;
var optionLabels = fallback['option_labels'];
for (var key in optionLabels) {
if (optionLabels.hasOwnProperty(key)) {
var value = optionLabels[key];
var image = value['configurable_product'][ConfigurableMediaImages.imageType];
var products = value['products'];

if (image) { //configurable product has image in the first place
//if intersection between compatible products and this label's products, we found a match
var isCompatibleProduct = products.filter(function(productId) {
return compatibleProducts.includes(productId);
}).length > 0;

if (isCompatibleProduct) {
return image;
}
}
}
});
}

//third, get image off of child product which is compatible
var childSwatchImage = null;
Expand All @@ -118,74 +125,122 @@ var ConfigurableMediaImages = {
getImageObject: function(productId, imageUrl) {
var key = productId+'-'+imageUrl;
if(!ConfigurableMediaImages.imageObjects[key]) {
var image = $j('<img />');
image.attr('src', imageUrl);
var image = document.createElement('img');
image.src = imageUrl;
ConfigurableMediaImages.imageObjects[key] = image;
}
return ConfigurableMediaImages.imageObjects[key];
},

updateImage: function(el) {
var select = $j(el);
var label = select.find('option:selected').attr('data-label');
updateImage(el) {
var select = el;
var label = select.options[select.selectedIndex].getAttribute('data-label');
var productId = optionsPrice.productId; //get product ID from options price object

//find all selected labels
var selectedLabels = new Array();
var selectedLabels = [];

$j('.product-options .super-attribute-select').each(function() {
var $option = $j(this);
if($option.val() != '') {
selectedLabels.push($option.find('option:selected').attr('data-label'));
var superAttributeSelects = document.querySelectorAll('.product-options .super-attribute-select');
superAttributeSelects.forEach(function(option) {
if (option.value !== '') {
selectedLabels.push(option.options[option.selectedIndex].getAttribute('data-label'));
}
});

var swatchImageUrl = ConfigurableMediaImages.getSwatchImage(productId, label, selectedLabels);
if(!ConfigurableMediaImages.isValidImage(swatchImageUrl)) {
if (!ConfigurableMediaImages.isValidImage(swatchImageUrl)) {
console.log('no image found');
return;
}

var swatchImage = ConfigurableMediaImages.getImageObject(productId, swatchImageUrl);

ProductMediaManager.swapImage(swatchImage);
this.swapImage(swatchImage);
},

swapImage: function(targetImage) {
empiricompany marked this conversation as resolved.
Show resolved Hide resolved
targetImage.classList.add('gallery-image');

var imageGallery = document.querySelector('.product-image-gallery');

if (targetImage.complete) { // image already loaded -- swap immediately
var galleryImages = imageGallery.querySelectorAll('.gallery-image');
galleryImages.forEach(function(image) {
image.classList.remove('visible');
});

// move target image to correct place, in case it's necessary
imageGallery.appendChild(targetImage);

// reveal new image
targetImage.classList.add('visible');
} else { // need to wait for image to load
// add spinner
imageGallery.classList.add('loading');

// move target image to correct place, in case it's necessary
imageGallery.appendChild(targetImage);

// wait until image is loaded
targetImage.addEventListener('load', function() {
// remove spinner
imageGallery.classList.remove('loading');

// hide old image
var galleryImages = imageGallery.querySelectorAll('.gallery-image');
galleryImages.forEach(function(image) {
image.classList.remove('visible');
});

// reveal new image
targetImage.classList.add('visible');
});
}
},

wireOptions: function() {
$j('.product-options .super-attribute-select').change(function(e) {
ConfigurableMediaImages.updateImage(this);
var selectElements = document.querySelectorAll('.product-options .super-attribute-select');
selectElements.forEach(function(selectElement) {
selectElement.addEventListener('change', function(e) {
ConfigurableMediaImages.updateImage(this);
});
});
},

swapListImage: function(productId, imageObject) {
var originalImage = $j('#product-collection-image-' + productId);
var originalImage = document.querySelector('#product-collection-image-' + productId);

if(imageObject[0].complete) { //swap image immediately
if (imageObject.complete) { // swap image immediately

//remove old image
originalImage.addClass('hidden');
$j('.product-collection-image-' + productId).remove();
// remove old image
originalImage.classList.add('hidden');
document.querySelectorAll('.product-collection-image-' + productId).forEach(function (image) {
image.remove();
});

//add new image
imageObject.insertAfter(originalImage);
// add new image
originalImage.parentNode.insertBefore(imageObject, originalImage.nextSibling);

} else { //need to load image
} else { // need to load image

var wrapper = originalImage.parent();
var wrapper = originalImage.parentNode;

//add spinner
wrapper.addClass('loading');
// add spinner
wrapper.classList.add('loading');

//wait until image is loaded
imagesLoaded(imageObject, function() {
//remove spinner
wrapper.removeClass('loading');
// wait until image is loaded
imageObject.addEventListener('load', function () {
// remove spinner
wrapper.classList.remove('loading');

//remove old image
originalImage.addClass('hidden');
$j('.product-collection-image-' + productId).remove();
// remove old image
originalImage.classList.add('hidden');
document.querySelectorAll('.product-collection-image-' + productId).forEach(function (image) {
image.remove();
});

//add new image
imageObject.insertAfter(originalImage);
// add new image
originalImage.parentNode.insertBefore(imageObject, originalImage.nextSibling);
});

}
Expand All @@ -198,7 +253,7 @@ var ConfigurableMediaImages = {
}

var newImage = ConfigurableMediaImages.getImageObject(productId, swatchImageUrl);
newImage.addClass('product-collection-image-' + productId);
newImage.classList.add('product-collection-image-' + productId);

ConfigurableMediaImages.swapListImage(productId, newImage);
},
Expand Down
50 changes: 25 additions & 25 deletions skin/frontend/rwd/default/js/configurableswatches/swatches-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,63 +15,63 @@
var ConfigurableSwatchesList = {
swatchesByProduct: {},

init: function()
{
init: function() {
var that = this;
$j('.configurable-swatch-list li').each(function() {
that.initSwatch(this);
var $swatch = $j(this);
if ($swatch.hasClass('filter-match')) {
that.handleSwatchSelect($swatch);
document.querySelectorAll('.configurable-swatch-list li').forEach(function(element) {
that.initSwatch(element);
var swatch = element;
if (swatch.classList.contains('filter-match')) {
that.handleSwatchSelect(swatch);
}
});
},

initSwatch: function(swatch)
initSwatch: function initSwatch(swatch)
empiricompany marked this conversation as resolved.
Show resolved Hide resolved
{
var that = this;
var $swatch = $j(swatch);
var $swatch = swatch;
var productId;
$j($swatch).hover(function() {
$swatch.addEventListener('mouseenter', function() {
/**
*
* - Preview the stock status
**/
var swatchUl = $swatch.parent();
swatchUl.find('.x').each(function(){
$j(this).show();
$j(this).closest('li').addClass('not-available');
var swatchUl = $swatch.parentNode;
var xElements = swatchUl.querySelectorAll('.x');
xElements.forEach(function(element) {
element.style.display = 'block';
element.closest('li').classList.add('not-available');
});
});
if (productId = $swatch.data('product-id')) {
if (typeof(this.swatchesByProduct[productId]) == 'undefined') {
if (productId = $swatch.dataset.productId) {
if (typeof this.swatchesByProduct[productId] == 'undefined') {
this.swatchesByProduct[productId] = [];
}
this.swatchesByProduct[productId].push($swatch);

$swatch.find('a').on('click', function(e) {
var anchorElement = $swatch.querySelector('a');
anchorElement.addEventListener('click', function(e) {
e.preventDefault();
that.handleSwatchSelect($swatch);
});
}
},

handleSwatchSelect: function($swatch)
{
var productId = $swatch.data('product-id');
handleSwatchSelect: function(swatch) {
var productId = swatch.dataset.productId;
var label;
if (label = $swatch.data('option-label')) {
if (label = swatch.dataset.optionLabel) {
ConfigurableMediaImages.swapListImageByOption(productId, label);
}

$j.each(this.swatchesByProduct[productId], function(key, $productSwatch) {
$productSwatch.removeClass('selected');
Array.from(this.swatchesByProduct[productId]).forEach(function(productSwatch) {
productSwatch.classList.remove('selected');
});

$swatch.addClass('selected');
swatch.classList.add('selected');
}
};

$j(document).on('configurable-media-images-init', function(){
document.addEventListener('DOMContentLoaded', function() {
ConfigurableSwatchesList.init();
});