1

To get around the fact you can't pop user dialogue windows on mobile devices, I have created a simple function which posts any error messages to a cell and waits for the user to check a checkbox to confirm they have read the message. Once the checkbox is checked, the message and the checkbox are removed:

function messageHandler (mssg, mssgType) {
  sheet.getRange('D7').setValue(mssg);
  sheet.getRange('I7').activate();
  sheet.getActiveRangeList().insertCheckboxes();
  /*while (sheet.getRange('I7').getValue() !== true) {
    window("checkbox value is "+sheet.getRange('I7').getValue());
    Utilities.sleep(3000);
  }*/
  do {
    window("checkbox value is "+sheet.getRange('I7').getValue());
    Utilities.sleep(3000);
  } while (sheet.getRange('I7').getValue() !== true);

  sheet.getRangeList(['D7','I7']).activate();
  sheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
}

As you can see, I tried both while and do loops, but in both cases, the value of the checkbox is always FALSE, even after checked by the user, so the function never completes.
Is the checkbox only ever evaluated once? Do I need to add a check to my onEdit() trigger?

4
  • 1
    "Is the checkbox only ever evaluated once?" - Yes, it runs server-side, so when you run your messageHandler function, it executes once on the server. This means that sheet.getRange('I7').getValue() only reads the value at the moment the script is executing. Commented Oct 30 at 11:39
  • Thanks for that. Feel free to post this as an answer and I'll mark it as such Commented Oct 30 at 11:58
  • The code runs a loop, so it will read the contents of cell I7 until the script times out. That's in 30 seconds or 6 minutes depending on context. But that's not a very good way to detect a checkbox click. Commented Oct 30 at 12:03
  • window and sheet are undefined. Commented Nov 7 at 17:59

2 Answers 2

2

Use a simple trigger, like this:

function messageHandler(mssg, mssgType) {
  sheet.getRange('D7').setValue(mssg);
  sheet.getRange('I7').insertCheckboxes();
}

function onEdit(e) {
  if (e?.value !== 'TRUE' || e.range.rowStart !== 7 || e.range.columnStart !== 10) return;
  sheet.getRangeList(['D7', 'I7']).clearContent();
}

Also see these onEdit(e) best practices.

Sign up to request clarification or add additional context in comments.

Comments

1

"Is the checkbox only ever evaluated once?" - Yes, it runs server-side, so when you run your messageHandler function, it executes once on the server. This means that sheet.getRange('I7').getValue() only reads the value at the moment the script is executing. Utilities.sleep(3000) pauses the server-side execution, but it doesn't allow updating in real time (so no interacting with the checkbox).

All this explains why the while or do-while loops never complete, the server never sees their updated value..

I would suggest using an onEdit() trigger (or adding functionality to your existing one) to detect the checkbox changes.

7 Comments

That's inaccurate. The code runs sheet.getRange('I7').getValue() in a loop, and will read the contents of cell I7 each time through the loop until the script times out. That's in 30 seconds or 6 minutes depending on context. Running a loop to find a checkbox value isn't a very good way to detect a checkbox click.
Yes, getValue() runs each loop, but the script runs server-side. The script can't actually "wait" for the user to check the box in real time. So even if you loop, it'll just keep reading the original value (FALSE) and never sees the update.
That continues to be inaccurate. Checkboxes are Boolean values. The values in the spreadsheet will change whenever any user who has access to the spreadsheet edits them, and those changes will be seen by a server-side script.
Server-side scripts can see cell changes, but a running function can't "pause" and wait for a user to check a box in real time. You can't interact with the checkbox and have the server see that change during the same script execution. When the user clicks on the checkbox, the script is either already timed out or still looping. You can see edits if a separate trigger/script reads the cell after the user has (un)checked, but it can't wait in the middle of a server-side function for that to happen.
Here's an example where the script runs for 30 seconds and changes you make to column B during that time are used by the script to impact the blinking cells. Blinking effect with script
Also, just to clarify, I didn't suggest using a loop, it's part of their code. I was just explaining why it didn't work and what would be a better approach.
"a running function can't "pause" and wait for a user to check a box" — of course it can, but that seldom makes sense. A running script can certainly sleep and then check on a spreadsheet cell value again. We're not talking about dialog boxes but spreadsheet cells here. Checkbox cells are values. See checkboxes. The code in the question won't work, of course, because it's attempting to call window(), which doesn't exist in pure JavaScript. I don't think this discussion is going anywhere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.