可以使用GAS创建一个交互式Web应用程序吗? [英] Can one create an Interactive web app with GAS?

查看:49
本文介绍了可以使用GAS创建一个交互式Web应用程序吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

归根结底,我想从Web应用程序上下文中做的是:

Broken down to its most elemental, what I want to do from a web app context is:

  • 向用户询问一些数据.
  • 向用户显示一些数据.
  • 向用户询问更多数据.
  • 使用Web应用程序中的所有数据.

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

More specifically, I am trying to build a Google Script web app that does the following:

  1. 显示一个html页面,用户可以在其中输入用户ID号.
  2. 获取该数字并找到电子表格中的最后一行 给那个用户.
  3. 向用户显示最后一个行号(这是 我感到难过的第一点-见下文 尝试过的).
  4. 显示第二个html输入页面,用户可以在其中输入 接受显示给他们的最后一行信息,或输入备用 号(以及其他一些信息).
  5. 所有这些信息然后用于 创建一个Google文档,并在新行上添加有关该Google文档的信息 在Google电子表格中.
  1. Presents an html page where the user can input a user ID number.
  2. Takes that number and finds the last line on a spreadsheet belonging to that user.
  3. Displays that last line number to the user (this is the first point at which I am stumped—see below for what I have tried).
  4. Presents a 2nd html input page where the user can either accept the last line info displayed to them, or enter an alternate number (and some other info).
  5. All of that info is then used to create a Google Doc and add info about that Google Doc on a new row in a Google spreadsheet.

我尝试过:

(a)类PromptResponse [ui.prompt]
(b)警报(提示)
(c)showModalDialog
(d)显示ModelessDialog

(a) Class PromptResponse [ui.prompt]
(b) alert(Prompt)
(c) showModalDialog
(d) show ModelessDialog

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

All of these failed as they apparently must be triggered from a bound app.

我考虑了在单个webApp中具有两个doGet语句的概念,这使我 链接到Google Apps脚本中的另一个HTML页面,但这似乎处理的是两页的单一html,而不是两个单独的html页(这是我认为我需要的).

I considered the concept of having two doGet statements in a single webApp which led me to Linking to another HTML page in Google Apps Script, but that seems to deal with a two-page SINGLE html rather than two separate html pages (which is what I think I need).

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

I also considered using the Browser.msgBox in the Class CacheService but that produced the same context error as (a) thru (d) above.

最后,我考虑了-不是显示上面(1)的用户ID号-而是保存变量并将其稍后插入脚本中(即,将其加载到上面的(4)中).那导致我进入了CacheService.但是我看不到如何进行这项工作,无论如何,这并不是我真正想做的.

Lastly, I thought about—rather than displaying the user ID number from (1) above—saving the variable and inserting it later in the script (i.e., loading it in (4) above). That led me to the CacheService. But I could not see how to make that work and in any event, it’s not really what I want to do.

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;
}

如前所述,我尝试的所有内容均出现上下文"错误.顺便说一句,我还创建了一个Web应用程序,它具有2个GS页面和2个Index页面,并且仅在一个页面上显示了两个html页面,但我仍然不知道如何显示用户ID.

As noted, I got "context" errors with everything I tried. BTW, I also created a web app that had 2 GS pages and 2 Index pages, and that just displayed both html pages on one page, and I still couldn't figure out how to display the User ID.

最后,我在SO和整个网络上花费了很多时间,并使用了很多搜索词,试图找到其他可以解决该问题的人,并且想到了鹅卵.

Finally, I spent a lot of hours, and used a lot of search terms, both at SO and the web in general trying to find someone else that has tackled this problem—and came up goose eggs.

注意:为了尊重最小且可验证的",我没有包括要求提供第二组信息的脚本,但该脚本已编写且可以使用.

Note: To respect "minimal, and verifiable," I have not included the script that asks for the 2nd set of info, but it is written and works.

更新:以下SO问题/答案出现在该问题的右侧:"

Update: The following SO Question/Answer showed up to the right of this question: "Web apps+ remotely using script" after I posted it

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

It seems to in part solve my problem. At least it does display the user's User ID input, but I need it to display info I pull from a Google sheet based on the User ID (i.e., the songId). Using the doGet(e) approach, I still don't know where to put the getSongIdcode that gets the songId. I have added that code above.

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>

推荐答案

首先尝试简单的操作.只是看到您可以使客户端和服务器进行通信:

Try something simple first. Just to see that you can get the client and the server communicating:

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()函数:

Then use a simple getSongId() function:

function getSongId(uObj) {
  return uObj.user
}

我会使用这种doGet()

I would use this sort of doGet()

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

您的html没有任何需要评估的scriptlet.它不是真正的模板.

You html doesn't have any scriptlets that need to be evaluated. It's not really a template.

然后单独测试getSongId,一旦工作成功,您就可以将其返回到div,如果您希望以后可以创建另一个页面,则可以将其返回.

Then test the getSongId by itself and once that works you can return it to the div and later if you wish you can create another page.

这篇关于可以使用GAS创建一个交互式Web应用程序吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