Dynamic dropdowns for product options - velo

Hi guys I’m stucked with a piece of code, we have a client who requires to show dropdowns on a custom dynamic product page, we made it using static code time ago, but the new requirements is that we need to generate dropdowns dinamically, because the client states that they have about 40 different options, so hardcoding 40 differents options is not feasible for us, could anyone give us a light on this?

Kind Regards,

wixData . query ( “Stores/Products” )
. eq ( ‘_id’ , session . getItem ( ‘productId’ ))
. find ()
. then (( r ) => {

**if** ( r.items.length  >  0 ) { 
  $w ( '#text49' ). show () 
  **if**   ( 'OPTION1'  **in**  r.items [ 0 ]. productOptions ) { 
    $w ( '#dropdown1' ). show () 
    **let**  queryItems1  =  r.items [ 0 ]. productOptions.FABRIC.choices 
    $w ( '#dropdown1' ). placeholder  =  'SELECT OPTION1' 
    $w ( "#dropdown1" ). options  =  prepareDataForDropdown ( queryItems1 ,  "description" ) 
  }  **else** { 
    $w ( '#dropdown1' ). hide () 
  } 
  
  **if**  ( 'OPTION2'  **in**  r.items [ 0 ]. productOptions ){ 
    $w ( '#dropdown2' ). show () 
    **let**  queryItems2  =  r.items [ 0 ]. productOptions.LABEL.choices 
    $w ( '#dropdown2' ). placeholder  =  'SELECT OPTION2' 
    $w ( "#dropdown2" ). options  =  prepareDataForDropdown ( queryItems2 ,  "description" ) 
  }  **else** { 
    $w ( '#dropdown2' ). hide () 
  } 

  **if**   ( 'OPTION0'  **in**  r.items [ 0 ]. productOptions ) { 
     $w ( '#dropdown' ). show ()         
     **let**  queryItems  =  r.items [ 0 ]. productOptions.COLLAR.choices 
     $w ( '#dropdown' ). placeholder  =  'SELECT OPTION0'         
     $w ( "#dropdown" ). options  =  prepareDataForDropdown ( queryItems ,  "description" ) 
  }  **else** { 
    $w ( '#dropdown' ). hide () 
  } 

  **if**  ( 'OPTION3'  **in**  r.items [ 0 ]. productOptions ){ 
    $w ( '#dropdown3' ). show ()                 
    **let**  queryItems3  =  r.items [ 0 ]. productOptions.SLEEVE.choices 
    $w ( '#dropdown3' ). placeholder  =  'SELECT OPTION3'                 
    $w ( "#dropdown3" ). options  =  prepareDataForDropdown ( queryItems3 ,  "description" ) 
  } **else** { 
    $w ( '#dropdown3' ). hide () 
  } 

}  **else**  { 
 console . log ( 'Nothing to Show' ) 
} 

**function**  prepareDataForDropdown ( data ,  column ) { 
  **return**  data . map ( item  => { 
      **return**  { 
          label :  item[column ], 
          value :  item[column ], 
      } 
  }) 
} 

})
. catch (( err ) => {
console . log ( err );
});

What i can tell you immediatelly is that you will have a lot of difficulties solving this.

While generating such a functionality, your first boundary will be

  1. To read the DATABASE and get out data. You will ask yourself, why is it difficult to do that? Since you want to load DropDowns dynamically, you will have to scan your whole DATABASE to be able to show all options of your results inside a Dropdown.

  2. Second problem will be that you will have the problem to read more than just 1000-Items at once.

  3. A resulting next problem will be SLOW-LOADING-TIMES

  4. Another problem will be to get unique DATA out of found DATA from DATABSE.

  5. At least you will have to populate your Dropdown with FILTERED, UNIQUE DATA.

I am working on a similar problem at current time (already for days) generating a complete new QUERY-ENGINE which already start to work and do all the magic.

Already at this point you lose the fight against your sissue!

wixData.query("Stores/Products")   
.eq('_id', session.getItem('productId'))   
.find()   
.then((r) => {

How you wanna show all found data to be loaded into your dropdown, if the size of your DB is about for example 500-ITEMS, but your query is limited to max. 50-items???


So you already forgot about the usage of → LIMITATION → myQuery.limit(1000);

HURAYYY! You solved your first step!!! REALLY !!! Did you ??? Nope you still didn’t!!

Now let it be 1000-items inside your DB!!! Again your LIMITAION gets it’s boundaries!

A query can hold max. 1000-items! So what now?
myQuery.limit(1000) → what next?

Ok, let’s say you could solve this issues, but there is still the problem of slowing down speed of your site by heavy data-loadings. Maybe doing a query won’t take that much time, but if it comes to load an element like for example a REPEATER, you will have the next problem.

Maybe 3000-items are ok, maybe even 5000 or 10.000 items will still be ok, but the bigger your data will be, the slower will get your site.

And if you will need a cascading-dropdown (loading of next dropdown-options by the value of previous one) you got your JACK-POT!

But like i always like to say, there is a solution for every problem!:grin:
In my case i already long time ago created, maintaine, modified and expanded a project, called → iQuery (intelligentQuery) which do all the magic automatically.

Maybe you also want to create something like that.

If not, you will still have the OPTION to do a workaround and using a INPUT-BOX, SEARCHING by INPUT.

But i want to give you something…a little old code-part of my older project.



async function create_UniqueDropdown2(items, DBFIELDS, dropdown) {console.log("Creating dropdowns running...");
  const uniqueSubcategories = await getUniqueSubcategories(items); console.log("Unique-Subcategories: ", uniqueSubcategories);
  buildOptions(uniqueSubcategories);

  async function getUniqueSubcategories(items) {let myArray = []; 
    for (let a = 0; a < items.length; a++) {console.log(items[a][DBFIELDS]);        
      myArray.push(items[a][DBFIELDS]);
      if(a===items.length-1) {return [...new Set(myArray)];}
    }    
  }

  function buildOptions(uniqueList) {let options=[];
    for (let i = 0; i < uniqueList.length; i++) {
      options.push({"label":uniqueList[i], "value":uniqueList[i]});
      if(i===uniqueList.length-1) {$w(`#${dropdown}`).options = options; console.log("OPTIONS: ", options);}
    }
  }
}

Maybe you can use parts of it for your own one.