【问题标题】:How to auto populate form options based on a column in the attached spreadsheet如何根据附加电子表格中的列自动填充表单选项
【发布时间】:2019-08-10 10:26:04
【问题描述】:

我创建了一个新的谷歌表来收集用户信息。在我的工作表脚本编辑器中,我创建了这个表单: https://script.google.com/macros/s/AKfycbz6uGmXfSiXg4lYseeX0IN7Qv_9eM4eN9knUtBm5Co/exec

上面的表格有一个选择题,我需要使用附加电子表格中的特定列自动填充该问题

我在下面的代码中使用了他,但由于某种原因更新功能没有读取表单选项或其他内容

当我运行更新表单函数时,它给出“TypeError: Cannot find function getItemById in object”

有没有办法通过工作表栏来更新表单选项

    function doGet() {
    return HtmlService.createTemplateFromFile('form.html')
        .evaluate() // evaluate MUST come before setting the Sandbox mode
        .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
    }


    function updateForm(){
    // call your form and connect to the drop-down item
    var form = ("https://script.google.com/macros/s/AKfycbz6uGmXfSiXg4lYseeX0IN7Qv_9eM4eN9knUtBm5Co/exec");

    var namesList = form.getItemById("890244015").asListItem();


    // identify the sheet where the data resides needed to populate the drop-down
    var ss = SpreadsheetApp.getActive();
    var names = ss.getSheetByName("CHOICES");

    // grab the values in the first column of the sheet - use 2 to skip header row 
    var namesValues = names.getRange(2, 16, names.getMaxRows() - 1).getValues();

    var studentNames = [];

    // convert the array ignoring empty cells
    for(var i = 0; i < namesValues.length; i++)    
    if(namesValues[i][0] != "")
      studentNames[i] = namesValues[i][0];

     // populate the drop-down with the array data
     namesList.setChoiceValues(studentNames);

     }

这是form.html代码:

<!DOCTYPE html>
<html>
<body>

<style>

body {
padding: 0px 0px 0px 0px;
margin: 0px 0px 0px 0px;
background-color: white;
}

</style>


<link href='/static/forms/client/css/3145455273- 
mobile_formview_st_ltr.css' type='text/css' rel='stylesheet' media='screen 
and 
(max-device-width: 721px)'>



<div class="ss-form-container">

<div class="ss-header-image-container"><div class="ss-header-image-image"> 
<div class="ss-header-image-sizer"></div></div></div>

<div class="ss-top-of-page"><div class="ss-form-heading"><h1 class="ss- 
form-title" dir="ltr">Test</h1>
<div class="ss-form-desc ss-no-ignore-whitespace" dir="ltr">WELD DATE 
00</div>

<div class="ss-required-asterisk" aria-hidden="true" id="Required">* 
Required</div></div></div>

<br><br>

<div class="ss-form">


<script type="text/javascript">var submitted=false;</script>
<iframe name="hidden_iframe" id="hidden_iframe" style="display:none;"     
onload="if(submitted) 
{window.location='https://sites.google.com/site/formredirection/';}"> 
</iframe>
  <form action="https://docs.google.com/forms/d/e/formid/formResponse" 
  method="post" target="hidden_iframe" 
 onsubmit="submitted=true;">


<div class="ss-form-question errorbox-good" role="listitem">
<div dir="auto" class="ss-item ss-item-required ss-select"><div class="ss- 
 form-entry">
<label class="ss-q-item-label" for="entry_890244015"><div class="ss-q- 
title">JOINT
<label for="itemView.getDomIdToLabel()" aria-label="(Required field)"> 
</label>
<span class="ss-required-asterisk" aria-hidden="true">*</span></div>
<div class="ss-q-help ss-secondary-text" dir="auto"></div></label>



<select name="entry.890244015" id="entry_890244015" aria-label="JOINT  " 
aria-required="true" required=""><option value=""></option>
<option value="OPTION 01">OPTION 01</option> <option value="OPTION 
02">OPTION 02</option> <option value="OPTION 03">OPTION 03</option> 
<option value="OPTION 04">OPTION 04</option></select>
</div></div></div>


<div class="ss-form-question errorbox-good" role="listitem">
<div dir="auto" class="ss-item ss-item-required ss-radio"><div class="ss- 
form-entry">
<label class="ss-q-item-label" for="entry_117174731"><div class="ss-q- 
title">REP NO.
<label for="itemView.getDomIdToLabel()" aria-label="(Required field)"> 
</label>
<span class="ss-required-asterisk" aria-hidden="true">*</span></div>
<div class="ss-q-help ss-secondary-text" dir="auto"></div></label>


