Populating Selection Tag from Repeater Data

Hello everyone!

So, I was wonder if its possible to populate selection tag options based off of items present in a repeater.

The repeater is currently being populated by a dataQuery and filtered based off of another selection tag from the following code

After that, I’d like to populate a selection tag based off of the items present in the repeater


import wixData from 'wix-data';

//-------- USER-INTERFACE -------------------------------------------------
var DBFIELDS = []
var DATABASE = "Edgebanding"
var DBLIMIT = 1000
var REPEATER = "EdgeRepAll"
//-----------------------------
DBFIELDS[0] = "lengths";
//-------- USER-INTERFACE -------------------------------------------------

$w.onReady(()=>{
   wixData.query(DATABASE)
  .limit(DBLIMIT)
  .find()
  .then(async(results)=>{console.log(results.items);
     let ITEMS = results.items
     populateRepeater($w('#LengthsST').value);
  });
     
function populateRepeater(selectedOption1) {
 let dataQuery = wixData.query(DATABASE).ascending("title");
 if (selectedOption1.length>0){dataQuery = dataQuery.hasSome(DBFIELDS[0], selectedOption1);} 
  dataQuery.find()
  .then(results => {
    const filteredItems = results.items;
    $w('#'+REPEATER).data = filteredItems;
 })
}

Thanks for any pointers!

This CODE is very familiar to me, as if it was written by my own, regarding all the code-syntax and style.

Where did you find this code?

I am 100% sure, it was written by me :grin:

And YES, of course it is possible to populate SELECTION-TAGS!

But FIRST, read this to improve your coding skills…

Turn normal function into a RETURN-FUNCTION.
This will make your work with wix-data a little bit more simple.

What does mean → POPULATE SELECTION TAG ???

It’s nothing else as populate a …

  1. DropDown
  2. Radio-Button-Group

All of these needs an ARRAY, filled with objects…

$w("#mySelectionTags").options = [
    { 'label': 'Onion', 'value': 'onion'},
    { 'label': 'Tomatoes', 'value': 'tomatoes'},
    { 'label': 'Extra Cheese', 'value': 'cheese'}

];

Consisting of LABEL and VALUE .

EXAMPLE:

Let’s say you have a DATABASE called —> “Edgebanding”
Your DATABASE includes several DB-FIELDs, where you store all your data.
One of DB-FIELD is called —> “lengths”
Another DB-FIELD will be —> “title”
Another standard integrated DB-FIELD will be —> “_id”
Another standard integrated DB-FIELD will be —> “_owner”
And last DB-FIELD will be called —> “tags” → This is the DB-FIELD where you store all your SELECTION-Tags.

You also use several repeaters, which are called different —>
REPEATER-1 = “owner”

STEP-1:
Generating USER-INTEFACE: (defining variables)

//-------- USER-INTERFACE ---------------------------------
let DATABASE = "Edgebanding";
let DBLIMIT = 1000;
//-------------------------------
let DBFIELD = [];
    DBFIELD[0] = "lengths";
    DBFIELD[1] = "tags";
   // DBFIELD[2] = "title";

//-------------------------------
let REPEATER = [];
      REPEATER[0] = "#EdgeRepAll";
      REPEATER[1] = "#LengthsST";
//-------------------------------
let SEARCHVALUE = [];
    SEARCHVALUE[0] = "";  
    //SEARCHVALUE[1] = "mySearch_Value2_here"; 
    //SEARCHVALUE[2] = "mySearch_Value3_here"; 
//-------- USER-INTERFACE ---------------------------------

STEP-2:
Starting CODE with —> onReady(()=>{---------------});

$w.onReady(()=>{console.log('page ready...');});

STEP-3:
Using RETURN-FUNCTION… (We use a returning function, like already explained in the link shown above.)

$w.onReady(()=>{console.log('page ready...');
    let resData = await getData(DATABASE, DBFIELD[0], SEARCHVALUE[0]);
    console.log("RESULT-DATA = ", resData);
});
function getData(db, dbField, searchValue) {
    let dataQuery = wixData.query(db)
  
    if(searchValue){dataQuery = dataQuery.eq(dbField, searchValue);} 
    else {dataQuery = dataQuery.ascending("title");}
    
    return dataQuery.find()
    .then((results) => {
        if(results.items.length > 0){return(results);}
        else {console.log("No data found"); return ([]);}
    });
};

If no SEARCHVALUE included in the Query, you should get all DATA-ITEMS from DB.

STEP-4 (expanding code → adding the populateRepeater-function and the repeater-onItemReady-function)…

function populateRepeater(repeater, data) {
    $w('#'+repeater).data = data.items;
} 

$w('#'+REPEATER[0]).onItemReady(($item, itemData, index)=>{
        $w('#myTextElement1').text = itemData.title;
        $w('#myPicElement1').src = itemData["hereYourDeclaredImageDBField"];
        $w('#button1').onClick(()=>{console.log(itemData);});
});

FULL-CODE RIGHT NOW…

import wixData from 'wix-data';

//-------- USER-INTERFACE ---------------------------------
let DATABASE = "Edgebanding";
let DBLIMIT = 1000;
//-------------------------------
let DBFIELD = [];
    DBFIELD[0] = "lengths";
    DBFIELD[1] = "tags";
   // DBFIELD[2] = "title";

//-------------------------------
let REPEATER = [];
      REPEATER[0] = "#EdgeRepAll";
      REPEATER[1] = "#LengthsST";
//-------------------------------
let SEARCHVALUE = [];
    SEARCHVALUE[0] = "";  
    //SEARCHVALUE[1] = "mySearch_Value2_here"; 
    //SEARCHVALUE[2] = "mySearch_Value3_here"; 
//-------- USER-INTERFACE ---------------------------------



$w.onReady(async()=>{console.log('page ready...');
    let resData = await getData(DATABASE, DBFIELD[0], SEARCHVALUE[0]);
    console.log("RESULT-DATA = ", resData);
    //--------------------------------
    populateRepeater(REPEATER[0], resData);
    
    $w('#'+REPEATER[0]).onItemReady(($item, itemData, index)=>{
        $w('#myTextElement1').text = itemData.title;
        $w('#myPicElement1').src = itemData["hereYourDeclaredImageDBField"];
        $w('#button1').onClick(()=>{console.log(itemData);});
    });
});

function getData(db, dbField, searchValue) {
    let dataQuery = wixData.query(db)
  
    if(searchValue){dataQuery = dataQuery.eq(dbField, searchValue);} 
    else {dataQuery = dataQuery.ascending("title");}
    
    return dataQuery.find()
    .then((results) => {
        if(results.items.length > 0) {console.log("Data found");
            return(results);
        }
        else {console.log("No data found"); return ([]);}
    });
}



function populateRepeater(repeater, data) {
    $w('#'+repeater).data = data.items;
} 


Check and replace all the ELEMENT-IDs with your own!!!

What have been done till here?

  • a DATABASE was queried and some data was found.
  • a repeater has been populated with the found data.
  • items now should be visible inside repeater.

What still has to be done?

“populate selection tag options based off of items present in a repeater”

We have now all items inside repeater.
What you wanna have now is the functions, which can populate a selections-tag-element out of the present items inside the repeater.

This function should be able to populate all 3-types like…

  1. Dropdowns
  2. Radiobutton-Groups
  3. Selection-Tags

Recommended-FUNCTION-INPUT:

  1. repData —> REPEATER-DATA → (results.items)
  2. dbField —> Database-Field → which related DB-FIELD ?

In this case it will be the —> “tags”-field. This is the ID of the Database-Field, where you store all your selectiontag-informations.

function get_sTagOptions(repData, dbField) {console.log("Repeater-Data: ", repData);
    let options=[];
    
    
    for (let a = 0; a < repData.length; a++) {
        const element = repData[a]; 
        console.log(element); 
        console.log(element.tags); 
        console.log(element.tags[0]);
        
        for (let b = 0; b < element.tags.length; b++) {
            options.push({label: element.tags[b], value: element.tags[b]})
        }
    } return options;   
}

How to start/use function ? (using async-await) !!!

let options = await get_sTagOptions(repData, dbField); console.log(options);

Now try to put all information together and bring this example to work!

Good luck!

Na Hallöchen Ninja!

Yea your name definitely isn’t unfamiliar to me. I’ve been studying your examples extensively for the past 8 months.

You really helped me out for the first time from this post: https://www.wix.com/velo/forum/coding-with-velo/how-can-i-create-multi-checkbox-filter-similar-to-the-wix-store-prebuild-filter

And that’s of course where you probably recognize your code and syntax from!

So it’s been a busy past couple of weeks, and I’ve managed to compile something that surprisingly works! Here is everything…

(the ZShield is how I inactivate items in the database that are currently out of stock, so they get removed from the repeater)


import wixData from 'wix-data';
import wixWindow from 'wix-window';

//-------- USER-INTERFACE -------------------------------------------------
var DBFIELDS = []
var DATABASE = "Edgebanding"
var DBLIMIT = 1000
var REPEATER = "EdgeRepAll"
//-----------------------------
DBFIELDS[0] = "lengths";       
DBFIELDS[1] = "finishes"; 
DBFIELDS[2] = "zShield"; 
//-------- USER-INTERFACE -------------------------------------------------

$w.onReady(()=>{
   $w('#TheShield').hide()  
   wixData.query(DATABASE)
  .limit(DBLIMIT)
  .find()
  .then(async(results)=>{console.log(results.items);
     populateRepeater($w('#LengthsST').value, $w('#FinishesST').value, $w('#TheShield').value);
      populatesTags("LengthsST", DBFIELDS[0], DBFIELDS[1], $w('#FinishesST').value, $w('#TheShield').value);
      populatesTags("FinishesST", DBFIELDS[1], DBFIELDS[0], $w('#LengthsST').value, $w('#TheShield').value);
  });
  

  $w("#EdgeRepAll").onItemReady (async($item, itemData) => {
      $item("#repTitle").text = itemData.title;
      $item("#repImage").src = itemData.image;

    $item("#repImage").onClick(()=>{
        const repeaterItem = itemData;
        wixWindow.openLightbox("Edgebanding Product",repeaterItem)
      });
      
    $item("#arrow").onClick(()=>{
        const repeaterItem = itemData;
        wixWindow.openLightbox("Edgebanding Product",repeaterItem)
      });
   });

$w('#LengthsST, #FinishesST').onChange(()=>{
      $w("#LengthsST").value =[$w("#LengthsST").value[$w("#LengthsST").value.length -1]];
      $w("#FinishesST").value =[$w("#FinishesST").value[$w("#FinishesST").value.length -1]];
      populateRepeater($w('#LengthsST').value, $w('#FinishesST').value, $w('#TheShield').value);
      populatesTags("LengthsST", DBFIELDS[0], DBFIELDS[1], $w('#FinishesST').value, $w('#TheShield').value);
      populatesTags("FinishesST", DBFIELDS[1], DBFIELDS[0], $w('#LengthsST').value, $w('#TheShield').value);
   });

   $w('#Reset').onClick(()=> {
      $w("#LengthsST, #FinishesST, #sTagTest").value = undefined; 
      populateRepeater($w('#LengthsST').value, $w('#FinishesST').value, $w('#TheShield').value)
      populatesTags("LengthsST", DBFIELDS[0], DBFIELDS[1], $w('#FinishesST').value, $w('#TheShield').value);
      populatesTags("FinishesST", DBFIELDS[1], DBFIELDS[0], $w('#LengthsST').value, $w('#TheShield').value);
   });
});

function populateRepeater(selectedOption1, selectedOption2, selectedOption3) {
 let dataQuery = wixData.query(DATABASE)
    .ascending("title");
 if (selectedOption1.length>0){dataQuery = dataQuery.hasSome(DBFIELDS[0], selectedOption1);}
 if (selectedOption2.length>0){dataQuery = dataQuery.hasSome(DBFIELDS[1], selectedOption2);}
 if (selectedOption3.length>0){dataQuery = dataQuery.ne(DBFIELDS[2], selectedOption3);}
    dataQuery.find()
 .then(results => {
    const filteredItems = results.items;
    $w('#'+REPEATER).data = filteredItems;
 })
}

function populatesTags(sTags, DBFIELD1, DBFIELD2, selectedOption1, selectedOption3) {
 let dataQuery = wixData.query(DATABASE)
    .ascending(DBFIELD1);
 if (selectedOption1.length>0){dataQuery = dataQuery.hasSome(DBFIELD2, selectedOption1);}
 if (selectedOption3.length>0){dataQuery = dataQuery.ne(DBFIELDS[2], selectedOption3);}
    dataQuery.find()
 .then(results => {
    const ITEMS = results.items;
    let uniqueTitles = [...new Set(getxxx(ITEMS).flat())]; 
      $w('#'+sTags).options = buildOptions(uniqueTitles);
      function getxxx(items) {
         const titlesOnly=items.map(item => item[DBFIELD1]); 
         return [...new Set(titlesOnly)];
      }
      function buildOptions(item) {
         return item.map(item => {
            return {label:item, value:item};
         });
      }
   })
}

Now there’s just one more puzzle piece to go… but that’s a separate post.

Huge thanks again to you and all you do for the community.

1 Like

:wink: