I've seen a lot of questions about changing a single unique element within a repeater. After pouring over the other questions I have a fairly simple solution that might help others.
My particular needs were that I needed to set up something similar to the stock Wix color selector for a custom product page. My custom page is set up so that I can sell totally customizable printed garments (T-shirts and such) as well as standard products. My totally-custom products have their own dropdowns for garment types, color, and sizes (working fine with 89,400 product variants) .
For 'standard' products I wanted the ability to have regular product options. I built logic that will determine if the product has any options and if it does it will show them. I can handle 0-4 list options, 0-1 color options, and 0-1 custom text fields. The issue I had was that the best way to show the color options was through a repeater and it made visual dynamics difficult. I populated the color repeater with a button and text to show the color name. It worked fine, but there was no visual indication that a color had been chosen.
As we all know (or found out the hard way, like myself) when one imposes an event upon a repeater, the entire repeater updates. So any code on a clicked element would affect all the elements from the one clicked on all the way down the rest of the repeater. I added a logic switch ('colorselected' in my example) and used a simple 'if' statement to check for a match to the variable inside of the onClick() event.
When my "select color" button is clicked on the repeater, it changes the outline of the button to visually signify that single item has been selected. This code can be fairly easily modified to suit your needs in the event that you want some user-action to change a single repeater-item. here's my code:
$w.onReady(function () {
let selectedcolor; //variable to see if a color choice has been clicked on
/*text13 and button 4 are the elements in my repeater
the arrays names theoptions[] and theoptionchoices[] are for adding the options to the cart when all the unknown amount of options are chosen correctly */
//populate repeater two
idstring2 = "color" + (x + 1);
repeaterstuff2 = {
"_id": idstring2,
"colorcode": optionvalues[x],
"xcolorname": colornames[x]
}
myrepeater2.push(repeaterstuff2);
$w('#repeater2').data = myrepeater2;
$w("#repeater2").forEachItem(($item2, itemData2, index) => {
$item2('#text13').text = itemData2.xcolorname;
$item2('#button4').style.backgroundColor = itemData2.colorcode;
if( selectedcolor==itemData2.xcolorname) {
$item2('#button4').style.borderColor="red";
}
item2("#button4").onClick((event) => {
filled[0] = 1; //dynamic option logic
theoptions[0] = "Color"; //set option name for add to cart
theoptionchoices[0] = itemData2.xcolorname;
selectedcolor=itemData2.xcolorname; //tell the repeater which color to change
$w("#repeater2").forEachItem(($item2, itemData2, index) => {
$item2('#button4').style.backgroundColor = itemData2.colorcode;
$item2('#button4').style.borderColor="black";
//if this element is the chosen color change the border
if( selectedcolor==itemData2.xcolorname) {
$item2('#button4').style.borderColor="red";
}
});
}
Here's how it renders. Note the red border on the chosen color.
I hope my explanation wasn't too vague and that it will help others that, like me, faced the same challenge.
Thank you Russian-Dima!
Yes, I am a fan of well-formatted code and I am well aware that my code lacks any semblance of structure. However, and this is no excuse--I know, I had never done any JavaScript before 03-09-2021, so I'm learning as I go.
1) This one should go to the example-section.
2) You should edit your post and show the code, like it should be in a CODE-BLOCK.
3) And you should also complete the whole code (starting with --> onReady() )