如何使提交功能以使用Google Apps脚本创建并嵌入在Google站点中的Web表单中?

发布于 2025-02-01 13:05:38 字数 5118 浏览 4 评论 0原文

我想将使用Google Apps脚本创建的Web嵌入到Google站点中。但是,表格中的数据提交按钮已停用,当表单嵌入Google站点中时,例如这个

在Web表单中,将访问者输入数据到由index.html产生的表单,并在数据提交后,请参见result.htmlindex.html中有一个内部链接可以连接标头及其相关内容。表单应用程序未嵌入任何其他网站时成功起作用。请参阅

有人告诉我我想念什么吗?

MWE

我在Google Apps脚本的同一项目中有四个文件:

  1. index.html 生成表单
  2. javascript.html 定义index.html中使用的函数
  3. result.html 在表单提交
  4. code.gs 之后呈现出现 通过doget()显示表单,并处理提交的数据和呈现restect.html by dopost()代码>。 inclage()在此文件中定义的启用javascript.html in index.html

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <!-- <?!= include("css"); ?> -->
  </head>

  <body onload="addOptions()">   <!--Execute addOptions function immediately after a page has been loaded-->
    <form class="" action="<?!= getScriptUrl(); ?>" method="post" onSubmit="document.getElementById('submit').disabled=true;">
      <div>
        <h1 id="Question">
          Choose either cheesecake or chocolate cake.
        </h1>
          <select id="dropdownList" name="cake" class="form-control"> 
          </select>
      </div>
      <p>
        <div style="width:100px;height:500px;border:1px solid #000;">
          Blank box to scroll down
        </div>
      </p>
      <p>
        Please do not forget what you've answered in the <a href="#Question" target="_self">question<a>
      </p>
      <div class="form-submit">
        <input type="submit" name="" value="Submit">
      </div>
    </form>
  </body>
  <?!= include('JavaScript') ?>
</html>

<代码> javascript.html

<script>
  function addOptions() {
    /*This will call server-side Apps Script function getAvailableExps and if it is successful, 
    it will pass the return value to function addListValues which will add options to the drop down menu*/
    google.script.run
      .withFailureHandler(onFailure)
      .withSuccessHandler(addListValues)
      .getAvailableExps();
  }

  function addListValues(values) { 
    //Add options to drop down menu using the values of parameter 'values'.     
    for (var i = 0; i < values.length; i++) {
      var option = document.createElement("option");
      option.text = values[i][0];
      option.value = values[i][0];
      var select = document.getElementById("dropdownList");
      select.appendChild(option);
    }
  }

  function onFailure(err) {
    alert('Error: ' + err.message);
  }
</script>

result.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <base />
    <title>Thank you for your order!</title>
    <!-- <?!= include('css'); ?> -->
  </head>
  <body>
    <p>
      Don't forget what you've ordered!
    </p>
  </body>
</html>

code.gs

var sheetID = "............................................";
var inventory_sheet = "Inventory";

function doGet(){
  PropertiesService.getScriptProperties().setProperty("key", "sample");
  return HtmlService.createTemplateFromFile("index").evaluate();
}

function include(filename){
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}

function getScriptUrl() {
  var url = ScriptApp.getService().getUrl();
  Logger.log(url);
  return url;
}

function doPost(e){
  var p = PropertiesService.getScriptProperties();

  if (p.getProperty("key") == "sample") {

    var ss = SpreadsheetApp.openById(sheetID);
    var sh = ss.getSheets()[0];
    sh.appendRow([String(e.parameters.cake)]);

    //update Inventory
    var inventory = ss.getSheetByName(inventory_sheet);
    var row = inventory.createTextFinder(e.parameters.cake).findNext().getRow();
    var range = inventory.getRange(row, 2);
    var data = range.getValue();
    range.setValue(parseInt(data - 1))

    p.deleteProperty("key");
  }

  return HtmlService.createTemplateFromFile("result").evaluate(); 
  
}

function getAvailableExps(){
  var inventory = SpreadsheetApp.openById(sheetID).getSheetByName(inventory_sheet);
  var data =  inventory.getRange(2, 1, 2, 2).getValues();
  var filtered = data.filter(arr =>  arr[1] > 0 || arr[1] != ''); //remove exp to array if quantity is 0 or empty
  return filtered;
}

I want to embed a web created using Google Apps Script to a Google Site. However, data submission button in the form comes to be defunct, when the form is embedded in a Google Site like this.

In the web form, form visitors input data to the form produced by index.html and see result.html after data submission. There is an internal link in index.html to connect a header and its related contents. The form app successfully works when it is not embedded in any other site. See the form app and you will find the data submission button works fine.

Does anybody tell me what I am missing?

MWE

