谷歌表从下拉列表中返回值并创建新行

时间:2020-07-17 22:30:27

标签: javascript html google-apps-script google-sheets

我正在尝试从Google表格创建html弹出窗口,该弹出窗口从下拉列表中返回所选选项。我创建了html窗口,将其传递给变量数组并将其转换为选项。现在,我需要将选择内容传递回GAS,并使用GAS在工作表上创建新行。这是我正在使用的GAS代码和HTML文件:

//Add Standing Order
function addSO() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    ss.setActiveSheet(ss.getSheetByName("Customers"));
    var sheet = ss.getSheetByName("Customers"); 
    var list  = sheet.getRange("A:A").getValues();
    var values  = list.toString().split(",");
    var values = JSON.stringify(values);
    var sheet = ss.getSheetByName("ResourcesDONTTOUCH"); 
    var list  = sheet.getRange("H:H").getValues();
    var values1  = list.toString().split(",");
    var values1 = JSON.stringify(values1);
    var t = HtmlService.createTemplateFromFile('htmlAddSO'); // Modified
    t.values = [values]; // Added
    t.values1 = [values1]; //Added
      html = t.evaluate().setWidth(400).setHeight(300);
    SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
    .showModalDialog(html, 'Add New Standing Order');
}

//Write Standing Order
function writeSO(obj) {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    ss.setActiveSheet(ss.getSheetByName("Standing Orders"));
    var sheet = ss.getSheetByName("Standing Orders"); 
    sheet.appendRow([obj.selectCustomer, obj.selectProduct, obj.notes]);
}  
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
    <base target="_top">
  </head>
  <body>
 <form>
 <H2>Select Customer from list</H2>
 <select id="selectCustomer" name="selectCustomer">
    <option>Choose a Customer</option>
</select>
<H2>Select Product</H2>
 <select id="selectProduct" name="selectProduct">
    <option>Choose a Product</option>
</select>
<H2>Notes</H2>
<input type="text" size="50" name="notes" id="notes">
<br>
<br>
     <input type="button" value="OK" onClick="submitorder(this.parentNode);" />
</form>
<script>

var select = document.getElementById("selectCustomer");
var options = <?!= values ?>;
for(var i = 0; i < options.length; i++) {
    var opt = options[i];
    var el = document.createElement("option");
    el.textContent = opt;
    el.value = opt;
    select.appendChild(el);
}
var select = document.getElementById("selectProduct");
var options1 = <?!= values1 ?>;
for(var i = 0; i < options1.length; i++) {
    var opt = options1[i];
    var el = document.createElement("option");
    el.textContent = opt;
    el.value = opt;
    select.appendChild(el);
}

function submitorder(obj) {
 google.script.run
   .withSuccessHandler(function(){google.script.host.close();})
   .writeSO(obj);
      }
</script>
</body>
 </html>

对此的任何帮助都将非常有帮助。

TIA

编辑 我已经将代码片段更新为更紧密的工作版本,而以前则是一团糟。为了清楚起见,我需要能够将期权的价格和注释部分返回到GAS中,以便我可以在常规订单中创建并填写新行

目前,我已经从工作表中拉出了范围,拆分了范围并将其作为HTML中的选项显示。我也将其附加到行中,但是目前将其附加为空白,而不是使用html中选择的选项,它也不会拉“注释”。

我只需要将变量从html返回到GAS的正确方法。对于学习目的,对其工作原理的任何解释将不胜感激。

2 个答案:

答案 0 :(得分:2)

在您的模板中,建议将您的scriptlet(<? ?>标签)移出JavaScript并移入HTML。仅在极少数情况下,我发现JavaScript内需要使用Scriplet。这应该消除您尝试使用JSON.stringify(values)完成的所有操作。您应该能够只将值的数组放到模板上,而无需使用JSON。

使用google.script.run来调用服务器端函数以追加行。您可以将google.script.host.close用作成功处理程序。

模板:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
    <base target="_top">
  </head>
  <body>
 <form>
 <H2>Select Customer from list</H2>
 <select id="selectCustomer" name="selectCustomer">
    <option>Choose a Customer</option>
    <? customers.forEach(value => { ?>
         <option value="<?= value ?>"><?= value ?></option>
    <? }) ?>
</select>
<H2>Select Product</H2>
 <select id="selectProduct" name="selectProduct">
    <option>Choose a Product</option>
    <? products.forEach(value => { ?>
      <option value="<?= value ?>"><?= value ?></option>
    <? }) ?>
</select>
<H2>Notes</H2>
<input type="text" size="50" name="notes" id="notes">
<br>
<br>
<button>Submit</button>
</form>
<script>
document.querySelector('button').addEventListener("click", onsubmit);
const selectCustomer = document.querySelector("#selectCustomer");
const selectProduct = document.querySelector("#selectProduct");
const notes = document.querySelector('#notes');
function onsubmit() {
  google.script.run.withSuccessHandler(google.script.host.close).append({
    customer: selectCustomer.value,
    product: selectProduct.value,
    notes: notes.value
  });
}
</script>
</body>
</html>

服务器端代码:

//Add Standing Order
function addSO() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var customersSheet = ss.getSheetByName("Customers"); 
  var customers  = customersSheet
    .getRange("A:A")
    .getValues()
    .flat() // requires V8; turns nested arrays into single array
    .filter(value => value); // removes blanks
  var productsSheet = ss.getSheetByName("ResourcesDONTTOUCH");
  var products = productsSheet
    .getRange("H:H")
    .getValues()
    .flat()
    .filter(value => value);
  var template = HtmlService.createTemplateFromFile('htmlAddSO');
  template.customers = customers; // Should be an array of strings
  template.products = products; // Should be an array of strings
  var html = template.evaluate().setWidth(400).setHeight(300);
  SpreadsheetApp.getUi()
    .showModalDialog(html, 'Add New Standing Order');
}

function append(obj) {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    ss.setActiveSheet(ss.getSheetByName("Standing Orders"))
    var sheet = ss.getSheetByName("Standing Orders"); 
    sheet.appendRow([obj.customer, obj.product, obj.notes]);
}

答案 1 :(得分:0)

我使用了您的大部分代码,但做了一些如下所述的更改

GS:

function addSO() {
  var ss=SpreadsheetApp.getActive();
  var sh1=ss.getSheetByName("Sheet1");//modified sheet name 
  var values=sh1.getRange(1,1,sh1.getLastRow(),1).getValues().map(function(r){return r[0]});
  var sh2=ss.getSheetByName("Sheet2");//modified sheet name
  var values1=sh2.getRange(1,8,sh2.getLastRow(),1).getValues().map(function(r){return r[0]});
  var t=HtmlService.createTemplateFromFile('ah3');//modified html file name
  t.values='['+ values.join(',') + ']';//modified from original passwed as printed strings not arrays
  t.values1='['+ values1.join(',') + ']';//modified from original
  var html=t.evaluate().setWidth(400).setHeight(300);
  SpreadsheetApp.getUi().showModelessDialog(html, 'Add New Standing Order');//made modeless because it's easier for me to debug as I have debug tools avialable in sidebar
}

//Write Standing Order
function writeSO(obj) {
    var ss=SpreadsheetApp.getActive();
    var sheet = ss.getSheetByName("Sheet3"); 
    sheet.appendRow([obj.selectCustomer, obj.selectProduct, obj.notes]);
}  

HTML:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
    <base target="_top">
  </head>
  <body>
 <form>
 <H2>Select Customer from list</H2>
 <select id="selectCustomer" name="selectCustomer"></select>
<H2>Select Product</H2>
 <select id="selectProduct" name="selectProduct"></select>
<H2>Notes</H2>
<input type="text" size="50" name="notes" id="notes">
<br>
<br>
     <input type="button" value="OK" onClick="submitorder(this.parentNode);" />
</form>
<script>
  console.log('Globals');
  var options= <?!= values ?>;
  options.unshift('Choose a Customer');//I find this easier to put initial value in the array
  //console.log(options);
  var options1= <?!= values1 ?>;//these are passed as printed strings
  options1.unshift('Choose a Product');
  //console.log(options1);

  //added this function
  function updateSelect(vA,id){
      var id=id || 'selectCustomer';
      var select = document.getElementById(id);
      select.options.length = 0; 
      for(var i=0;i<vA.length;i++) {
        select.options[i] = new Option(vA[i],vA[i]);
      }
  }

//Runs after html is loaded in the page
window.onload=function() {
  updateSelect(options,'selectCustomer');
  updateSelect(options1,'selectProduct');
}

function submitorder(obj) {
 google.script.run
   .withSuccessHandler(function(){google.script.host.close();})
   .writeSO(obj);
      }
</script>
</body>
 </html>