4

Due to ongoing development versioning, plus seemingly insurmountable problems implementing user permissions workarounds, I need to capture form data linked to a sheet which is not exposd to the users. Instead I want to launch the form from a separate spreadsheet app using a custom menu. Yet despite thorough Google searches, and the tantalizingly named 'FormApp.openById' method, I can't find a way to accomplish this.

I know I'm off track here; could anyone please point me to the way back?

4

2 回答 2

12

第 1 步:创建表单

正常操作过程 - 通过脚本或使用表单 UI 创建表单。捕获表单的 ID。例如,在编辑器中从 URL:

https://docs.google.com/forms/d/1-AWccGNgdJ7_5Isjer5K816UKNSaUPSlvlkY3dGJ1UQ/edit
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

附加电子表格以捕获响应。(我们不会在这里做更多的事情。)

第 2 步:客户端脚本

在用户可访问的电子表格中,创建一个容器绑定脚本(以便它可以访问电子表格 UI)。以下脚本生成一个自定义菜单,其中包含一个在 Ui 弹出窗口中启动表单的选项。

/**
 * Uses the Forms service to get a handle on an existing form, then retrieve its published URL.
 * Uses the UrlFetch Service to get a copy of the HTML for the form.
 * Uses the HtmlService to embed the form's HTML in a Spreadsheet UI.
 * ... which is finally shown using Spreadsheet.show().
 */
function launchForm() {
  var formID = '1-AWccGNgdJ7_5Isjer5K816UKNSaUPSlvlkY3dGJ1UQ';
  var form = FormApp.openById(formID);
  var formUrl = form.getPublishedUrl();

  var response = UrlFetchApp.fetch(formUrl);
  var formHtml = response.getContentText();

  var htmlApp = HtmlService
      .createHtmlOutput(formHtml)
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setTitle('Ta Daaa!')
      .setWidth(500) 
      .setHeight(450);

  SpreadsheetApp.getActiveSpreadsheet().show(htmlApp);
}

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Launch Form",
    functionName : "launchForm"
  }];
  sheet.addMenu("Custom Menu", entries);
};

演示

这是您从“自定义菜单”中选择“启动表单”时看到的内容。不过,有点烦人——当表单被提交时,用户会被带到另一个浏览器窗口或选项卡。在电子表格中,UI 保持打开状态,需要手动关闭。IFRAME 沙盒解决了这个问题!

屏幕截图 - 嵌入式表单


编辑:最近引入了 ECMA 沙箱默认值的更改,这需要将沙箱模式显式设置为 NATIVE 才能使该技术起作用。代码已更新。

再次编辑:较新的 IFRAME 沙盒模式将整个表单体验保留在对话框中。

于 2013-06-17T20:36:26.547 回答
2

Mogsdad 让我走上了正轨,但为了让提交按钮起作用,我不得不将它直接嵌入到代码中。

1)创建一个表单,在表单菜单中,选择“在网页中嵌入表单”

2) 复制出现的整个代码块。它应该类似于:

<iframe src="https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true" width="500" height="450" frameborder="0" marginheight="0" marginwidth="0">Loading…&lt;/iframe>

3)将此功能添加到您的脚本页面

function launchForm() {
  var embeddedHtml = '<iframe src="https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true" width="500" height="450" frameborder="0" marginheight="0" marginwidth="0">Loading…&lt;/iframe>'
  var htmlApp = HtmlService.createHtmlOutput(embeddedHtml)
  SpreadsheetApp.getUi().showModalDialog(htmlApp, 'Title');
}

如果您希望保留表单的格式和横幅,请删除?embedded=true嵌入式链接https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true

于 2020-03-23T02:33:07.303 回答