Populating list data in dropdown from JS

Hi all, I'm quite new to ReTool. And pretty new to JS as well, so I have probably bitten of a little more than I can chew again. . . . Seems to be my thing.

I'm working out what i'm needed to get done for my client though. However am now snagged here, which would seem to be a very simple thing.

I'm trying to populate a dropdown based on data that is changing so not hard coded in through "inspector: values"

Is there a way to populate it through JS from an array? dropdown.setValue seems to set the selected value and not the list of values. The property dropdown.values seems to list values in the dropdown as an array but it seems to only be possible to read from .values and not write to it. I have looked and searched for other options and properties but don't seem to be making progress.

Another approach I could take would be to have the dropdown populated with a column of data within a table. But again i'm not quite sure how to go about this.

Any input would be hugely appreciated.

Looking forward to hearing back. Many thanks in advance.

Hi @tristanNebe

Welcome to the community!

I think what you are getting at can be done pretty simply - just use a set of curly brackets to reference an array of data you are looking to populate the dropdown menu instead of hard coding it in. Here is an example if you had a transformer that returned an array. (note the curly brackets in the right panel.

If you want to reference a table you can do this with a map. (note the {{query1.data.map(d=>d.Title)}} in values & display values. The formula for this is {{ queryname.data.map(d=>d.columnnameyouarelookingtomap)}}

Hope this is what you are looking for!

Hi @JoeyKarczewski,

Thanks so much for your reply! I really appreciate it!

I did manage to get {{ queryname.data.map(d=>d.columnnameyouarelookingtomap)}} to work for the one dropdown so that is working great.

With the second dropdown, it was a little more complex. Based on what was selected in the first dropdown (the above) i needed to find the “id” from a table and then look in a second table for entries with that “id” and certain other fields. One might have been able to do it using table queries but they are too new to me and filtering etc is not something i’ve got yet. So I tried to use a transformer as you suggested in your first example. So using 2 for loops, one to get the id from the one table and the second to look for the id and the other conditions that needed to be met from a second table. All matches I added to an array. I believe that the code was working because using console.log I was able to see what was being added to the array etc. However when I tried to return the array at the end of the transformer and set the dropdowns value to transformer.value (and I tried .data) nothing was coming through on the dropdown.

So I would be interested how to go about doing something like that. I tried 101 workarounds and couldn’t seem to work out to to get it right.

In the end I figured out a work around where I got a js query to generate an array and then write that array to a text box and then i could set the dropdown to the text box and that now seems to work fine but its by no means the most elegant solution.

If you have any thoughts on this, please do let me know I would be interested for the future and to possibly re do this in a more elegant way.

Many thanks.

Hey @tristanNebe

Happy to help my man.

Hmm… am a bit confused on what you mean by getting the ID. is that like an ID in a selected row?

Hi @JoeyKarczewski,

Sorry about that! Yeah, i’m sure it could get confusing. . . “Id” is just a column within the one table that needs to be matched with the “vehicle” in another table along with checking that “load” = 1. Then adding the “stop” to the array.

Here is the code i’m using within a js query and setting the array to a text box and the dropdown is reading the text in the text box . . . .

If I could use this code in a transformer and return the array so that the dropdown could read it straight from the transformer that would be better than my current work around.

let arrRouteNames = [];

function GenerateStopsCboData(SelectedRouteName){
let strVehicleCode;
let strStop;
let intRowCount;
  
  console.log ("Stops are being found for route " + SelectedRouteName)
  //Find Vehicle Number in table
  for (intRowCount = 0; intRowCount < tblVehicleDetails.data.length; intRowCount++){
   	if (tblVehicleDetails.data[intRowCount].name == SelectedRouteName){
      strVehicleCode = tblVehicleDetails.data[intRowCount].id;
      console.log("id found " + strVehicleCode)
      break;
    }

  }  
  
  
  for (intRowCount = 0; intRowCount < tblVisitsByDate.data.length; intRowCount++){
    //console.log("Vehicle " + tblVisitsByDate.data[intRowCount].vehicle + " and load " + tblVisitsByDate.data[intRowCount].load)
    if ((tblVisitsByDate.data[intRowCount].vehicle == strVehicleCode) && (tblVisitsByDate.data[intRowCount].load == "1")){
    	
      strStop = tblVisitsByDate.data[intRowCount].order
      console.log("adding stop = " + strStop);
      arrRouteNames.push(strStop)
      
    }
    
  }
	
  cboStopNumber.setValue = ""
  txtStopNumbersStore.setValue(arrRouteNames)
  
	return 

}

//console.clear();
GenerateStopsCboData(cboRouteName.value);

Hope this makes it clearer.

Many thanks.