【问题标题】:Can one create an Interactive web app with GAS?可以使用 GAS 创建交互式 Web 应用程序吗?
【发布时间】:2019-05-28 09:21:24
【问题描述】:

归结为最基本的,我想从网络应用程序上下文中做的是:

  • 向用户请求一些数据。
  • 向用户显示一些数据。
  • 向用户索取更多数据。
  • 在网络应用程序中使用所有这些数据。

更具体地说,我正在尝试构建一个执行以下操作的 Google Script 网络应用:

  1. 提供一个 html 页面,用户可以在其中输入用户 ID 号。
  2. 获取该数字并在属于的电子表格中找到最后一行 给那个用户。
  3. 向用户显示最后的行号(这是 我被难住的第一点——见下文我所拥有的 试过)。
  4. 提供第二个 html 输入页面,用户可以在其中 接受显示给他们的最后一行信息,或输入替代信息 号码(和其他一些信息)。
  5. 所有这些信息随后用于 创建一个 Google Doc 并在新行上添加有关该 Google Doc 的信息 在 Google 电子表格中。

我试过了:

(a) 类 PromptResponse [ui.prompt]
(b) 警报(提示)
(c) showModalDialog
(d) 显示无模式对话框

所有这些都失败了,因为它们显然必须从绑定的应用程序中触发。

我考虑了在单个 webApp 中包含两个 doGet 语句的概念,这导致我 Linking to another HTML page in Google Apps Script,但这似乎是处理一个两页的 SINGLE html 而不是两个单独的 html 页面(这是我认为我需要的)。

我也考虑过在 CacheService 类中使用 Browser.msgBox,但这会产生与上述 (a) 到 (d) 相同的上下文错误。

最后,我想到了——而不是显示上面 (1) 中的用户 ID 号——保存变量并稍后将其插入脚本中(即,在上面的 (4) 中加载它)。这导致我使用 CacheService。但我不知道如何做到这一点,无论如何,这不是我真正想做的。

GS