I have four files in the same project of Google Apps Script:

  1. index.html that produces the form
  2. JavaScript.html that defines functions used in index.html
  3. result.html that is presented after the form submission
  4. code.gs that shows the form by doGet(), and processes the submitted data and presents result.html by doPost(). include() defined in this file enables to input JavaScript.html into index.html

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <!-- <?!= include("css"); ?> -->
  </head>

  <body onload="addOptions()">   <!--Execute addOptions function immediately after a page has been loaded-->
    <form class="" action="<?!= getScriptUrl(); ?>" method="post" onSubmit="document.getElementById('submit').disabled=true;">
      <div>
        <h1 id="Question">
          Choose either cheesecake or chocolate cake.
        </h1>
          <select id="dropdownList" name="cake" class="form-control"> 
          </select>
      </div>
      <p>
        <div style="width:100px;height:500px;border:1px solid #000;">
          Blank box to scroll down
        </div>
      </p>
      <p>
        Please do not forget what you've answered in the <a href="#Question" target="_self">question<a>
      </p>
      <div class="form-submit">
        <input type="submit" name="" value="Submit">
      </div>
    </form>
  </body>
  <?!= include('JavaScript') ?>
</html>

JavaScript.html

<script>
  function addOptions() {
    /*This will call server-side Apps Script function getAvailableExps and if it is successful, 
    it will pass the return value to function addListValues which will add options to the drop down menu*/
    google.script.run
      .withFailureHandler(onFailure)
      .withSuccessHandler(addListValues)
      .getAvailableExps();
  }

  function addListValues(values) { 
    //Add options to drop down menu using the values of parameter 'values'.     
    for (var i = 0; i < values.length; i++) {
      var option = document.createElement("option");
      option.text = values[i][0];
      option.value = values[i][0];
      var select = document.getElementById("dropdownList");
      select.appendChild(option);
    }
  }

  function onFailure(err) {
    alert('Error: ' + err.message);
  }
</script>

result.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <base />
    <title>Thank you for your order!</title>
    <!-- <?!= include('css'); ?> -->
  </head>
  <body>
    <p>
      Don't forget what you've ordered!
    </p>
  </body>
</html>

code.gs

var sheetID = "............................................";
var inventory_sheet = "Inventory";

function doGet(){
  PropertiesService.getScriptProperties().setProperty("key", "sample");
  return HtmlService.createTemplateFromFile("index").evaluate();
}

function include(filename){
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}

function getScriptUrl() {
  var url = ScriptApp.getService().getUrl();
  Logger.log(url);
  return url;
}

function doPost(e){
  var p = PropertiesService.getScriptProperties();

  if (p.getProperty("key") == "sample") {

    var ss = SpreadsheetApp.openById(sheetID);
    var sh = ss.getSheets()[0];
    sh.appendRow([String(e.parameters.cake)]);

    //update Inventory
    var inventory = ss.getSheetByName(inventory_sheet);
    var row = inventory.createTextFinder(e.parameters.cake).findNext().getRow();
    var range = inventory.getRange(row, 2);
    var data = range.getValue();
    range.setValue(parseInt(data - 1))

    p.deleteProperty("key");
  }

  return HtmlService.createTemplateFromFile("result").evaluate(); 
  
}

