0

I have created a HTML dialog box (with help from the community) that will add items to specific categories in a data set based on the user input. I am now working on a dialog box to prompt the user to delete an item in the data set based on the same criteria.

I have tried "backward engineering" the code I have for adding items to the data set, but this is the first time I have delved into adding HTML dialog boxes to my spreadsheet and as such I am very rusty in understanding how it interacts with the .gs script file. I've searched through potentially relevant questions on Stack Overflow, but only found one that seemed relevant to me.

So far, I have created a HTML dialog box that asks the user to select the Region from a drop down - this then determines which column of the spreadsheet tab I place into the variable - as the code outlines. I added some Logger.log to check that the data was being collected properly.

I only learnt about <? ?> scriptlets today, and I'm not sure if I'm using them correctly. I haven't done very much with arrays, so I'm also unsure if this is how they're supposed to be recalled (I understand I would need to set up a loop to create the drop down options, but I'm just trying to get something to work).

Ideally the options drop down would appear in the existing dialog box created from the removeDeckSelectRegion.html file, but I am unsure how to do that. The first dialog box isn't closing, nor is the second one opening at the moment.

Demo Spreadsheet

Code & HTML to add decks (works fine)

function addDeck() {
  //Open a dialog
  var htmlDlg = HtmlService.createHtmlOutputFromFile('addDeck')
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setWidth(180)
      .setHeight(150);
  SpreadsheetApp.getUi().showModalDialog(htmlDlg, 'Add a New Deck');
}


function functionToRunOnFormSubmit(fromInputForm) {
  var decks = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Decks");

  for (var i = 4; i >= 1; i++) {
    if (decks.getRange(i, 1).getValue() == "") {
      break
    }
  }
  decks.getRange(i, 1, 1, 2).setValues([[fromInputForm.Class, fromInputForm.Archetype]]);
}

AddDeck.HTML

<!DOCTYPE html>
<html>
<body>
<form>
  <select name="Class" id="class-selector" autofocus="autofocus" autocorrect="off" autocomplete="off">
    <option value="" selected="selected">Class</option>
    <option value="Druid">Druid</option>
    <option value="Hunter">Hunter</option>
    <option value="Mage">Mage</option>
    <option value="Paladin">Paladin</option>
    <option value="Priest">Priest</option>
    <option value="Rogue">Rogue</option>
    <option value="Shaman">Shaman</option>
    <option value="Warlock">Warlock</option>
    <option value="Warrior">Warrior</option>
  </select>

  <input name="Archetype" type="text">

  <input type="submit" value="Submit" onclick="addDeck(this.parentNode)">
</form>
<p id="addDeck"></p>

<script>
function addDeck(obj) {
  var x = document.getElementById("class-selector").value;
  google.script.run
    .withSuccessHandler(() => google.script.host.close())
    .functionToRunOnFormSubmit(obj);
}
</script>
</body>
</html>

Code to remove decks (not working)

function removeDeck() {
  //Open a dialog
  var htmlDlg = HtmlService.createHtmlOutputFromFile('removeDeckSelectRegion')
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setWidth(180)
      .setHeight(150);
  SpreadsheetApp.getUi().showModalDialog(htmlDlg, 'Select Region');
}


function functionToRunToRemoveDeckSelectRegion(fromInputForm) {
  var decks   = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Decks");
  var lastRow = decks.getLastRow();

  if (fromInputForm.Region == "Americas") {
    var existingDecks = decks.getRange(4, 2, lastRow-3, 1).getValues();
  }

  Logger.log(existingDecks);
  Logger.log("-----------");

  for (var i = 0; i < existingDecks.length; i++) {
    Logger.log(existingDecks[i][0]);
  }

  var htmlDlg2 = HtmlService.createHtmlOutputFromFile('removeDeck')
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setWidth(180)
      .setHeight(150);
  SpreadsheetApp.getUi().showModalDialog(htmlDlg, 'Select Deck');
}

removeDeckSelectRegion.html

<!DOCTYPE html>
<html>
<body>
<form>
  <select name="Region" id="region-selector" autofocus="autofocus" autocorrect="off" autocomplete="off">
    <option value="" selected="selected">Region</option>
    <option value="Americas">Americas</option>
    <option value="Europe">Europe</option>
    <option value="Asia">Asia</option>
  </select>

  <input type="submit" value="Submit" onclick="removeDeckSelectRegion(this.parentNode)">
