0
votes

I need to run through an array of roles and open a modal dialog (in HTML) for each. I had a problem where each next dialog gets opened before I close the previous dialog (because of asynchronous Google Script.

I have tried implementing a solution by setting a while loop for Utilities.sleep() and adding a global variable 'sleeping' that becomes false when the modal dialog is closed.

However, now only the first dialog opens and the code does not run through the full 'for' loop.

function nightStart(nightNumber, playersArray, roleList) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var range = sheet.getRange("Controls!G3:G1000");
  var wakeupOrder = [];
  var sleeping;
  var role;

//collecting the array to define in what order roles wake up
  for (var i = 1; i<=20; i++) {
    var cellValue = range.getCell(i,1).getValue();
    wakeupOrder.push(cellValue);
  }

//the FOR loop that I am trying to make work (open Dialog for each role)
  for (index in wakeupOrder) {
    role = wakeupOrder[index];
    if (roleList.indexOf(role) != -1) {
      sleeping = true;
      roleWakeUp(role, playersArray, roleList);
      do {
        Utilities.sleep(2000);
        //calling global sleeping parameter that is defined as FALSE in the 'nightTargetSelection' function        
        sleeping = PropertiesService.getScriptProperties().getProperty('sleeping'); 
      } while (sleeping != false);
    }
  }   
}



//below is the function that opens the modal dialog (but the server side code still keeps running).
function roleWakeUp (role, playersArray, roleList){    
  //I have removed all code from here for Stack Overflow. The only part that I believe is important is that it opens an HTML dialog with a form
  SpreadsheetApp.getUi().showModalDialog(actionInputDlg, wakeUpText);
}



//Below function is called by the client on HTML form submission. After this form is submitted I need the next dialog to open (i.e need the Utilities.sleep to stop running
function nightTargetSelection (selected, playerNumber){
  var sleeping = false;
  PropertiesService.getScriptProperties().setProperty('sleeping', sleeping);
}

I need an HTML dialog to open for each 'role' in the 'wakeupOrder' array (if the role exists in 'roleList'). Each next dialog needs to open only after the submission of the previous dialog.

1
I have to apologize. I noticed the error of the function name in my answer. So I modified it just now. Could you please confirm it?Tanaike

1 Answers

1
votes
  • You want to open several dialogs in order.
  • When the process is finished on a dialog, you want to open next dialog.
    • Namely, you don't want to open the next dialog before the current job is finished.

If my understanding is correct, how about this answer?

When SpreadsheetApp.getUi().showModalDialog() is opened in order, the dialog is overwritten. I think that this is the reason of your issue. So, here, I would like to introduce a sample script. In this sample script, the next dialog is opened from the current dialog. The flow of this sample script is as follows. Please think of this as just one of several answers.

  1. Open a dialog by running start().
  2. When "ok" button is clicked, the next dialog is opened by including the next job.
    • By this, each job can be completely done.
  3. When all jobs were finished, done() is run and the dialog is closed.

Sample script:

When you use this script, please copy and paste "Code.gs" and "index.html" to "script" and "HTML" on your script editor, respectively. And please run start(). This sample script supposes that you are using the container-bound script of Spreadsheet.

Code.gs: Google Apps Script

// When all jobs were finished, this function is called.
function done(e) {
  Logger.log(e)
}

// Open a dialog
function openDialog(jobs, i) {
  var template = HtmlService.createTemplateFromFile('index');
  template.jobs = JSON.stringify(jobs);
  template.index = i;
  SpreadsheetApp.getUi().showModalDialog(template.evaluate(), "sample");
}

// Please run this script
function start() {
  var jobs = ["sample1", "sample2", "sample3"];
  openDialog(jobs, 0);
}

index.html: HTML and Javascript

<div id="currentjob"></div>
<input type="button" value="ok" onclick="sample()">
<script>
  var jobs = JSON.parse(<?= jobs ?>);
  var index = Number(<?= index ?>);
  document.getElementById("currentjob").innerHTML= "currentJob: " + jobs[index] + ", index: " + index; 

  function sample() {
    if (index < jobs.length - 1) {
      google.script.run.openDialog(jobs, index + 1); // Modified
    } else {
      google.script.run.withSuccessHandler(()=>google.script.host.close()).done("Done.");
    }
  }
</script>

References:

Note:

  • This is a simple sample script. So please modify this for your situation.

If I misunderstood your question and this was not the result you want, I apologize.