<ul class="ss-choices" role="radiogroup" aria-label="REP NO.  "><li 
class="ss-choice-item">
<label><span class="ss-choice-item-control goog-inline-block"><input 
type="radio" name="entry.735659431" value="" id="group_735659431_1" 
role="radio" class="ss-q-radio" aria-label="" required="" aria- 
required="true"></span>
<span class="ss-choice-label"></span>
</label></li></ul>
<div class="error-message" id="117174731_errorMessage"></div></div></div> 
</div>



<div class="ss-form-question errorbox-good" role="listitem">
<div dir="auto" class="ss-item ss-item-required ss-date"><div class="ss- 
form-entry">
<label class="ss-q-item-label" for="entry_1715668372"><div class="ss-q- 
title">WELD DATE
<label for="itemView.getDomIdToLabel()" aria-label="(Required field)"> 
</label>
<span class="ss-required-asterisk" aria-hidden="true">*</span></div>
<div class="ss-q-help ss-secondary-text" dir="auto"></div></label>

<input type="date" name="entry.1715668372" value="" class="ss-q-date" 
dir="auto" id="entry_1715668372" aria-label="WELD DATE  " aria- 
required="true" required="">
</div></div></div>



<div class="ss-form-question errorbox-good" role="listitem">
<div dir="auto" class="ss-item ss-item-required ss-select"><div class="ss- 
form-entry">
<label class="ss-q-item-label" for="entry_1048274308"><div class="ss-q- 
title">WELDER
<label for="itemView.getDomIdToLabel()" aria-label="(Required field)"> 
</label>
<span class="ss-required-asterisk" aria-hidden="true">*</span></div>
<div class="ss-q-help ss-secondary-text" dir="auto"></div></label>

<select name="entry.1048274308" id="entry_1048274308" aria-label="WELDER  
" aria-required="true" required=""><option value=""></option>
<option value="WR 01">WR 01</option> <option value="WR 02">WR 02</option> 
<option value="WR 03">WR 03</option> <option value="WR 04">WR 04</option> 
</select>
</div></div></div>


<div class="ss-form-question errorbox-good" role="listitem">
<div dir="auto" class="ss-item ss-item-required ss-select"><div class="ss- 
form-entry">
<label class="ss-q-item-label" for="entry_1712008875"><div class="ss-q- 
title">WPS
<label for="itemView.getDomIdToLabel()" aria-label="(Required field)"> 
</label>
<span class="ss-required-asterisk" aria-hidden="true">*</span></div>
<div class="ss-q-help ss-secondary-text" dir="auto"></div></label>

<select name="entry.1712008875" id="entry_1712008875" aria-label="WPS  " 
aria-required="true" required=""><option value=""></option>
<option value="WPS 01">WPS 01</option> <option value="WPS 02">WPS 
02</option> <option value="WPS 03">WPS 03</option> <option value="WPS 
04">WPS 04</option></select>
</div></div></div>


<input type="hidden" name="draftResponse" value=" 
[null,null,&quot;-8333688893315580231&quot;]
">
<input type="hidden" name="pageHistory" value="0">



<input type="hidden" name="fbzx" value="-8333688893315580231">
<div class="ss-send-email-receipt" style="margin-bottom: 4px;" dir="ltr"> 
<label for="emailReceipt" style="display:inline;"></label></div>


<input type="submit" name="submit" value="Submit" id="ss-submit" 
class="jfk-button jfk-button-action "></form></div></div>

</body>
</html>

【问题讨论】:

  • getItemById()在哪里?
  • 感谢您对迈克的关注。在我的表单中访问选项列表的正确方法是什么??
  • @MikePoole 该问题使用 Google Apps Script 服务器端服务,因此不应使用 Stack Snippet,因为这些服务在此处无法执行。
  • 链接请求许可。无论如何,请改为包含客户端代码的minimal reproducible example
  • 提供minimal reproducible example。你的代码太长了,有很多问题不需要的东西。见this question。从头开始,只构建重现问题所必需的部分。

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


【解决方案1】:

a previous thread 上,您已经得到了有关如何创建 HTML 表单的答案。

在此问题的代码中,您尝试在字符串值上使用getItemById,但此方法来自Class Form。换言之,此方法应仅用于 Google 表单,而不应用于 Web 表单。使用其他方法(如 setChoiceValues)也会发生类似的情况。

要使用客户端代码从 Web 表单设置选项列表,您应该使用 DOM 方法,例如 querySelectorAllgetElementsByTagName 等。如果您需要从电子表格中获取选项,您可以使用服务器端代码,并且可以使用google.script.run 从客户端调用该代码。

有关 Google Apps Script Web 应用程序如何工作的概述,请阅读https://developers.google.com/apps-script/guides/web

相关

