@@ -25,13 +25,14 @@ $product = $block->getProduct()
25
25
"numberToShow " => json_decode ($ block ->escapeJs ($ block ->getNumberSwatchesPerProduct ()), true ),
26
26
"jsonConfig " => json_decode ($ block ->getJsonConfig (), true ),
27
27
"jsonSwatchConfig " => json_decode ($ block ->getJsonSwatchConfig (), true ),
28
- "mediaCallback " => json_decode ( $ block ->escapeJs ( $ block -> escapeUrl ( $ block -> getMediaCallback ())), true ),
28
+ "mediaCallback " => $ block ->getMediaCallback (),
29
29
"jsonSwatchImageSizeConfig " => json_decode ($ block ->getJsonSwatchSizeConfig (), true ),
30
30
"showTooltip " => json_decode ($ block ->escapeJs ($ configurableViewModel ->getShowSwatchTooltip ()), true )];
31
31
32
- $ configurableImages = $ swatchData ["jsonConfig " ][ ' images ' ];
32
+ $ configurableImages = $ swatchData ["jsonConfig " ];
33
33
$ swatchConfig = $ swatchData ["jsonConfig " ];
34
- $ swatchAttributes = $ swatchData ["jsonSwatchConfig " ];
34
+ $ swatchAttributes = $ swatchData ["jsonSwatchConfig " ];
35
+ $ mediaUrl = $ swatchData ["mediaCallback " ];
35
36
?>
36
37
<?php /*
37
38
<script type="text/x-magento-init">
@@ -72,51 +73,75 @@ $configurableImagesData = [];
72
73
foreach ($ configurableImages as $ productId => $ images ) {
73
74
$ configurableImagesData [$ productId ] = $ images ;
74
75
}
75
-
76
+ $ lockBlock = $ block ->getLayout ()->getBlock ('header ' );
77
+ $ lock = $ lockBlock ->getData ('print ' ) ?? false ;
78
+ if (!$ lock ) {
76
79
?>
77
80
<script>
78
81
var confGallery = <?= json_encode ($ configurableImagesData )?> ;
79
82
var catImage = '<?= htmlspecialchars ($ catImage )?> ';
80
83
84
+ // Local cache for swatch images
85
+ var swatchImageCache = {};
86
+
81
87
// Function to load gallery images via AJAX
82
- function loadGalleryImages(productId) {
83
- if (confGallery[productId]) {
84
- const images = confGallery[productId];
85
- let galleryHtml = '<div class="gallery" id="product-gallery"><div class="m-img" id="m-img">';
86
-
87
- // Find and add main image
88
- images.forEach(function(image) {
89
- if (image.isMain) {
90
- galleryHtml += '<img src="' + image.img + '" src-full="' + image.full + '" alt="' + image.caption + '" id="mImg" width="700px" height="700px">';
91
- }
92
- });
93
-
94
- galleryHtml += '</div><div class="thmb">';
95
-
96
- // Add thumbnails
97
- images.forEach(function(image) {
98
- galleryHtml += '<img src="' + image.thumb + '" loading="lazy" src-full="' + image.full + '" alt="' + image.caption + '" class="thumb" onclick="document.getElementById(\'mImg\').src=\'' + image.img + '\'; document.getElementById(\'mImg\').setAttribute(\'src-full\', \'' + image.full + '\');">';
99
- });
100
-
101
- galleryHtml += '</div></div>';
102
-
103
- // Update the gallery container
104
- const galleryContainer = document.querySelector('.gallery-container');
105
- if (galleryContainer) {
106
- galleryContainer.innerHTML = galleryHtml;
107
- }
108
- }
88
+ function loadSwatchImages(variantProductId) {
89
+ var mediaUrl = "<?= $ mediaUrl ?> ?product_id=" + variantProductId + "&isAjax=true";
90
+
91
+ // Get the clicked swatch and find its product image
92
+ var clickedSwatch = event.target;
93
+ var productImage = clickedSwatch.closest('[id^="product-item-info_"]').querySelector('img.product-image-photo');
94
+
95
+ if (!productImage) {
96
+ console.error('Product image not found');
97
+ return;
98
+ }
99
+
100
+ // Check if image is already cached
101
+ if (swatchImageCache[variantProductId]) {
102
+ // Apply loading effect for cached images too
103
+ productImage.style.opacity = '0.6';
104
+ productImage.src = swatchImageCache[variantProductId];
105
+ setTimeout(() => {
106
+ productImage.style.opacity = '1';
107
+ }, 150);
108
+ return;
109
+ }
110
+
111
+ // Apply loading effect
112
+ productImage.style.opacity = '0.6';
113
+ productImage.style.transition = 'opacity 0.3s ease-in-out';
114
+
115
+ fetch(mediaUrl)
116
+ .then(response => response.json())
117
+ .then(data => {
118
+ if (data && data.medium) {
119
+ // Store in cache
120
+ swatchImageCache[variantProductId] = data.medium;
121
+ // Update image with fade effect
122
+ productImage.src = data.medium;
123
+ // Fade in the new image
124
+ setTimeout(() => {
125
+ productImage.style.opacity = '1';
126
+ }, 100);
127
+ }
128
+ })
129
+ .catch(error => {
130
+ console.error('Error:', error);
131
+ // Restore opacity on error
132
+ productImage.style.opacity = '1';
133
+ });
109
134
}
110
-
111
- // Load gallery if cat_image parameter is present
112
- if (catImage !== '') {
113
- loadGalleryImages(catImage);
135
+ <?php
136
+ $ lockBlock ->setData ('print ' , true );
114
137
}
138
+ ?>
139
+
115
140
</script>
116
141
117
142
<div class="swatch-opt" data-role="swatch-options"></div>
118
143
119
- <a href="<?= $ product ->getProductUrl ()?> ">
144
+ <!--< a href="<?= $ product ->getProductUrl ()?> ">-- >
120
145
<div class="product-options-wrapper" id="product-options-wrapper">
121
146
<div class="fieldset" tabindex="0">
122
147
<div class="swatch-opt" data-role="swatch-options" data-rendered="true">
@@ -134,18 +159,43 @@ if (catImage !== '') {
134
159
<div class="swatch-attribute-options clearfix">
135
160
<?php foreach ($ swatchAttributes [$ attributeId ] as $ optionId => $ optionData ): ?>
136
161
<?php if (!is_array ($ optionData ) || !isset ($ optionData ['type ' ])) {
137
- continue ;
138
- }
139
- ?>
140
-
141
- <div class="swatch-option <?= $ optionData ['type ' ] == 1 ? 'color ' : 'text ' ?> "
162
+ continue ;
163
+ }
164
+ $ swatchType = $ optionData ['type ' ] == 1 ? 'color ' : 'text ' ;
165
+ if ($ swatchType == 'text ' ) : ?>
166
+ <a href="<?= $ product ->getProductUrl ()?> ">
167
+ <?php endif ; ?>
168
+
169
+ <div class="swatch-option <?= $ swatchType?> "
142
170
data-option-type="<?= $ escaper ->escapeHtmlAttr ($ optionData ['type ' ])?> "
143
171
data-option-id="<?= $ escaper ->escapeHtmlAttr ($ optionId )?> "
144
172
data-option-gallery-id="<?= $ escaper ->escapeHtmlAttr ($ optionToImage [$ optionId ])?> "
145
173
data-option-label="<?= $ escaper ->escapeHtmlAttr ($ optionData ['label ' ] ?? '' )?> "
146
- style="<?= $ optionData ['type ' ] == 1 ? 'background: ' . $ escaper ->escapeHtmlAttr ($ optionData ['value ' ]) . ' no-repeat center; ' : '' ?> ">
147
- <?= $ optionData ['type ' ] == 0 ? $ escaper ->escapeHtml ($ optionData ['value ' ]) : '' ?>
174
+ <?php if ($ swatchType == 'color ' ): ?>
175
+ <?php
176
+ $ options = $ swatchConfig ['attributes ' ][$ attributeId ];
177
+
178
+ // Transpose options array to be indexed by option id
179
+ $ transposedOptions = [];
180
+ if (isset ($ options ['options ' ]) && is_array ($ options ['options ' ])) {
181
+ foreach ($ options ['options ' ] as $ option ) {
182
+ if (isset ($ option ['id ' ])) {
183
+ $ transposedOptions [$ option ['id ' ]] = $ option ;
184
+ }
185
+ }
186
+ }
187
+
188
+ // Now $transposedOptions is indexed by option id
189
+ // Example: $transposedOptions[57] contains all data for Purple option
190
+ ?>
191
+ onclick="loadSwatchImages(<?= isset ($ transposedOptions [$ optionId ]['products ' ][0 ]) ? $ transposedOptions [$ optionId ]['products ' ][0 ] : 'null ' ?> )"
192
+ <?php endif ;?>
193
+ style="<?= $ swatchType == 'color ' ? 'background: ' . $ escaper ->escapeHtmlAttr ($ optionData ['value ' ]) . ' no-repeat center; ' : '' ?> ">
194
+ <?= $ swatchType == 'text ' ? $ escaper ->escapeHtml ($ optionData ['value ' ]) : '' ?>
148
195
</div>
196
+ <?php if ($ swatchType == 'text ' ): ?>
197
+ </a>
198
+ <?php endif ; ?>
149
199
<?php endforeach ; ?>
150
200
</div>
151
201
<input class="swatch-input super-attribute-select" name="super_attribute[<?= $ attributeId?> ]" type="text" value="" data-selector="super_attribute[<?= $ attributeId?> ]" data-validate="{required: true}" aria-required="true">
@@ -155,5 +205,5 @@ if (catImage !== '') {
155
205
</div>
156
206
</div>
157
207
</div>
158
- </a >
208
+ <!--</a>-- >
159
209
0 commit comments