google-apps-scriptgmail-addons

Creating a select (dropdown) input with a dynamic list of options in a gmail addon


The Google App Script SelectionInput docs show selection inputs with a static list of options. Trying to create a dynamic options list like below:

var items = [...];

var selectWidget = CardService.newSelectionInput()
  .setType(CardService.SelectionInputType.DROPDOWN)
  .setTitle("Select an item")
  .setFieldName("item");

items.forEach(function (item) {
  selectWidget.addItem(item, item, false);
});

results in a runtime error:

Object does not have property 
    - /​Card/​sections[0]/​widgets[1]/​selection_control/​items. [line: 115, function: XYZ, file: Code]

How should I go about creating a selection input with dynamic options in my gmail addon?


Solution

  • Addon Dropdown

    I haven't built any addons in a while but I knew that I wanted to sometime in the future so I did a couple of examples for myself. This is part of one of them.

    function buildMessageCard(dfltObj){
      var card=CardService.newCardBuilder();
      card.setHeader(CardService.newCardHeader().setTitle('DropDown Tester'));
      var section=CardService.newCardSection().setHeader('Making Choices');
      var makeAChoice=CardService.newSelectionInput().setType(CardService.SelectionInputType.DROPDOWN)
      .setTitle('Make a Choice')
      .setFieldName('userChoice')
      .setOnChangeAction(CardService.newAction().setFunctionName('saveChoice'))
      for(var i=1;i<dfltObj.selections;i++){
        makeAChoice.addItem('Choice ' + i, i, (i==dfltObj.finalChoice)?true:false);
      }
      section.addWidget(makeAChoice);
      var choiceText=CardService.newTextInput()
      .setTitle('Final Choice')
      .setFieldName('finalChoice')
      .setValue(dfltObj.finalChoice);
      section.addWidget(choiceText);
      card.addSection(section);
      return card.build();
    }
    
    function saveChoice(e){
      var cObj={finalChoice:e.formInput.userChoice};
      setDefaults(cObj);
      return buildMessageCard(getDefaults());
    }
    
    var Default_URL='dflturl';
    
    function setDefaults(dfltObj){
      var ss=SpreadsheetApp.openByUrl(Default_URL);
      var sh=ss.getSheetByName('Defaults');
      var rg=sh.getDataRange();
      var vA=rg.getValues();
      for(var i=0;i<vA.length;i++){
        if(typeof(dfltObj[vA[i][0]])!='undefined'){
          vA[i][1]=dfltObj[vA[i][0]];
        } 
      }
      rg.setValues(vA);
    }
    
    function getDefaults(){
      var ss=SpreadsheetApp.openByUrl(Default_URL);
      var sh=ss.getSheetByName('Defaults');
      var rg=sh.getDataRange();
      var vA=rg.getValues();
      var dfltObj={};
      for(var i=0;i<vA.length;i++){
        dfltObj[vA[i][0]]=vA[i][1];
      }
      return dfltObj;
    }
    

    So you could change the number of selections dynamically with a little code and with a little more thought you could probably figure out how to change the options.

    Here is the hash table for my dfltObj:

    enter image description here