- You want to send values at HTML side to Google Apps Script side using
google.script.run()
.
If my understanding is correct, how about this modification? Please think of this as just one of several answers.
At first, about your following issue, I think that the reason of your issue is that google.script.run()
works by the asynchronous processing.
Magically, after the For loop finishes, the GS function starts populating relevant cells (somehow it remembers all the dynamic values). However, not all expected cells get populated and also not in the correct order.
In order to avoid this, I think that there are 2 patterns for your situation.
Pattern 1:
In this pattern, after all values are retrieved, the values are sent to Google Apps Script. When you test this pattern, please modify as follows.
Google Apps Script:
function rolesInputer(values){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
sheet.getRange(17, 3, 1, values.length).setValues([values]);
}
HTML and Javascript:
I used <select>...</select>
as the sample values. In this sample, when the HTML is opened, the script is run.
<select id="role1"><option value="role1" selected>role1</option></select>
<select id="role2"><option value="role2" selected>role2</option></select>
<select id="role3"><option value="role3" selected>role3</option></select>
<select id="role4"><option value="role4" selected>role4</option></select>
<select id="role5"><option value="role5" selected>role5</option></select>
<script>
function saveInput() {
var dataEncoded = 5;
var values = [];
for (var i = 1; i <= dataEncoded; i++) {
var temprole = "role" + (i);
var roleSelect = document.getElementById(temprole);
var roleSelected = roleSelect.options[roleSelect.selectedIndex].value;
values.push(roleSelected);
}
google.script.run.withSuccessHandler(() => {google.script.host.close()}).rolesInputer(values);
}
saveInput();
</script>
Pattern 2:
In this pattern, the value is sent every one value to Google Apps Script using the for loop. When you test this pattern, please modify as follows.
Google Apps Script:
In this pattern, Google Apps Script is not modified.
HTML and Javascript:
In this sample, when the HTML is opened, the script is run.
<select id="role1"><option value="role1" selected>role1</option></select>
<select id="role2"><option value="role2" selected>role2</option></select>
<select id="role3"><option value="role3" selected>role3</option></select>
<select id="role4"><option value="role4" selected>role4</option></select>
<select id="role5"><option value="role5" selected>role5</option></select>
<script>
function work(roleSelected, i) {
return new Promise((resolve, reject) => {
google.script.run.withSuccessHandler(() => resolve()).rolesInputer(roleSelected, i);
});
}
async function saveInput() {
var dataEncoded = 5;
for (var i = 1; i <= dataEncoded; i++) {
var temprole = "role" + (i);
var roleSelect = document.getElementById(temprole);
var roleSelected = roleSelect.options[roleSelect.selectedIndex].value;
await work(roleSelected, i);
}
}
saveInput().then(() => google.script.host.close());
</script>
Note:
- When the process cost is thought, I think that the pattern 1 is better.
References:
- google.script.run
google.script.run is an asynchronous client-side JavaScript API available in HTML-service pages that can call server-side Apps Script functions.
If this was not useful for your situation, I apologize.