使用 google sheet 脚本编辑器将数据提交到不同的选项卡
Submitting data to different tabs using google sheet script editor
在我的电子表格脚本编辑器中,我有以下代码:
Code.gs
function doGet() {
return HtmlService.createTemplateFromFile('checkForm.html')
}
function doPost1(e) {
Logger.log(JSON.stringify(e))
if (!e || !e.parameter) {
return;
}
var lock = LockService.getScriptLock();
lock.tryLock(10 * 1000);
var scriptProp = PropertiesService.getScriptProperties();
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var checkForm = ss.getSheetByName("checkForm");
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow() + 1;
var newRow = headers.map(function(header) {
return header === 'Timestamp' ? new Date() : e.parameter[header]
});
sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow]);
var startTime = newRow[1];
var endTime = newRow[2];
var cal = CalendarApp.getCalendarById("ID");
var allEvents = cal.getEvents(new Date(startTime), new Date(endTime));
if (allEvents.length > 0) {
return HtmlService.createTemplateFromFile('calendarAgenda.html')
}else {
return HtmlService.createTemplateFromFile('bookingForm.html')
};
}
catch (e) {
return ContentService
.createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
.setMimeType(ContentService.MimeType.JSON)
}
finally {
lock.releaseLock()
}
}
function doPost2(e) {
Logger.log(JSON.stringify(e))
if (!e || !e.parameter) {
return;
}
var lock = LockService.getScriptLock();
lock.tryLock(10 * 1000);
var scriptProp = PropertiesService.getScriptProperties();
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var bookForm = ss.getSheetByName("bookForm");
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow() + 1;
var newRow = headers.map(function(header) {
return header === 'Timestamp' ? new Date() : e.parameter[header]
});
sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow]);
return ContentService
.createTextOutput(JSON.stringify('Successfully received. Thank you!'))
.setMimeType(ContentService.MimeType.JSON)
}
catch (e) {
return ContentService
.createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
.setMimeType(ContentService.MimeType.JSON)
}
finally {
lock.releaseLock()
}
}
checkForm.html
<!DOCTYPE html>
<body>
<form name="class1Check" id="class1Check" action="ScriptURL" target="_self" method="POST">
Start Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="Start Date & Time">
<br><br>
End Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="End Date & Time">
<button type="submit" onclick="google.script.run.doPost1(this.parentNode)">Check</button>
</form>
<script>
function postData(form) {
google.script.run.withSuccessHandler(postData).doPost1(e);
}
</script>
</body>
</html>
bookingForm.html
<!DOCTYPE html>
<body>
<form name="class1Booking" id="class1Booking" action="ScriptURL" target="_self" method="POST">
<inputs> ..
<button type="submit" onclick="google.script.run.doPost1(this.parentNode)">Check</button>
</form>
<script>
function postData(form) {
google.script.run.withSuccessHandler(postData).doPost2(e);
}
</script>
</body>
</html>
goGet 函数 returns "checkForm.html" 提交的页面应该 运行 doPost1 函数将数据发送到电子表格中的选项卡 "checkForm",然后returns 第二页"bookingForm.html" 提交时应该运行 doPost2 函数将数据发送到选项卡"bookForm" 然后returns 某个文本输出
当我提交支票表格时,我收到错误 "Script function not found: doPost",我想我可能有一些关于 google.script.run 的问题,我尝试修改了几次但没有成功。任何帮助和提前感谢
忘掉 doPost()。尝试这样的事情。
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>#msg{display:none;}</style>
</head>
<body>
<form>
<!--><inputs type="text" name="name1">-->
<button type="button" value="Submit" onclick="processForm(this.parentNode);" />
</form>
<div id="msg"></div>
<script>
$(function(){
//You can get stuff from the server after the dom has loaded. I know it takes some time but it's a simple way to intialize. Personally for my own sutff Id rather do this that use templated html
});
function processFormC(form) {
//input validation
google.script.run
.withSuccessHandler(function(obj){
$('#msg').css("display","block");
$('#msg').html(obj.msg);
})
.processFormS(form);
}
</script>
</body>
</html>
GS:
function processFormS(obj) {
//obj.name1...
return {msg:'Got it.'}
}
function doGet() {
return HtmlService.createHtmlOutputFromFile('whatever file name')
}
我个人更喜欢将所有 javascript 和 css 放在同一个文件中,因为以后更容易找到。是的,我知道它会变大,但那是我的选择,不一定是你的选择。
您没有使用 google.script.run functions correctly, as it’s stated in the documentation 您只能 return 类型的值:
Number, Boolean, String, or null, as well as JavaScript objects and
arrays that are composed of primitives, objects and arrays.
在您的情况下,您正在尝试 return 一个 textOutput object, which is not allowed, this class is intended for Web Apps 函数(doGet(e) 或 doPost(e))。
在有关 [客户端到服务器通信] (https://developers.google.com/apps-script/guides/html/communication) 的文档中,解释了如何使用 google.script.run。这是一个适用于您的案例的示例,因此您可以更好地理解它的工作原理:
checkForm.html
<!DOCTYPE html>
<body>
<form name="class1Check" id="class1Check" target="_self" method="POST">
Start Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="Start Date & Time">
<br><br>
End Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="End Date & Time">
<button onclick="postData(this.parentNode)">Check</button>
</form>
<script>
//It’s run when form button is clicked
function postData(form) {
//Calls doSomething function in code.gs with form parameter
google.script.run.withSuccessHandler(handlerFunction).doSomething(form);
}
//Handles the response from doSomething function
function handlerFunction(responseData) {
//Logs ‘It worked!’ in developer console
console.log(responseData);
}
</script>
</body>
</html>
code.gs
//Web App function
function doGet() {
return HtmlService.createTemplateFromFile('checkForm.html')
}
//Apps script function to receive form object and return response
function doSomething(form) {
//Do something
return ‘It worked!’;
}
Apps Script 的 Web 应用程序被设计为单页应用程序(一个 HTML 页)而不是多页应用程序,尽管有不同的解决方法示例可以指导您实现多页行为:
[1] Linking to another HTML page in Google Apps Script
[2] https://sites.google.com/corp/view/googlappsscript/recent-scripts/multiple-page-webapp-example
在我的电子表格脚本编辑器中,我有以下代码:
Code.gs
function doGet() {
return HtmlService.createTemplateFromFile('checkForm.html')
}
function doPost1(e) {
Logger.log(JSON.stringify(e))
if (!e || !e.parameter) {
return;
}
var lock = LockService.getScriptLock();
lock.tryLock(10 * 1000);
var scriptProp = PropertiesService.getScriptProperties();
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var checkForm = ss.getSheetByName("checkForm");
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow() + 1;
var newRow = headers.map(function(header) {
return header === 'Timestamp' ? new Date() : e.parameter[header]
});
sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow]);
var startTime = newRow[1];
var endTime = newRow[2];
var cal = CalendarApp.getCalendarById("ID");
var allEvents = cal.getEvents(new Date(startTime), new Date(endTime));
if (allEvents.length > 0) {
return HtmlService.createTemplateFromFile('calendarAgenda.html')
}else {
return HtmlService.createTemplateFromFile('bookingForm.html')
};
}
catch (e) {
return ContentService
.createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
.setMimeType(ContentService.MimeType.JSON)
}
finally {
lock.releaseLock()
}
}
function doPost2(e) {
Logger.log(JSON.stringify(e))
if (!e || !e.parameter) {
return;
}
var lock = LockService.getScriptLock();
lock.tryLock(10 * 1000);
var scriptProp = PropertiesService.getScriptProperties();
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var bookForm = ss.getSheetByName("bookForm");
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow() + 1;
var newRow = headers.map(function(header) {
return header === 'Timestamp' ? new Date() : e.parameter[header]
});
sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow]);
return ContentService
.createTextOutput(JSON.stringify('Successfully received. Thank you!'))
.setMimeType(ContentService.MimeType.JSON)
}
catch (e) {
return ContentService
.createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
.setMimeType(ContentService.MimeType.JSON)
}
finally {
lock.releaseLock()
}
}
checkForm.html
<!DOCTYPE html>
<body>
<form name="class1Check" id="class1Check" action="ScriptURL" target="_self" method="POST">
Start Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="Start Date & Time">
<br><br>
End Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="End Date & Time">
<button type="submit" onclick="google.script.run.doPost1(this.parentNode)">Check</button>
</form>
<script>
function postData(form) {
google.script.run.withSuccessHandler(postData).doPost1(e);
}
</script>
</body>
</html>
bookingForm.html
<!DOCTYPE html>
<body>
<form name="class1Booking" id="class1Booking" action="ScriptURL" target="_self" method="POST">
<inputs> ..
<button type="submit" onclick="google.script.run.doPost1(this.parentNode)">Check</button>
</form>
<script>
function postData(form) {
google.script.run.withSuccessHandler(postData).doPost2(e);
}
</script>
</body>
</html>
goGet 函数 returns "checkForm.html" 提交的页面应该 运行 doPost1 函数将数据发送到电子表格中的选项卡 "checkForm",然后returns 第二页"bookingForm.html" 提交时应该运行 doPost2 函数将数据发送到选项卡"bookForm" 然后returns 某个文本输出
当我提交支票表格时,我收到错误 "Script function not found: doPost",我想我可能有一些关于 google.script.run 的问题,我尝试修改了几次但没有成功。任何帮助和提前感谢
忘掉 doPost()。尝试这样的事情。
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>#msg{display:none;}</style>
</head>
<body>
<form>
<!--><inputs type="text" name="name1">-->
<button type="button" value="Submit" onclick="processForm(this.parentNode);" />
</form>
<div id="msg"></div>
<script>
$(function(){
//You can get stuff from the server after the dom has loaded. I know it takes some time but it's a simple way to intialize. Personally for my own sutff Id rather do this that use templated html
});
function processFormC(form) {
//input validation
google.script.run
.withSuccessHandler(function(obj){
$('#msg').css("display","block");
$('#msg').html(obj.msg);
})
.processFormS(form);
}
</script>
</body>
</html>
GS:
function processFormS(obj) {
//obj.name1...
return {msg:'Got it.'}
}
function doGet() {
return HtmlService.createHtmlOutputFromFile('whatever file name')
}
我个人更喜欢将所有 javascript 和 css 放在同一个文件中,因为以后更容易找到。是的,我知道它会变大,但那是我的选择,不一定是你的选择。
您没有使用 google.script.run functions correctly, as it’s stated in the documentation 您只能 return 类型的值:
Number, Boolean, String, or null, as well as JavaScript objects and arrays that are composed of primitives, objects and arrays.
在您的情况下,您正在尝试 return 一个 textOutput object, which is not allowed, this class is intended for Web Apps 函数(doGet(e) 或 doPost(e))。
在有关 [客户端到服务器通信] (https://developers.google.com/apps-script/guides/html/communication) 的文档中,解释了如何使用 google.script.run。这是一个适用于您的案例的示例,因此您可以更好地理解它的工作原理:
checkForm.html
<!DOCTYPE html>
<body>
<form name="class1Check" id="class1Check" target="_self" method="POST">
Start Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="Start Date & Time">
<br><br>
End Date & Time
<input class="w3-input w3-border" type="datetime-local" required name="End Date & Time">
<button onclick="postData(this.parentNode)">Check</button>
</form>
<script>
//It’s run when form button is clicked
function postData(form) {
//Calls doSomething function in code.gs with form parameter
google.script.run.withSuccessHandler(handlerFunction).doSomething(form);
}
//Handles the response from doSomething function
function handlerFunction(responseData) {
//Logs ‘It worked!’ in developer console
console.log(responseData);
}
</script>
</body>
</html>
code.gs
//Web App function
function doGet() {
return HtmlService.createTemplateFromFile('checkForm.html')
}
//Apps script function to receive form object and return response
function doSomething(form) {
//Do something
return ‘It worked!’;
}
Apps Script 的 Web 应用程序被设计为单页应用程序(一个 HTML 页)而不是多页应用程序,尽管有不同的解决方法示例可以指导您实现多页行为:
[1] Linking to another HTML page in Google Apps Script
[2] https://sites.google.com/corp/view/googlappsscript/recent-scripts/multiple-page-webapp-example