【讨论】:

  • 感谢 Ruben 的关注我正在尝试更改表单共享选项,但它一直给我一个错误我已经使用谷歌表单但我将源代码添加到应用程序脚本中以便我可以添加对其进行一些修改以下是我的 form.html 文件中的问题代码:
  • 如您所见,表单仍将结果提交到随附的 google sheet。那么你能给我一个关于如何使用 google.script.run 的例子吗?使用电子表格中的特定列自动更新上述列表项。提前致谢
  • @MahmoudBayoumi 关于你问的例子,请查看这个问题:stackoverflow.com/q/33701881/1595451
  • 非常感谢鲁本的努力。我检查了您发送的线程,在运行函数时仍然存在一些问题(无法获取 null 的 GetRange,无法获取 null 的 GetLastRaw 方法)请您提供更新我的应用程序脚本中选项列表所需的脚本,因为我是对java脚本不太熟悉。谢谢
  • 好的,现在我成功运行了函数(functionToRunOnFormSubmit),但仍然没有成功(genDiscRep);它给出了一个错误(范围内的行数必须至少为 1)
【解决方案2】:

考虑使用&lt;?= ?&gt;&lt;? ?&gt; scriptlets

这允许您访问 HTML 文件中的 Apps SCript 功能。

.gs 文件

function doGet() {  
  return HtmlService
      .createTemplateFromFile('index')
      .evaluate();
}

function createInnerHTML(){
    var ss = SpreadsheetApp.getActive();
    var names = ss.getSheetByName("CHOICES");
    var namesValues = names.getRange(2, 16, names.getMaxRows() - 1).getValues(); 
   return namesValues;
}

HTML 文件

<body>
...
<? var namesValues= createInnerHTML(); ?>  
<div>
<select name="entry.890244015" id="entry_890244015" aria-label="JOINT  " aria-required="true" required="">
<option value=""></option>
<option value="OPTION 01"><?= namesValues[0][0]?></option>
<option value="OPTION 02"><?= namesValues[1][0]?></option>
<option value="OPTION 03"><?= namesValues[2][0]?></option>
<option value="OPTION 04"><?= namesValues[3][0]?></option>
</select>
</div>
...
</body>

如果您的 HTML 框架是预先确定的(您事先知道您的下拉菜单将有 4 个选项),这是一个简单的解决方案。

如果你想动态调整选项的数量,一个更优雅的解决方案是:

.gs 文件

function doGet() {  
  return HtmlService
      .createTemplateFromFile('index')
      .evaluate();
}

function createInnerHTML()
{
    var ss = SpreadsheetApp.getActive();
    var names = ss.getSheetByName("CHOICES");
    var namesValues = names.getRange(2, 16, names.getMaxRows() - 1).getValues(); 
    var InnerHTML = [];
    for (var i=0;i<namesValues.length;i++){
      InnerHTML.push('<option value="OPTION '+(i+1)+'>' + namesValues[i][0]+ '</option>'; 
    }); 
   InnerHTML.join('');
   return InnerHTML;
  }

HTML 文件

<body>
...
<? var innerHTML= createInnerHTML(); ?>  
<div>
<select name="entry.890244015" id="entry_890244015" aria-label="JOINT  " aria-required="true" required="">
<option value=""></option>
//HERE the inner HTML will be inserted
<?= innerHTML?>
</select>
</div>
...
</body>

【讨论】:

  • 哇 Ziganotschka,第一个代码工作得很好,非常感谢你。动态代码在运行函数时没有给出任何错误,但是由于某种原因仍然无法工作,并且列表在表单中变为空。如果您能对此提供帮助,我将不胜感激。再次感谢
  • 顺便说一句,我刚刚添加了 doGet 函数并修复了一些语法错误,所以最后它变成了这样: function createInnerHTML() { var ss = SpreadsheetApp.getActive(); var 名称 = ss.getSheetByName("CHOICES"); var namesValues = names.getRange(2, 2, names.getMaxRows() - 1).getValues(); var InnerHTML = []; for (var i=0;i
    没错,我没有在示例中插入 doGet() 函数。现在,您添加了它 - 代码对您有用吗?
  • 第一个代码出现了另一个问题,工作表停止接收来自脚本编辑器中表单的任何新提交,但同时仍接收来自谷歌表单的新提交。有什么帮助吗??
  • Google 表单会自动将所有表单回复保存在目标电子表格中,但如果您创建手动表单,则必须自己处理。我建议您在公司中加入 一个 onchange 事件,该事件会触发手动 JS 保存功能运行。这里有一个如何实现它的想法:stackoverflow.com/a/57337242/11599789。我上面给你的示例只是sn-ps,要集成到你的项目中。
猜你喜欢
相关资源
最近更新 更多
热门标签