如何从使用 Google Apps 脚本部署的表单中排除已达到容量的选项

How to exclude an option that have reached capacity from the form deployed using Google Apps Script

我使用 Google 具有容量选项的 Apps 脚本创建了一个网络表单。

在下面的示例中,有一个问题要求访问者选择芝士蛋糕或巧克力蛋糕。假设我只有两块芝士蛋糕和三块巧克力蛋糕,如果两个访客已经​​选择了芝士蛋糕,我想从表单中删除芝士蛋糕选项,使该选项不可见,因此无法选择,显示选项只有巧克力蛋糕。

那么,这样一个select问题,其选项有能力使用Google Apps Script,我该如何实现?

请注意,但我想创建一个自定义 Web 表单,而且这次 我不为此目的使用 Google 表单

编辑

以下 link 将展示此程序如何在电子表格中保存数据:https://docs.google.com/spreadsheets/d/11nE1yL24HamfbAbeRjoQV6SE0ecq6rCx1WlbQZ8N8R0/edit?usp=sharing

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>

  <body>
    <form class="" action="<?!= getScriptUrl(); ?>" method="post">
      <div>
        <h1 id="Question">
          Choose either cheesecake or chocolate cake.
        </h1>

          <select id="" name="cake" class="form-control">
            <option value="cheesecake">cheesecake</option>
            <option value="chocolate_cake">chocolate_cake</option>
          </select>
      </div>

      <div class="form-submit">
        <input type="submit" name="" value="Submit">
      </div>
    </form>
  </body>
</html>

code.gs

function doGet(){

 return HtmlService.createTemplateFromFile("index").evaluate();

}

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

function doPost(e){

  var sh = SpreadsheetApp.openById("11nE1yL24HamfbAbeRjoQV6SE0ecq6rCx1WlbQZ8N8R0").getSheets()[0];

  sh.appendRow([String(e.parameters.cake)]);

  return HtmlService.createHtmlOutput('<b>Thank you!</b>');
}

我相信你的现状和目标如下。

  • 您的 HTML 包含在 Google Apps 脚本项目中。
  • 您想从 Spreadsheet 中检索值并将它们显示在下拉列表中。
  • 例如,有两块芝士蛋糕。当用户selects 芝士蛋糕并提交时,您想从 Spreadsheet.
  • 中的芝士蛋糕中减少 1
  • 当芝士蛋糕的数量是0时,你不想select它。

在这种情况下,下面的示例脚本怎么样?

传播样本sheet

在这个脚本中,为了测试,使用了下面的Spreadsheet。 sheet 是 Spreadsheet 的第一个标签。

示例脚本

请将以下脚本复制并粘贴到脚本编辑器中。并且,请将最新的脚本反映到 Web Apps

Google Apps 脚本端:Code.gs

var spreadsheetId = "###"; // Please set your Spreadsheet ID.

function updateValue(e) {
  var sheet = SpreadsheetApp.openById(spreadsheetId).getSheets()[0];
  var range = sheet.getRange("A2:B" + sheet.getLastRow());
  var values = range.getValues().map(([a, b]) => a == e ? [a, --b] : [a, b]);
  range.setValues(values);
  return values.map(([a, b]) => `<option value="${a}" ${b == 0 ? "disabled" : ""}>${a}</option>`).join("");
}

const doGet = () => {
  var sheet = SpreadsheetApp.openById(spreadsheetId).getSheets()[0];
  var [, ...values] = sheet.getDataRange().getValues();
  var v = values.map(([a, b]) => `<option value="${a}" ${b == 0 ? "disabled" : ""}>${a}</option>`).join("");
  var html = HtmlService.createTemplateFromFile("index.html");
  html.values = v || "";
  return html.evaluate();
}

HTML & Javascript 方:index.html

<!DOCTYPE html>
<html>

<head>
  <base target="_top">
</head>

<body>
  <form id="form">
    <div>
      <h1 id="Question">
        Choose either cheesecake or chocolate cake.
      </h1>

      <select id="sampleSelect" name="cake" class="form-control">
        <?!= values ?>
      </select>
    </div>

    <div class="form-submit">
      <input type="submit" value="Submit" onclick="saveValue(this);return false;">
    </div>
  </form>
  <script>
    function saveValue(e) {
      const v = document.getElementById("form").cake.value;
      google.script.run.withSuccessHandler(updated => {
        document.getElementById("sampleSelect").innerHTML = updated;
      }).updateValue(v);
    }
  </script>
</body>

</html>

测试

请访问修改后的脚本中反映的已部署的 Web 应用程序。这样,您就可以看到下拉列表了。

在这个例子中,cheesecake有2个。当你select一个cheesecake并点击“提交”按钮时,Spreadsheet上的cheesecake数量从2变成1。当你select cheesecake 再次点击按钮,可以确认cheesecake选项不能select编辑

我认为这可能是您的预期结果。

备注

  • 当您修改 Google Apps 脚本时,请将部署修改为新版本。这样,修改后的脚本就会反映在 Web Apps 中。请注意这一点。

  • 您可以在“Redeploying Web Apps without Changing URL of Web Apps for new IDE”的报告中看到详细信息。

  • 这个示例脚本是一个简单的脚本。所以,请根据您的实际情况进行修改。

参考

如果你想删除一个基于数量的选项,那么你应该将每个蛋糕的数量保存到Sheet。

我在这里修改了您的代码并添加了一些功能:

Code.gs:

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

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

function doPost(e){
  var ss = SpreadsheetApp.openById("insert sheet id here");
  var sh1 = ss.getSheets()[0];
  sh1.appendRow([String(e.parameters.cake)]);

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

  return HtmlService.createHtmlOutput('<b>Thank you!</b>'); 
  
}

function getAvailableFlavors(){
  var ss = SpreadsheetApp.openById("insert sheet id here");
  var sh = ss.getSheetByName("Inventory");
  var data =  sh.getRange(2, 1, 2, 2).getValues();
  var filtered = data.filter(arr =>  arr[1] > 0 || arr[1] != ''); //remove flavor to array if quantity is 0 or empty
  return filtered;
}

index.html:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>

  <body onload="addOptions()">   <!--Execute addOptions function immediately after a page has been loaded-->
    <form class="" action="<?!= getScriptUrl(); ?>" method="post">
      <div>
        <h1 id="Question">
          Choose either cheesecake or chocolate cake.
        </h1>
          <select id="dropdownList" name="cake" class="form-control"> 
          </select>
      </div>

      <div class="form-submit">
        <input type="submit" name="" value="Submit">
      </div>
    </form>
  </body>
  <script>
    function addOptions() {
      /*This will call server-side Apps Script function getAvailableFlavors 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)
        .getAvailableFlavors();
    }

    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>
</html>

这里我创建了一个名为“Inventory”的sheet:

每人点一个蛋糕,数量减1

当蛋糕数量为0时,脚本将从下拉列表中删除芝士蛋糕:

注意:您可以复制并粘贴上面的代码,但您需要一个 Sheet 命名为 Inventory,其内容和格式与我上面的示例相同。

参考文献: