根据我的理解,只有一个doGet()可以在Google Apps脚本应用程序中触发唯一的doPost()。
我想执行 软件发布商系统 ,用户上传文件或填写表单中的修订信息,然后将提交推送到下一步。最后一页将显示输入信息,向人发送电子邮件并完成所有操作。
但是如何在推送提交按钮后输入下一个表单?
我尝试过在 doPost() 中创建第2步和第3步表单的方法,并使用 try ... catch 以不同的步骤形式触发当前步骤,如下面的代码。 (因为任何步骤都不能通过非前一步骤抛出回调项,所以它会产生异常)
它运作良好,但我认为它不会让人感到愚蠢。有更好的解决方案吗?谢谢,拜托。
//---------------------------------------------------------------------------
function doGet(e)
{
var app = UiApp.createApplication().setTitle("AP Publisher");
createFileUploadForm(app);
return app;
}
//---------------------------------------------------------------------------
function doPost(e)
{
var app = UiApp.getActiveApplication();
try {
// 2nd step form
var fileBlob = e.parameter.thefile;
createRevisionForm();
}
catch(error) {
try {
// 3rd step form
createConfirmForm(e);
}
catch(error2) {
//Complete
sendMail(e);
modifySitePageContent(e);
saveHistoryFile(e);
showConfirmedInfo(e);
}
}
return app;
}
答案 0 :(得分:0)
我认为在您的doGet功能中使用3个(或更多)不同的面板与您需要的所有项目并使用它们的可见性会更简单。
首先只有第一个面板可见,并且根据用户输入(使用客户端处理程序来处理)显示下一个面板(并最终隐藏第一个面板)。
最后,提交按钮将调用doPost并从doGet获取所有数据。
答案 1 :(得分:0)
此答案完全从create a new page in a form dynamically, based on data of the prev. page复制。
使用UiApp
服务,您有一个doGet()
和一个doPost()
功能......但是这里有一种扩展它们以支持动态多部分表单的方法。 (示例代码来自this answer。)
您的doGet()
只是构建表单的第1部分。但是,在表单中,您需要通过名称标识表单,如下所示:
var form = app.createFormPanel().setId("emailCopyForm");
然后,doPost()
将根据提交的表单将后期操作的处理转移到不同的功能。见下文。 (还包括:reportFormParameters ()
,一个默认处理程序,它将显示表单部分收集的所有数据。)
/**
* doPost function with multi-form handling. Individual form handlers must
* return UiApp instances.
*/
function doPost(eventInfo) {
var app;
Logger.log("Form ID = %s", eventInfo.parameter.formId);
// Call appropriate handler for the posted form
switch (eventInfo.parameter.formId) {
case 'emailCopyForm':
app = postEmailCopyForm(eventInfo);
break;
default:
app = reportFormParameters (eventInfo);
break;
}
return app;
}
/**
* Debug function - returns a UiInstance containing all parameters from the
* provided form Event.
*
* Example of use:
* <pre>
* function doPost(eventInfo) {
* return reportFormParameters(eventInfo);
* }
* </pre>
*
* @param {Event} eventInfo Event from UiApp Form submission
*
* @return {UiInstance}
*/
function reportFormParameters (eventInfo) {
var app = UiApp.getActiveApplication();
var panel = app.createVerticalPanel();
panel.add(app.createLabel("Form submitted"));
for (var param in eventInfo.parameter) {
switch (param) {
// Skip the noise; these keys are used internally by UiApp
case 'lib':
case 'appId':
case 'formId':
case 'token':
case 'csid':
case 'mid':
break;
// Report parameters named in form
default:
panel.add(app.createLabel(" - " + param + " = " + eventInfo.parameter[param]));
break;
}
}
app.add(panel);
return app;
}
要生成每个表单部分,后续表单处理程序可以使用前面部分中检索的数据动态地将新的Form对象添加到ui。
答案 2 :(得分:0)
首先是我对莫格斯达的帽子。他的帖子在黑暗记录的路径中引导我,这引导我来到这里。 Here is some working code
它演示了一个多页面形式,即它执行初始doGet()
,然后让您来回前进多个doPost()
。所有这些都是在标准getForm()
和doGet()
函数调用的单个doPost()
函数中完成的。
// Muliple page form using Google Apps Script
function doGet(eventInfo) {return GUI(eventInfo)};
function doPost(eventInfo) {return GUI(eventInfo)};
function GUI (eventInfo) {
var n = (eventInfo.parameter.state == void(0) ? 0 : parseInt(eventInfo.parameter.state));
var ui = ((n == 0)? UiApp.createApplication() : UiApp.getActiveApplication());
var Form;
switch(n){
case 0: {
Form = getForm(eventInfo,n); // Use identical forms for demo purpose only
} break;
case 1: {
Form = getForm(eventInfo,n); // In reality, each form would differ but...
} break;
default: {
Form = getForm(eventInfo,n) // each form must abide by (implement) the hidden state variable
} break;
}
return ui.add(Form);
};
function getForm(eventInfo,n) {
var ui = UiApp.getActiveApplication();
// Increment the ID stored in a hidden text-box
var state = ui.createTextBox().setId('state').setName('state').setValue(1+n).setVisible(true).setEnabled(false);
var H1 = ui.createHTML("<H1>Form "+n+"</H1>");
var H2 = ui.createHTML(
"<h2>"+(eventInfo.parameter.formId==void(0)?"":"Created by submission of form "+eventInfo.parameter.formId)+"</h2>");
// Add three submit buttons to go forward, backward and to validate the form
var Next = ui.createSubmitButton("Next").setEnabled(true).setVisible(true);
var Back = ui.createSubmitButton("Back").setEnabled(n>1).setVisible(true);
var Validate = ui.createSubmitButton("Validate").setEnabled(n>0).setVisible(true);
var Buttons = ui.createHorizontalPanel().add(Back).add(Validate).add(Next);
var Body = ui.createVerticalPanel().add(H1).add(H2).add(state).add(Buttons).add(getParameters(eventInfo));
var Form = ui.createFormPanel().setId((n>0?'doPost[':'doGet[')+n+']').add(Body);
// Add client handlers using setText() to adjust state prior to form submission
// NB: Use of the .setValue(val) and .setValue(val,bool) methods give runtime errors!
var onClickValidateHandler = ui.createClientHandler().forTargets(state).setText(''+(parseInt(n)));
var onClickBackHandler = ui.createClientHandler().forTargets(state).setText(''+(parseInt(n)-1));
Validate.addClickHandler(onClickValidateHandler);
Back.addClickHandler(onClickBackHandler);
// Add a client handler executed prior to form submission
var onFormSubmit = ui.createClientHandler()
.forTargets(state).setEnabled(true) // Enable so value gets included in post parameters
.forTargets(Body).setStyleAttribute("backgroundColor","#EEE");
Form.addSubmitHandler(onFormSubmit);
return Form;
}
function getParameters(eventInfo) {
var ui = UiApp.getActiveApplication();
var panel = ui.createVerticalPanel().add(ui.createLabel("Parameters: "));
for( p in eventInfo.parameter)
panel.add(ui.createLabel(" - " + p + " = " + eventInfo.parameter[p]));
return panel;
}
代码使用单个“隐藏”状态(此处在TextBox
中可视化)和多个SubmitButton
以允许用户在表单序列中前后前进,以及验证表单的内容。两个额外的SubmitButton
使用ClientHandler
进行“重新布线”,只需在表单提交之前修改隐藏状态。
备注强>
请注意在客户端处理程序中使用.setText(value)
方法。使用Chrome浏览器,如果我切换到TextBox
的{{1}}或.setValue(value)
方法,我会收到奇怪的运行时错误。
我尝试(不成功)使用.setValue(value, fireEvents)
而不是隐藏的TextBox来实现此逻辑。这需要使用服务器处理程序,而不是客户端处理程序。行为不稳定,向我建议异步服务器端事件发生在表单提交事件之后。