</form>
<p id="removeDeckSelectRegion"></p>

<script>
function removeDeckSelectRegion(obj) {
  var x = document.getElementById("region-selector").value;
  google.script.run
    .withSuccessHandler(() => google.script.host.close())
    .functionToRunToRemoveDeckSelectRegion(obj);
}
</script>
</body>
</html>

removeDeck.html

<!DOCTYPE html>
<html>
<body>
<form>
  <select name="Deck" id="deck-selector" autofocus="autofocus" autocorrect="off" autocomplete="off">
    <option value="" selected="selected">Deck</option>
    <option value="<? existingDecks[1][0] ?>"><? existingDecks[1][0] ?></option>
    <option value="<? existingDecks[2][0] ?>"><? existingDecks[2][0] ?></option>
    <option value="<? existingDecks[3][0] ?>"><? existingDecks[3][0] ?></option>
  </select>

  <input type="submit" value="Submit" onclick="removeDeck(this.parentNode)">
</form>
<p id="removeDeck"></p>

<script>
function removeDeck(obj) {
  var x = document.getElementById("deck-selector").value;
  google.script.run
    .withSuccessHandler(() => google.script.host.close())
    .functionToRunToRemoveDeck(obj);
}
</script>

</body>
</html>
tehhowch
  • 9,645
  • 4
  • 24
  • 42
Aaron Irvine
  • 343
  • 3
  • 13
  • If you're referring to the for loop in the macros.gs then that works perfectly fine - that's used for adding items to the list. Being unsure of how to add the existing items to the HTML drop down I don't have a for loop written for that. – Aaron Irvine Apr 06 '19 at 19:07
  • As far as reading the sheet data to make your HTML for removal, you can use the same process as you do for adding one - call some function that returns HTML. Have you read about Apps Script templated HTML? There are many questions already about displaying sheet data in HTML, almost any of them are pertinent. Just remember your sheet data comes out as a "2d array" and then use what you know about working with JavaScript arrays – tehhowch Apr 06 '19 at 19:15
  • Here's an example with a select inside a form https://stackoverflow.com/a/55524415/7215091 – Cooper Apr 06 '19 at 21:49
  • Thanks for your reply tehhowch, I'll try and find further information on Apps Script templated HTML. I seem to get stuck on simple syntax issues which is really frustrating :( – Aaron Irvine Apr 07 '19 at 02:52
  • Cooper that code is amazing! O_O My code for adding data to the spreadsheet via dialog is a lot more simple than this (as can be seen), but it is working. What I'm struggling with is populating a drop down in a dialog with data from the spreadsheet. Thanks for commenting! – Aaron Irvine Apr 07 '19 at 02:57
  • tehhowch - I only need it to be a 1D array as I just want to retrieve the `fromInputForm.Archetype` data – Aaron Irvine Apr 07 '19 at 03:31
  • Still struggling with this one - I've added an update at the bottom of the question to show my (lack of) progress. – Aaron Irvine Apr 07 '19 at 12:14
  • 1
    @aaron, oddly enough we don't need more working code from you; we need to see 1) how the user invokes the HTML form that should display `Range` contents, and 2) how you have attempted to build the `` from that `Range`. – tehhowch Apr 07 '19 at 13:28
  • @tehhowch sorry I have tidied it up and updated to where I am currently at. Just wanted to show that I am doing my best to try and find a solution and not just relying on the community to write the code for me. Thank you – Aaron Irvine Apr 07 '19 at 14:55
  • To reiterate the user invokes the function by clicking on the blue icon on the attached spreadsheet tab that looks similar to this: https://lennox-addington.on.ca/sites/default/files/2017-04/no%20signs.jpg – Aaron Irvine Apr 07 '19 at 17:16
  • @aaron probably you want to just send the `existingDecks` array back to your `removeDeckSelectRegion` dialog, and use the success handler there to create your new form (instead of closing the dialog) by constructing the HTML string and replacing the `
    ` with a new one (i.e. [overwrite its `outerHTML`](https://stackoverflow.com/a/9843436/9337071) or just its `innerHTML` as needed). This avoids attempting to close a UI dialog just to open a new one. As far as using the scriptlets, those are for `HtmlTemplate` objects (your code directly jumps to `HtmlOutput` objects).
    – tehhowch Apr 07 '19 at 19:48

0 Answers0