简体   繁体   中英

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

I created a web form using Google Apps Script that has options with capacity.

In the following example, there is a question to ask visitors to choose cheesecake or chocolate cake. Suppose that I have only two pieces of cheesecake and three pieces of chocolate cake, and if two visitors has already choose the cheesecake, I want to remove the option of cheesecake from the form and make that option invisible and thus unselectable, showing the option of chocolate cake only.

Then, how should I implement such a select question whose options have capacity using Google Apps Script?

Note but I want to create a custom web form, and that this time I do NOT use Google Forms for that purpose.

EDIT

The following link will show how this programme saves data on a spreadsheet: 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>');
}

I believe your current situation and goal are as follows.

  • Your HTML is included in the Google Apps Script project.
  • You want to retrieve the values from the Spreadsheet and show them in the dropdown list.
  • For example, there are two pieces of cheesecake. When an user selects a cheesecake and submit it, you want to reduce 1 from cheesecake in the Spreadsheet.
  • When the number of cheesecake is 0 , you don't want to select it.

In this case, how about the following sample script?

Sample spreadsheet

In this script, in order to test, the following Spreadsheet is used. This sheet is the 1st tab of the Spreadsheet.

在此处输入图像描述

Sample script

Please copy and paste the following scripts to the script editor. And, please reflect the latest script to the Web Apps .

Google Apps Script side: 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 side: 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>

Testing

Please access the deployed Web Apps reflected in the modified script. By this, you can see the dropdown list.

In this sample, cheesecake has 2. When you select a cheesecake and click the "Submit" button, the number of cheesecakes on the Spreadsheet becomes from 2 to 1. When you select cheesecake and click the button again, you can confirm that the option of cheesecake cannot be selected.

I thought that this might be your expected result.

Note

  • 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 ".

  • This sample script is a simple script. So, please modify this for your actual situation.

Reference

If you want to remove an option based on quantity, then you should save the quantity of each cake to a Sheet.

Here I modified your code and added some features:

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>

Here I created a sheet named " Inventory ":

在此处输入图像描述

and each time a person orders a cake, the quantity is reduced by 1.

在此处输入图像描述

When the quantity of cake reaches 0, the script will remove the cheesecake from the drop down list:

在此处输入图像描述

Note: You can copy and paste the code above but you need a Sheet named Inventory with the same content and format from my example above.

References:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM