Hello everyone,
So I’m currently working on creating a webshop with kirby/merx and am almost done with the final release.
However the single problem I’m facing is taking all my hairs at this point.
So for the store I have 2 product pages. 1 without variants and 1 with variants. For each product I have multiple images. On the product page there is a main image (selected-image) and there is a list of all said product images (product-images).
The functionality I’m working on is whenever I click on the product-images the selected-image changes into the product-image clicked. For the product page without variants this works, however for the product page with variants after selecting a new variant, all the product-images and selected-image changes into the desired variant. But when I click product-images after changing variants, the selected-image turns into the default variant product-image.
I think this has something to do with how I set up my click event and how it is called to change into data-resized-url, which is not updated in the select element. However every time I try to update this I seem to dig myself into a deeper hole. I believe there is an easy fix for my issue that I just can’t see anymore. So any help would be greatly appreciated.
Now for the actual data: (the code provided are not the full files (only what I think is relevant))
This is from my product-variants.php
<!-- Product Images -->
<div class="flex flex-col lg:flex-row justify-start items-start gap-4">
<div class="images-container flex flex-row lg:flex-col flex-wrap justify-start items-start gap-4" data-variant-id="<?= $page->defaultVariant()->id() ?>">
<?php $counter = 1; foreach($page->defaultVariant()->images() as $image):?>
<img id="product-image-<?= $counter ?>" class="product-images block rounded-2xl" src="<?= $image->crop('100','100')->url() ?>"
data-resized-url="<?= $image->crop('520','520')->url() ?>" >
<?php $counter++; endforeach; ?>
</div>
<img id="selected-image" class="block rounded-2xl" src="<?= $page->defaultVariant()->image()->crop('520','520')->url() ?>" >
</div>
<!-- Product Variants -->
<div class="flex flex-wrap gap-2 mt-4 relative text-center px-0 font-semibold border-0 text-brand-black outline-none bg-transparent">
<select class="form-input" data-action="update-variant" id="color">
<?php foreach ($page->variants() as $variant) : ?>
<option
value="<?= $variant->id() ?>"
<?php $page->defaultVariant() === $variant ? 'selected' : '' ?>
data-uid="<?= $variant->uid() ?>"
data-image="<?= $variant->image()->crop('520','520')->url() ?>"
<?php $counter = 1; foreach ($variant->images() as $image) {
echo "data-image" . $counter . "=\"" . $image->crop('100', '100')->url() . "\" "; $counter++;
}?>
data-price="<?= $variant->price()->toFormattedPrice() ?>"
data-stock-info="<?= $variant->stockInfo() ?>"
data-max-amount="<?= $variant->maxAmount() ?>"
>
<?= $variant->variantName() ?>
</option>
<?php endforeach; ?>
</select>
This is from my product-variants.js
class ProductVariants {
constructor(element) {
this.element = element;
const selectElement = element.querySelector('select[data-action="update-variant"]');
const imageElement = element.querySelector('#selected-image');
this.updateProductVariant = () => {
const selectedOption = selectElement.selectedOptions[0];
if (selectedOption) {
element.setAttribute('data-id', selectElement.value);
imageElement.src = selectedOption.dataset.image;
// Update additional images
let i = 1;
while (element.querySelector(`#product-image-${i}`)) {
const additionalImageElement = element.querySelector(`#product-image-${i}`);
if (selectedOption.dataset[`image${i}`]) {
additionalImageElement.src = selectedOption.dataset[`image${i}`];
}
i++;
}
This is from my product.js (click event)
// Get all images in the product-images div
var images = element.querySelectorAll('.product-images');
// Add click event listener to each image
images.forEach(function(image) {
image.addEventListener('click', function() {
// Get the data-resized-url of the clicked image
var clickedImageResizedUrl = this.getAttribute('data-resized-url');
// Get the selected-image element
var selectedImage = document.querySelector('#selected-image');
// Set the src of the selected-image to the data-resized-url of the clicked image
selectedImage.src = clickedImageResizedUrl;
});
});