简体   繁体   English

Google Apps Script HTML 服务中的 HTML5 表单验证和文件上传

[英]HTML5 form validation and file upload in Google Apps Script HTML Service

I'm developing an GAS using HTML service and now running into a roadblock.我正在使用 HTML 服务开发 GAS,但现在遇到了障碍。 What I'm trying to do is我想做的是

  1. Create a from that can add data from form elements (ie, name and email) to Google Sheet创建一个可以将表单元素(即姓名和电子邮件)中的数据添加到 Google Sheet 的 from
  2. The form also upload a file to a specific google drive该表单还将文件上传到特定的谷歌驱动器
  3. Before 1 and 2, the form should validate input based on HTML5在 1 和 2 之前,表单应该基于 HTML5 验证输入

Here's my (almost) working code:这是我的(几乎)工作代码:

Code.gs代码.gs

function doGet(e) {
    return HtmlService.createHtmlOutputFromFile('index.html');
}

function uploadFiles(form) {
    try {
    var ssID = '-------ssID-------';
    var dropboxID = '-------DriveID-------';
    var folder = DocsList.getFolderById(dropboxID);

    var blob = form.myFile;    

    if ( Boolean(blob) ) {
        var file = folder.createFile(blob);
        file.setDescription("Uploaded by " + form.myName);
    }

var sheet = SpreadsheetApp.openById(ssID).getSheets()[0];
var lastRow = sheet.getLastRow();
var targetRange = sheet.getRange(lastRow+1, 1, 1, 3).setValues([[ form.myName, form.myMail, file.getUrl() ]]);
return "File uploaded successfully"+ file.getUrl() + file.getName();

    } catch (error) {
        return error.name + ' on line: ' + error.lineNumber + ' -> ' + error.message;
    }
}

index.html索引.html

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<!-- You can also include your own CSS styles -->
<style>
    form { margin: 40px auto; }
    input { display:block; margin: 20px; }
</style>

<!-- This is the actual HTML form -->
<!--form id="myForm" onsubmit="runGAS(this)"-->
<form id="myForm" onsubmit="return google.script.run
    .withSuccessHandler(fileUploaded)
    .uploadFiles(this.parentNode);">

    <!-- Text input fields -->
    <input type="text" name="myName" id="myName" placeholder="Your name.." required />
    <input type="email" name="myMail" id="myMail" placeholder="Your mail.." required />
    <!-- File input filed -->
    <input type="file" name="myFile" id="myFile" required />
    <!-- The submit button. It calls the server side function uploadfiles() on click -->
    <input type="submit" value="run onClick" 
           onclick="this.value='Uploading..';
                    google.script.run.withSuccessHandler(fileUploaded)
                    .uploadFiles(this.parentNode);
                    return false;">
    <input type="submit" value="Run GAS Function">
</form>
<script>

function runGAS( argThis ) {
    var n = $( "#myName" ).val();
    var f = document.getElementById("myFile");
    // var g = $( "myFile" ).val();
    if( Boolean(n) ) {
        document.getElementById('output').innerHTML = "OK" + n + "js: " + f;
        google.script.run.withSuccessHandler(fileUploaded)
        .uploadFiles( argThis );
        document.getElementById('output').innerHTML = e.name + 'on line:' + e.lineNumber + '->' + e.message;
    }
    return false;
}

</script>

<!-- Here the results of the form submission will be displayed -->
<div id="output"></div>

<!-- The function will be called after the Google Script has executed -->
<script>
    function fileUploaded(status) {
        document.getElementById('myForm').style.display = 'none';
        document.getElementById('output').innerHTML = status;
    }
</script>

