How can I apply individual style to elements within a repeater item.

Hello respected members. I have two databases for my shop. One for listing products (productDatabase) the other for sellers (publisherDatabase).

I have created a “Premium” boolean field in the publisherDatabase. The Velo code first filters the publisherDatabase to get the _id of publishers with a premium plan. Then, it queries the productDatabase to get the products that reference the filtered publisher IDs. Finally, a repeater displays all products, I want the filtered items (those with references to premium plan sellers) and change the border color of the container (insider repeater) to blue.

My problem is that all items in a repeater have the same ID. So even though I finally filtered the items properly, the style change still applies to all containers. Ugh!!!

My page code:

// Query the "publisherDatabase" to get all the publishers
wixData.query("publisherDatabase")
  .eq('premium', true) // Filter sellers with premium plan
  .find()
  .then(results => {
    let publisherIds = results.items.map(item => item._id);
    console.log("All publisher IDs:", publisherIds);

    wixData.query("productDatabase")
      .hasSome("reference", publisherIds)
      .find()
      .then(results => {
        console.log("Filtered successfully");
        
// Change the border color of the container "#itemContainer" inside the repeater "#repeater" to blue if the "reference" field of the item matches one of the publisher IDs
        $w("#repeater").onItemReady(($item, itemData, index) => {
          let container = $item("#itemContainer");
          container.style.borderColor = "blue";
          console.log("Container style changed to blue successfully");
        });
      })
      .catch(error => {
        console.log(error);
      });
  })
  .catch(error => {
    console.log(error);
  });

I played around with chatGPT and it told me to create indexes for the container. I applied its example but it did not work, it broke the style change.