function doGet() {
  return HtmlService   
  .createTemplateFromFile('Index')
      .evaluate();
}
function getSongId(objArgs){
  // Get User's Catalog SS URL from Master Users List
  var userId = objArgs.user;
  var masterSSId = "ID";//This is the ID to the master users list SS.
  var userSS = SpreadsheetApp.openById(masterSSId);//Open
  var userSheet = userSS.getActiveSheet();
  var nameOfUserRange = "User" + userId; //this constructs the user ID, like "user101"
      Logger.log("nameOfUserRange = " + nameOfUserRange);
  var userNamedRange = userSS.getRangeByName(nameOfUserRange); //this returns "Range" to pass its value on to future code lines
  var cell = userNamedRange.activate(); //activates range and first cell in range
  var namedUrlRange = userSS.getRange('SongsSheetUrl'); //this gets the SongSheetUrl named range
  var userCol = namedUrlRange.getColumn(); //this gets col # of namedUrlRange
      Logger.log("userCol = " + userCol);
  var userSsUrl = cell.offset(0, userCol-1, 1, 1). getValue(); //this gets the user's Catalog SS URL
      Logger.log("userSsUrl = " + userSsUrl);
  var ss = SpreadsheetApp.openByUrl(userSsUrl);
  var sheet = ss.getActiveSheet();
  var lastRow = sheet.getLastRow();
  var songId = lastRow+1;
  Logger.log("songId = " + songId);
  //some code here that displays songID to user

HTML“索引”

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
<center>    Enter your User ID below.
    <input id="userId" type="text" placeholder="User ID"><br><br>
    <button onclick="saveUserInput()">Continue</button>
    </center>

    <script>
      window.saveUserInput = function() {
        var user = document.getElementById('userId').value;

        console.log('userId: ' + userId)

        google.script.run

          .withSuccessHandler(openPrompt)
          .getSongId({user:user})

      }

       function openPrompt(results){
           window.open(results.url, '_blank').focus();
       }
    </script>
  </body>
</html>

songId 代码

function getSongId() {
    var masterSSId = "ID";//This is the ID to the master users list SS.
    var userSS = SpreadsheetApp.openById(masterSSId);//Open
    var userSheet = userSS.getActiveSheet();
    var nameOfUserRange = "User" + userId; //this constructs the user ID, like "user101"
    var userNamedRange = userSS.getRangeByName(nameOfUserRange); //this returns "Range" to pass its value on to future code lines
    var cell = userNamedRange.activate(); //activates range and first cell in range
    var namedUrlRange = userSS.getRange('SongsSheetUrl'); //this gets the SongSheetUrl named range
    var userCol = namedUrlRange.getColumn(); //this gets col # of namedUrlRange
    var userSsUrl = cell.offset(0, userCol-1, 1, 1). getValue(); //this gets the user's Catalog SS URL
    var ss = SpreadsheetApp.openByUrl(userSsUrl);
    var sheet = ss.getActiveSheet();
    var lastRow = sheet.getLastRow();
    var songId = lastRow+1;
}

如前所述,我尝试的所有操作都出现“上下文”错误。顺便说一句,我还创建了一个有 2 个 GS 页面和 2 个索引页面的网络应用程序,并且只在一个页面上显示两个 html 页面,我仍然不知道如何显示用户 ID。

最后,我花了很多时间,使用了很多搜索词,在 SO 和整个网络上都试图找到解决这个问题的其他人 - 并想出了鹅蛋。

注意:为了尊重“最小且可验证”,我没有包含要求第二组信息的脚本,但它已编写并且有效。

更新:以下 SO 问题/答案在我发布后显示在此问题的右侧:“Web apps+ remotely using script

这似乎部分解决了我的问题。至少它确实显示了用户的用户 ID 输入,但我需要它来显示我根据用户 ID(即歌曲 ID)从谷歌表中提取的信息。使用 doGet(e) 方法,我仍然不知道将获取 songId 的 getSongIdcode 放在哪里。我已经在上面添加了该代码。

修改后的代码

gs

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function getSongId(uObj) {
  var userId = uObj.user;
  var masterSSId = "ID";//This is the ID to the master users list SS.
  var userSS = SpreadsheetApp.openById(masterSSId);//Open
  var userSheet = userSS.getActiveSheet();
  var nameOfUserRange = "User" + userId; //this constructs the user ID, like "user101"
    Logger.log("nameOfUserRange = " + nameOfUserRange);
  var userNamedRange = userSS.getRangeByName(nameOfUserRange); //this returns "Range" to pass its value on to future code lines
  var cell = userNamedRange.activate(); //activates range and first cell in range
  var namedUrlRange = userSS.getRange('SongsSheetUrl'); //this gets the SongSheetUrl named range
  var userCol = namedUrlRange.getColumn(); //this gets col # of namedUrlRange
  var userSsUrl = cell.offset(0, userCol-1, 1, 1). getValue(); //this gets the user's Catalog SS URL
  var ss = SpreadsheetApp.openByUrl(userSsUrl);
  var sheet = ss.getActiveSheet();
  var lastRow = sheet.getLastRow();
  var songId = lastRow+1;
    Logger.log("songId = " + songId);
  return songId;
}

html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
  <center>
Enter your User ID below.
<input id="userId" type="text" placeholder="User ID"><br>
<input type="button" value="Continue" onclick="saveUserInput()">
<div  id="results"></div>
</center>
<script>
      function saveUserInput() {
        var user = document.getElementById('userId').value;
        google.script.run
          .withSuccessHandler(function(hl){
            document.getElementById('results').innerHTML=hl;
          })
          .getSongId({user:user})
        }

    </script>
  </body>
</html>

【问题讨论】:

  • 你试过自己测试 GetSongId() 吗?
  • SongId 真的是最后一行的编号+1吗?
  • 我怀疑您的 getSongId 函数有问题。就个人而言,我不知道你想在那里做什么。
  • GetSongId 在我用过的其他地方工作得很好。对我来说,问题是我应该把它放在这个应用程序的哪里?它需要获取用户输入的 UserId 值,因此它似乎应该驻留在 Index html 文件中。我已经在
  • Javascript 函数在客户端。 getSongID 必须有权访问电子表格,因此它位于服务器上,并且通过 google.script.run 调用它是正确的做法。

标签: google-apps-script


【解决方案1】:

先尝试一些简单的东西。只是看看你可以让客户端和服务器通信:

html:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
Enter your User ID below.
<input id="userId" type="text" placeholder="User ID"><br>
<input type="button" value="Continue" onclick="saveUserInput()">
<div  id="results"></div>
<script>
      function saveUserInput() {
        var user = document.getElementById('userId').value;
        google.script.run
          .withSuccessHandler(function(hl){
            document.getElementById('results').innerHTML=hl;
          })
          .getSongId({user:user})
        }

    </script>
  </body>
</html>

然后使用一个简单的 getSongId() 函数:

function getSongId(uObj) {
  return uObj.user
}

我会使用这种 doGet()

function doGet() {return HtmlService.createHtmlOutputFromFile('Index');
}

您的 html 没有任何需要评估的 scriptlet。这不是一个真正的模板。

然后自行测试 getSongId,一旦成功,您可以将其返回到 div,然后如果您希望可以创建另一个页面。

【讨论】:

  • 感谢库珀。我会搞砸这个。 innerHTML 是我没见过的新皱纹。
  • 什么是uObj,它在做什么?它是否从某处/某物获得价值?
  • 这是 Javascript 中这一行的对象:.getSongId({user:user})
  • 所以这是用户输入的值(例如,“101”)?
  • 如果您开始遇到问题,请尝试将其分解为较小的问题。它可以帮助您解决问题,也可以帮助我们更快地找出当前问题所在。
猜你喜欢
  • 1970-01-01
  • 2012-05-22
  • 2020-03-04
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多