Home > Software design >  How to build dynamic dropdowns in configuration setup?
How to build dynamic dropdowns in configuration setup?

Time:03-26

I'm new to Google Data Studio and looking into building a community connector for our Saas service. For the configuration section, I need to use the Stepped Configuration process. Basically, I nested set of drop-down lists.

However, I need the data to populate those lists to come from my API. I have the REST service endpoints defined, but I cannot find any documenation/examples of how I'd configure this in the getConfig section of the community connector.

Does anyone have a working example I could use as reference?

In reviewing the documentation, there is a section on stepped configurations, which is what I am looking for. You can find that example here: https://developers.google.com/datastudio/connector/stepped-configuration#dynamic_dropdowns

In this example, they show the following for defining the dropdown values. Notice for the states, they have hard-coded the values for "Illinois" and "California".

My question is, how can I dynamically call API to retrieve values to populate this list? I have 3 nested dropdowns, each with a separate API call, using the answer from previous dropdown to drive the next.

For example first API might be http://myapi.com/countries which returns list of countries. When they select country, next API call might be http://myapi.com/states?country=US

etc.

 config.newSelectSingle()
      .setId("state")
      .setName("State")
  // Set isDynamic to true so any changes to State will clear the city
  // selections.
      .setIsDynamic(true)
      .addOption(config.newOptionBuilder().setLabel("Illinois").setValue("IL"))
      .addOption(config.newOptionBuilder().setLabel("California").setValue("CA"));

  if (!isFirstRequest) {
    var city = config.newSelectSingle()
        .setId("city")
        .setName("City");
    var cityOptions = optionsForState(configParams.state);
    cityOptions.forEach(function(labelAndValue) {
      var cityLabel = labelAndValue[0];
      var cityValue = labelAndValue[1];
      city.addOption(config.newOptionBuilder().setLabel(cityLabel).setValue(cityValue));
    });
  }
  return config.build();
}

CodePudding user response:

Worked through the issues I was having. For others who might have hit similiar issues, here's my working getConfig() method.

function getConfig(request) {
  var config = cc.getConfig();
  var configParams = request.configParams;
  var isFirstRequest = configParams === undefined;
  if (configParams ===undefined || configParams.tab ===undefined) {
    config.setIsSteppedConfig(true);
  }


var url ='https://<yourAPIURL>';

var userProperties = PropertiesService.getUserProperties();
var key = userProperties.getProperty('dscc.key');
 var mykey ="Bearer "   key

  var options = {
     "method" : "GET",
     "headers" : {
       "AUTHORIZATION" : mykey,
       "cache-control": "no-cache"
     }
   };
  var response = UrlFetchApp.fetch(url,options);
  var parsedResponse = JSON.parse(response);
      

  var zoneControl = config.newSelectSingle()
  .setId("zone")
  .setName("Zone")
  .setIsDynamic(true);
  
  parsedResponse.map(function(itm) {
    zoneControl.addOption(config.newOptionBuilder().setLabel(itm.name).setValue(itm.id))
  });
  
  if(configParams !==undefined && configParams.zone !==undefined){
    var blockurl ='https://<yourAPIURL>?zoneid='  configParams.zone;
    var blockResponse = UrlFetchApp.fetch(blockurl,options);
    var parsedBlockResponse = JSON.parse(blockResponse);
     var blockControl = config.newSelectSingle()
     .setId("block")
     .setName("Block")
     .setIsDynamic(true);
    
   parsedBlockResponse.map(function(itm) {
    blockControl.addOption(config.newOptionBuilder().setLabel(itm.name).setValue(itm.blockKey))
  });
  }
  
  if(configParams !==undefined && configParams.block !==undefined){
    var taburl =''https://<yourAPIURL>?blockKey='  configParams.block;
    var tabResponse = UrlFetchApp.fetch(taburl,options);
    var parsedTabResponse = JSON.parse(tabResponse);
     var tabControl = config.newSelectSingle()
     .setId("tab")
     .setName("Tab")
    
   parsedTabResponse.map(function(itm) {
    tabControl.addOption(config.newOptionBuilder().setLabel(itm.name).setValue(itm.internalname))
  });
  }
    
  return config.build();

}

CodePudding user response:

without testing the code:

function getConfig(request) {
  var configParams = request.configParams;
  var isFirstRequest = configParams === undefined;

var lst=["A","B","C"]; // your values obtained from REST

var tmp=config.newSelectSingle(); //add element to side
var element=tmp.setId("state").setName("State").setIsDynamic(true); // set name and id

for(var i in lst) // set all the values:
{
element = element.addOption(config.newOptionBuilder().setLabel(lst[i]).setValue(lst[i]))
}

if(isFirstRequest || configParams.state==undefined) // no state selected yet
{
config.setIsSteppedConfig(true); // stop here
}
else
{
// next dropdown element,
// Rest API with element set to: configParams.state
var lst2= ["x","y","z"]
var tmp2=config.newSelectSingle(); //add element to side
var element2=tmp2.setId("element2").setName("Element 2 depends on " configParams.state).setIsDynamic(true); // set name and id

for(var i in lst2) // set all the values:
{
element2 = element2.addOption(config.newOptionBuilder().setLabel(lst2[i]).setValue(lst2[i]))
}

// code for 3rd

}

}

If the user changes the first dropdown value alle other drop downs have to be reset. This may be a bit tricky.

  • Related