2
votes

I want to load a list of items into a dropdown select box using a combination of html and javascript (google apps script).

I have been able to get all of the javascript functions to call and return values as expected, but when my code tries to add options to the select object, it seems to fail.

Here is my current HTML ('index'):

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
// The code in these functions run when the page is loaded.
  google.script.run.withSuccessHandler(addItems).getFolderList();

//This function uses an array of folder names to create options for the select list
function addItems(folders){
  alert('addItems was called!');
  var htmlSelect = document.getElementById('folder');
  for(var z = 0; z < folders.length; z++){
    var selectBoxOption = document.createElement('OPTION');
    selectBoxOption.value = folders[z];
    selectBoxOption.text = folders[z];
    htmlSelect.add(selectBoxOption); 
  }
}

//this function lets the user know if the upload failed or not
function successMess(returnText) {
    var div = document.getElementById('output');
    div.innerHTML = '<p>'+returnText+'</p>';
}
</script>
</head>
<body>
<form id="myForm">
<p>Please choose a folder to receive the upload</p>
<select name="folder" id="folder">
<option value="Test Value">Test Value</option>
</select>
<br>
  <input name="myFile" type="file" id="myFile"/>
  <br>
  <input type="button" value="Submit"
      onclick="google.script.run.withSuccessHandler(successMess).processForm(this.parentNode)" />
</form>
<div id="output"></div>
</body>
</html>

Here is the accompanying JavaScript (.gs):

function doGet(){
  return HtmlService.createHtmlOutputFromFile('index');
}

function processForm(formObject) {
  var formBlob = formObject.myFile;
  var folderName = formObject.folder;
  var returnText = 'Please choose a valid file to upload';
  if(formBlob.length > 0){
    returnText = 'Your document was uploaded successfully!';
    try{
      var folder = DriveApp.getFoldersByName(folderName).next();
      var driveFile = folder.createFile(formBlob);
    }catch(e){
      returnText = 'There was an error processing your document';
    }
  }
  return returnText;
}

function getFolderList(){
  Logger.log('getFolderList was called');
  var ParentFolder = DriveApp.getFoldersByName('Test Folder').next();
  var shopFolders = ParentFolder.getFolders();
  var folderList = [];
  while(shopFolders.hasNext()){
    folderList.push(shopFolders.next().getName());
  }
  folderList.sort();
  return folderList;
}

Everything is working beautifully...except the folder list population. I have manually populated the select options just to make sure the processForm function is working correctly. I have even tested (using another alert) to make sure that the folder name array from "getFolderList()" is being passed faithfully (and it is). It doesn't seem to have any problems getting the select item called "folder" or creating a new "option" item. It seems to fail when "addItems" tries to add the option to the list. Can anyone tell me what I'm doing wrong, and/or how to fix it?

Thanks!

1

1 Answers

1
votes

Here is a solution to your problem:

<!DOCTYPE html>
<html>
<head>

</head>
<body>
<form id="myForm">
<p>Please choose a folder to receive the upload</p>
<select name="folder" id="fldrList">
<option value="Test Value">Test Value</option>
</select>
<br>
  <input name="myFile" type="file" id="myFile"/>
  <br>
  <input type="button" value="Submit"
      onclick="google.script.run.withSuccessHandler(successMess).processForm(this.parentNode)" />
</form>
<div id="output"></div>
</body>

<script type="text/javascript">
// The code in these functions run when the page is loaded.
  google.script.run.withSuccessHandler(addItems).getFolderList();

//This function uses an array of folder names to create options for the select list
function addItems(folders){
  console.log('addItems was called!' + folders);
  var htmlSelect = document.getElementById('fldrList');
  console.log('htmlSelect: ' + htmlSelect);

  var optionHTML = '';

  for(var z = 0; z < folders.length; z++){
    console.log('z: ' + z);
    console.log('folders[z]: ' + folders[z]);
    optionHTML = optionHTML + "<option value='" + folders[z] + "'>" + folders[z] + "</option>";
  };
  htmlSelect.innerHTML = optionHTML;
}

//this function lets the user know if the upload failed or not
function successMess(returnText) {
    var div = document.getElementById('output');
    div.innerHTML = '<p>'+returnText+'</p>';
}
</script>

</html>

Change the id name of your select element from folder to fldrList.

Unfortunately, the add method is not working. You can create the HTML in the form of a string and inject it.

Notice that the FOR LOOP creates an HTML string, then when the FOR LOOP is done, the HTML is injected into the SELECT element. It works. For some reason, Apps Script doesn't seem to be allowing the .add method. Don't know why.