function getAvailableExps(){
  var inventory = SpreadsheetApp.openById(sheetID).getSheetByName(inventory_sheet);
  var data =  inventory.getRange(2, 1, 2, 2).getValues();
  var filtered = data.filter(arr =>  arr[1] > 0 || arr[1] != ''); //remove exp to array if quantity is 0 or empty
  return filtered;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白鸥掠海 2025-02-08 13:05:38

问题和解决方法:

我认为,在您的情况下,使用您的显示脚本很难直接实现您的目标。 古斯塔沃的评论

当我看到您的评论,似乎您需要在Google方面运行Web应用程序。

在这种情况下,我认为可能需要使用解决方法。在此答案中,为了实现您的目标,我想提出解决方法。这种解决方法的重点如下。

  • 在您的脚本中,&lt; select ID =“下拉列表” name =“ cake” class =“ form-control”&gt;&lt;/select&gt;发送到dopost 使用action =“&lt;?!= getScriptUrl();?&gt;”方法=“ post”表格。
  • 在此解决方法中,该值使用google.script.run发送到Google Apps脚本。并且,在完全提交该值后,HTML主体被result.html覆盖。

当这一点反映在您的脚本中时,如下所示。

修改后的脚本:

index.html

请修改index.html,如下所示。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <!-- <?!= include("css"); ?> -->
  </head>
  <body id="body" onload="addOptions()">
    <form id="form">
      <div>
        <h1 id="Question">
          Choose either cheesecake or chocolate cake.
        </h1>
          <select id="dropdownList" name="cake" class="form-control"> 
          </select>
      </div>
      <p>
        <div style="width:100px;height:500px;border:1px solid #000;">
          Blank box to scroll down
        </div>
      </p>
      <p>
        Please do not forget what you've answered in the <a href="#Question" target="_self">question<a>
      </p>
      <div class="form-submit">
        <input type="submit" name="" value="Submit" onclick="sample(this);return false;">
      </div>
    </form>
  </body>
  <?!= include('JavaScript') ?>
</html>

javascript.html

请在javascript.html中添加以下功能。

function sample(e) {
  const f = document.getElementById("form");
  const obj = { parameters: [...f].reduce((o, g) => (o[g.name] = [g.value], o), {}) };
  google.script.run
    .withSuccessHandler((res) => {
      document.getElementById("body").innerHTML = res;
    })
    .sample(obj);
}
  • 在此示例脚本中,为了直接使用您的dopost,准备了obj的值。请注意。

code.gs:Google Apps脚本端,

请添加以下功能code.gs。此功能使用您的Dopost

function sample(e) {
  return doPost(e).getContent();
}

测试:

当您的脚本中反映此修改并将Web应用程序嵌入到Google站点中时,当单击“提交”按钮时,Cake的值将发送到Google Apps脚本side和result.html 显示。我认为这种情况可能是您的预期结果。

注意:

  • 此修改是解释解决方法的简单修改。因此,请为您的实际情况进行修改。

  • 修改Google Apps脚本时,请将部署修改为新版本。这样,修改后的脚本反映在Web应用程序中。请小心。

  • 请 重新启动Web应用程序而无需更改新IDE的Web应用程序的URL 。

  • 关于Web应用程序在Google站点上的内部链接时,似乎嵌入Web应用程序的WARE页面并未显示滚动条时,内部链接不起作用。当显示框架的滚动栏时,链接起作用。在这种情况下,似乎无法使用HTML和JavaScript来使用内部链接。而且,我无法确认错误消息。

Issue and workaround:

I think that in your situation, your goal is difficult to be directly achieved using your showing script. The reason for this has already been mentioned in Gustavo's comment.

When I saw your comment, it seems that you are required to run the Web Apps on the Google side.

In this case, I thought that a workaround might be required to be used. In this answer, in order to achieve your goal, I would like to propose a workaround. The point of this workaround is as follows.

  • In your script, the value of <select id="dropdownList" name="cake" class="form-control"></select> is sent to doPost using action="<?!= getScriptUrl(); ?>" method="post" of the form.
  • In this workaround, the value is sent to Google Apps Script using google.script.run. And, after the value was completely submitted, the HTML body is overwritten by result.html.

When this point is reflected in your script, it becomes as follows.

Modified script:

index.html

Please modify index.html as follows.

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <!-- <?!= include("css"); ?> -->
  </head>
  <body id="body" onload="addOptions()">
    <form id="form">
      <div>
        <h1 id="Question">
          Choose either cheesecake or chocolate cake.
        </h1>
          <select id="dropdownList" name="cake" class="form-control"> 
          </select>
      </div>
      <p>
        <div style="width:100px;height:500px;border:1px solid #000;">
          Blank box to scroll down
        </div>
      </p>
      <p>
        Please do not forget what you've answered in the <a href="#Question" target="_self">question<a>
      </p>
      <div class="form-submit">
        <input type="submit" name="" value="Submit" onclick="sample(this);return false;">
      </div>
    </form>
  </body>
  <?!= include('JavaScript') ?>
</html>

JavaScript.html

Please add the following function to JavaScript.html.

function sample(e) {
  const f = document.getElementById("form");
  const obj = { parameters: [...f].reduce((o, g) => (o[g.name] = [g.value], o), {}) };
  google.script.run
    .withSuccessHandler((res) => {
      document.getElementById("body").innerHTML = res;
    })
    .sample(obj);
}
  • In this sample script, in order to directly use your doPost, the value of obj is prepared. Please be careful about this.

Code.gs: Google Apps Script side

Please add the following function to Code.gs. This function use your doPost.

function sample(e) {
  return doPost(e).getContent();
}

Testing:

When this modification is reflected in your script and your Web Apps is embedded to a Google site, when the submit button is clicked, the value of cake is sent to the Google Apps Script side and result.html is displayed. I thought that this situation might be your expected result.

Note:

  • This modification is a simple modification for explaining the workaround. So, please modify this for your actual situation.

  • When you modified the Google Apps Script, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful this.

  • You can see the detail of this in the report of "Redeploying Web Apps without Changing URL of Web Apps for new IDE".

  • About the internal link of the Web Apps on Google site, it seems that when the while page of Web Apps is embedded and the scrollbar is not shown, the internal link doesn't work. When the scrollbar of the frame is shown, the link works. In this case, it seems that the internal link cannot be worked using both HTML and Javascript. And, I cannot confirm the error message.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文