I've came across many suggestions:我遇到了很多建议:

  1. Many tutorial that won't deal with file upload (only Sheet) would say call directly from submit button, this bypass HTML5 validation.许多不会处理文件上传(仅工作表)的教程会说直接从提交按钮调用,这绕过了 HTML5 验证。 This is an example of my first submit button name "run onClick."这是我的第一个提交按钮名称“run onClick”的示例。
  2. After searching, I found that to trigger HTML5 validation (Here's the link HTML5 form validation with Html Service ), the case of another submit button titled "run onClick," we should move GAS function call to form element, doing this help triggering HTML5 validation, BUT the weird thing happen to GAS as it won't and the URL generate typical GET with form values (eg, https://script.google.com/a/macros/----/s/---------/dev?myName=va&myMail=vas%40au.edu&myFile=imgName.jpg )经过搜索,我发现要触发HTML5验证(这里是HTML5表单验证与Html Service的链接),另一个标题为“run onClick”的提交按钮的情况,我们应该将GAS函数调用移动到form元素,这样做有助于触发HTML5验证,奇怪的事情发生在 GAS 上,因为它不会,并且 URL 生成带有表单值的典型GET (例如, https://script.google.com/a/macros/----/s/---------/dev?myName=va&myMail=vas%40au.edu&myFile=imgName.jpg )
  3. Another solution, some suggest that we can use jQuery to catch form submit to trigger GAS function call only when all requirements (validation) are met.另一种解决方案,有人建议我们可以使用jQuery来捕获表单提交,只有在满足所有要求(验证)时才触发GAS函数调用。 This gives the same result as 2. to me.这给了我与 2. 相同的结果。 The GAS run, but comes back to this page without passing any actual values. GAS 运行,但没有传递任何实际值就返回到此页面。

Any solution would be appreciated.任何解决方案将不胜感激。

EDIT 12/19/2014编辑 12/19/2014

<script>
window.runGAS = function() {
  // jQuery Style
  window.form = $( "#myForm" );
  // OR JS 
  window.form = document.getElementById('myForm');

  google.script.run
  .withSuccessHandler(fileUploaded)
  .uploadFiles(form);
  return false;
}
</script>

I tried what Sandy has suggested, omit passing value in function call onsubmit in the form element.我尝试了 Sandy 的建议,在表单元素的函数调用onsubmit中省略传递值。 This help firing HTML5 validation.这有助于触发 HTML5 验证。 I figured that I have to find ways to pass the form object (not individual form values) to code.gs , so I pass the form object through the GAS function run.我想我必须找到将表单对象(而不是单个表单值)传递给code.gs ,所以我通过 GAS 函数运行传递表单对象。

If I use jQuery style, JavaScript console reports Untaming of guest constructed objects unsupported: [object Object] .如果我使用 jQuery 样式,JavaScript 控制台会报告Untaming of guest constructed objects unsupported: [object Object]

If I use getElementById , I run into the same problem, it generates GET style URL with pair of name=value and comes back to the index.html without "performing" code.gs functions.如果我使用getElementById ,我会遇到同样的问题,它生成带有一对 name=value 的 GET 样式 URL 并返回 index.html 而不“执行” code.gs函数。 Note that it "seems" to go through code.gs somehow (ie, if I place some syntax error, it will report during this process) but it just doesn't do what it is supposed to do as in onclick .请注意,它“似乎”以某种方式通过code.gs (即,如果我放置了一些语法错误,它会在此过程中报告)但它只是没有像onclick那样做它应该做的事情。

The only way, so far, that this will work is to use onclick , not onsubmit , not calling intermediary GAS from tag.到目前为止,这将起作用的唯一方法是使用onclick ,而不是onsubmit ,而不是从标签调用中间 GAS。 But it bypasses HTML5 validation.但它绕过了 HTML5 验证。

I really have no clue here...我真的不知道这里...

Here is how I configure the FORM with HTML Service:以下是我使用 HTML 服务配置 FORM 的方法:

<form id="myInputForm" name="input" onsubmit="writeInput()">

I don't run the onsubmit="return google.script.run in the form. I think I ran into the same or similar problems that you are having. So, the form runs a JavaScript function writeInput() when the form is submitted. Then the JavaScript function in a SCRIPT tag runs google.script.run . That's what works for me. When I set it up that way, input fields that have a required setting will keep the form from being submitted.我没有在表单中运行onsubmit="return google.script.run 。我想我遇到了与您相同或类似的问题。因此,表单在提交表单时运行 JavaScript 函数writeInput() . 然后 SCRIPT 标签中的 JavaScript 函数运行google.script.run 。这对我google.script.run 。当我这样设置时,具有必填设置的输入字段将阻止提交表单。

<script>
  window.writeInput = function() {
    window.myInputValue = document.getElementById('idMyInputID').value; //Get input value
    google.script.run
  }
<script>

You should have data validation on both the front and back end.你应该对前端和后端两种数据验证。 Hackers might be able to find some way to send their own data to the .gs , server side code.黑客也许能够找到某种方式将他们自己的数据发送到.gs ,即服务器端代码。 If I were to choose either validation on the front in, client side, or back end, server side, I'd go with the server side validation.如果我选择在前面,客户端,或后端,服务器端验证要么,我会与服务器端验证去。 As far as getting a msg back to the user quickly if they did their data input wrong, the client side check is better, but it's not more secure.如果他们的数据输入错误,就快速将 msg 返回给用户,客户端检查更好,但它并不更安全。

You're really asking a question that is about personal preference, or matter of opinion.您实际上是在问一个关于个人偏好或意见问题的问题。 I just use JavaScript in the HTML to get the value out of the input field.我只是在 HTML 中使用 JavaScript 从输入字段中获取值。

window.variableName = document.getElementById('id_Name').value;

That line of code gets the value out of a form input field, and into a variable.这行代码从表单输入字段中获取值,并放入一个变量中。 Then you can send the variable to the .gs file.然后您可以将变量发送到.gs文件。

google.script.run.withFailureHandler(onFailure)
      .withSuccessHandler(savedLst)
      .writeInputData(variableName);

The above code is in the HTML.上面的代码在 HTML 中。 The function writeInputData is in a .gs script file.函数writeInputData位于.gs脚本文件中。

You can check the variable variableName for validation before calling the writeInputData function.您可以在调用writeInputData函数之前检查变量variableName以进行验证。

if (variableName === "") {
  alert("Missing Input");
  return false;
} else {
  google.script.run.withFailureHandler(onFailure)
    .withSuccessHandler(savedLst)
    .writeInputData(variableName);
};

There are other ways to do front end data validation.还有其他方法可以进行前端数据验证。 You can combine methods.您可以组合方法。 If you find an error that you can't fix, post the error message and what line it is coming from.如果您发现无法修复的错误,请发布错误消息以及它来自哪一行。

To print information from HTML use: console.log("some text here: " + variableName);要从 HTML 打印信息,请使用: console.log("some text here: " + variableName); That will print something to the console of your browser.这将在浏览器的控制台上打印一些内容。 Open the developer tools, and console to see what has been printed to the browsers console.打开开发人员工具和控制台以查看已打印到浏览器控制台的内容。 Not to be confused with Logger.log() which prints something to the server side Apps Script Log.不要与Logger.log()混淆,后者将某些内容打印到服务器端 Apps 脚本日志。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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