ChatGPT suggestion:

  $w("#repeater").onItemReady(($item, itemData, index) => {
  let container = $item(`#itemContainer${index}`);
  container.style.borderColor = "blue";
  console.log("Container style changed to blue successfully");

I would be very grateful if someone could point me in the right direction. :heart:

Yeah, Chat-GPT also gives a lot of useless informations :laughing:

My problem is that all items in a repeater have the same ID. So even though I finally filtered the items properly, the style change still applies to all containers. Ugh!!!

Absolutely correct!

When does the repeated container know if it has to change it’s color?
You have a container-ID of your repeated container inside your repeater.

let contID = “xxxxxxxxxxxx”

Your repeater-code:

$w.onReady(function () {
    $w("#repeater").onItemReady(($i, iData, index) => {
        console.log("Item-Data: ", iData);

        if (iData['myDBFieldIDhere']==="xxxxxxxxxxxxx") {
            console.log("Do something!!!!");}
            else {console.log("Else do something else!!!!");}
    });
});
$w.onReady(function () {
    $w("#repeater").onItemReady(($i, iData, index) => {
        console.log("Item-Data: ", iData);

        if (iData['myDBFieldIDhere']==="xxxxxxxxxxxxx") {
               console.log("Do something!!!!");
               $i('#'+contID); container.style.borderColor="red";
            }
            else {
               console.log("Else do something else!!!!");
               $i('#'+contID); container.style.borderColor="blue";
            }
    });
});

The → INDEX won’t help in this case → you need to know what’s inside of each item-data.

Example:
If found in item-Data what you need → green-container, else —> red-container !!!
The ID for all containers is the same → that’s correct → but it is a repeated-container inside a repeater.

!!! Good luck and happy coding !!!

Code-Ninja

Thank you! When I have the time I will try to implement your suggestion and consult with someone smarter than me if I get stuck. :hugs:

Edit: Quick question, how do I find my container-ID to create the contID variable?

Also I’m not sure if I need this, the items in repeater are already filtered from the productDatabase query above. I just need to apply the style changes to specific container(s) in repeater

if(iData['myDBFieldIDhere']==="xxxxxxxxxxxxx"){

I just have seen, that you do not load the filtered data back to your repeater.
This is very strange. Did you show the whole code?

Hi again, yes it’s the whole code.

This is what filters the products in repeater.

wixData.query("productDatabase")      .hasSome("reference", publisherIds)      .find()      .then(results => {        console.log("Filtered successfully");

If you want I am on Discord, also in the Community server: dqny#6106

Sorry, i do not use DISCORD.

After having a second look onto your code → your code seems either to be INCOMPLETE , or INCORRECT , or even both.

You are using Wix-Data-Query , but you never imported it …

import wixData from 'wix-data';  <-----missing code-part!!!

//not included inside your code !!!!

You are using onItemReady() to await for readyness of your repeater-data, but you never have feeded your repeater with data, to wait for…

$w("#repeater").onItemReady(($i,iData,index)=>{.......

Missing code-part.....
$w("#repeater").data = results-data of your query here

The Velo code first filters the publisherDatabase to get the _id of publishers with a premium plan. Then, it queries the productDatabase to get the products that reference the filtered publisher IDs. Finally, a repeater displays all products…

!!! NOT COMPLETELY TRUE !!!

You filter → publisherDatabase to get the IDs → yes, TRUE !!!
You filter again → productDatabase to get all related PRODUCTS → yes, TRUE !!!

But you never load your REPEATER with the found data.

And even if you are using a —> DATASET (although you never mentioned that) , your code would still be wrong and incomplete.
Missing code-part…

$w.onReady(()=>{
	$w('#datasetXXX).onReady(()=>{
		Missing code-part....
	});
});

There is a lot of CONFUSION inside your code.

Now, let’s do it the right way…
Try to understand what’s happening here…

import wixData from 'wix-data';

const DATABASE1 = "publisherDatabase";
const DATABASE2 = "productDatabase";

$w.onReady(async()=> {
    //------STEP-I------------
    let premiumUserIDs = await get_PremiumUsers();
    console.log("Congratulation!!! You got all Premium-User-Ids!!!");
    console.log("All-Premium-User-IDs: ", premiumUserIDs);
    //------STEP-II------------
    let products = await get_Products();
    console.log("Congratulation!!! You got all Product-Items, what next???");
    console.log("AllProducts: ", products);
    //------STEP-III------------
});

function get_PremiumUsers() {console.log("Step-I running...getting PREMIUM-USER-IDs...");
    return wixData.query(DATABASE1)
    .eq('premium', true)
    .find()
    .then(results => {
        let publisherIds = results.items.map(item => item._id);
        return publisherIds;
    }).catch((err)=>{console.log(err);});
}

function get_Products() {
    return wixData.query(DATABASE2)
    .find()
    .then((res)=>{return res.items})
    .catch(error=> {console.log(error);});
}

After you have understood this…try to add further code-parts, like…


import wixData from 'wix-data';

const DATABASE1 = "publisherDatabase";
const DATABASE2 = "productDatabase";
const dbField = "reference";

$w.onReady(async()=> {console.log("Page is ready...");
    let premiumUserIDs
    //------STEP-I------------
    premiumUserIDs = await get_PremiumUsers();
    console.log("Congratulation!!! You got all Premium-User-Ids!!!");
    console.log("All-Premium-User-IDs: ", premiumUserIDs);
    //------STEP-II------------
    let products = await get_Products();
    console.log("Congratulation!!! You got all Product-Items, what next???");
    console.log("AllProducts: ", products);
    //------STEP-III------------

    $w("#repeater").onItemReady(($i, iData, index) => {
        console.log("Item-Data: ", iData);
        let counter=0;        
        
        for (let i = 0; i < premiumUserIDs.length; i++) {
            const element = premiumUserIDs[i];

            if (element===iData[dbField]) {
                console.log("Found ID!!!!");
                counter = counter+1;
            }
            
            if(i>=premiumUserIDs.length-1) {
                if (counter>0) {console.log("Found!!!!");
                    $i('#'+contID); container.style.borderColor="green";
                }
                else {
                    console.log("No found!!!!");
                    $i('#container').style.borderColor="red";
                }
            }           
        }       
    });
});

function get_PremiumUsers() {console.log("Step-I running...getting PREMIUM-USER-IDs...");
    return wixData.query(DATABASE1)
    .eq('premium', true)
    .find()
    .then(results => {
        let publisherIds = results.items.map(item => item._id);
        return publisherIds;
    }).catch((err)=>{console.log(err);});
}

function get_Products() {
    return wixData.query(DATABASE2)
    .find()
    .then((res)=>{return res.items})
    .catch(error=> {console.log(error);});
}

Don’t use DATASET-CONNECTIONS in this example!!!
This code should work without any datasets!!!