2

请求摘要:

我知道 FormPanel 与 doPost(e) 一起使用。

但是,如果我有几个 formPanel 并且它们中的每一个都需要使用不同的 doPost(e) 集?

由于 doPost(e) 是固定名称,如何有一些不同的 doPost(e),如 doPost1(e)、doPost(2) 等。

createSubmitButton 的问题相同,因为它会自动查找函数 doPost(e),如何引导每个 formPanel 的提交触发正确的 doPostX(e)

如果上述不可行,是否意味着每个项目仅限于单个 doPost(e) 函数?

谢谢,

4

2 回答 2

2

doPost 和 doGet 函数可能存在的问题是每个项目最多只能有一个 doGet 和一个 doPost。这是因为这些功能使用共享资源,因此此类功能在一个项目的功能之间共享。

实际上有两种解决方法(至少我知道并且只测试了其中两种)来使用多个 doPost 查询,这些查询在一个项目中执行不同的操作。

最简单(也是最好的)方法是在单个 doPost 函数中使用不同的函数,每个任务都需要一个 doPost 函数。这里的诀窍是您需要在表单中添加一个隐藏字段,以帮助您区分项目中的不同表单。

然后您可以添加一个“if()else if()else”块来根据隐藏字段的值选择正确的函数。

例如,如果您有两个功能,您可以执行以下操作:

function doGet(e){
  var app=UiApp.createApplication();
  some stuff;
  return app; 
}


function doPost(e){

  some stuff

  if(e.parameter.form=="value1"){
    function1(e,otherParameters);
  }
 else if(e.parameter.form=="value2"){
    function2(e,otherParameters);
 }
 else{

 }

 some other stuff
}

function function1(e,otherParameters){

 var app=UiApp.getActiveApplication();
 var panel=app.createVerticalPanel();
 var formPanel=app.createFormPanel();
 var button=app.createSubmitButton();
 var formHidden=app.createHidden().setName("form");
 other widgets;
 panel.add(formHidden);
 panel.add(other widgets);
 panel.add(button);
 formPanel.add(panel);

 some stuff;
 app.add(formPanel);
}

function function2(e,otherParameters){
 var app=UiApp.getActiveApplication();
 var panel=app.createVerticalPanel();
 var formPanel=app.createFormPanel();
 var button=app.createSubmitButton();
 var formHidden=app.createHidden().setName("value2");
 other widgets different from those in function1;
 panel.add(formHidden);
 panel.add(other widgets);
 panel.add(button);
 formPanel.add(panel);

 some stuff different from what you have in function1;
 app.add(formPanel);
}

您还可以创建另一个具有 doPost 功能的项目(例如 Project2),并将该项目部署为 Web 应用程序。

这个想法是,您可以使用 FormPanel 的 setAction("url") 方法将信息从给定表单发送到某些 url。使用此方法,您可以将表单的内容发送到将处理您的查询的网页。因此,如果您将此方法的字符串值设置为您的网络应用程序的 url,您将向该应用程序发送 google-script 表单的内容。这就是这个应用程序,它将使用它的 doPost 函数来处理查询。

此选项开发起来有点困难,并且存在当前根本无法处理来自 FileUpload 的 Blob 的缺点。

希望对你有帮助

干杯

尼古拉斯

于 2013-02-05T17:45:41.627 回答
1

注意:在doPost()传递控制权的子程序中,一定要使用UiApp.getActiveApplication()方法。在匆忙中,我花费的时间比我愿意承认的要多,因为我UiApp.createApplication()在每个子例程中都调用了该方法。

编辑

这是演示多页表单的工作代码 ,即它执行初始操作doGet(),然后让您来回前进执行多个doPost()'s。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 -1: {
      Form = ui.createFormPanel().add(ui.createHTML("<H3>Exited by submission of form "+eventInfo.parameter.formId+"</h3>"));
    } break;
    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 Stay = ui.createSubmitButton("Stay").setEnabled(n>0).setVisible(true);
  var Exit = ui.createSubmitButton("Exit").setEnabled(n>0).setVisible(true);
  var Buttons = ui.createHorizontalPanel().add(Back).add(Stay).add(Next).add(Exit);
  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 onClickStayHandler = ui.createClientHandler().forTargets(state).setText(''+(parseInt(n)));
  var onClickBackHandler = ui.createClientHandler().forTargets(state).setText(''+(parseInt(n)-1));
  var onClickExitHandler = ui.createClientHandler().forTargets(state).setText('-1');
  Stay.addClickHandler(onClickStayHandler);
  Back.addClickHandler(onClickBackHandler);
  Exit.addClickHandler(onClickExitHandler);

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

该代码使用单个“隐藏”状态(此处以 a 可视化TextBox)和多个SubmitButton's 来允许用户在表单序列中前进和后退,以及验证表单的内容。三个额外SubmitButton的 's 使用 's “重新连接” ClientHandler,它们在表单提交之前简单地修改隐藏状态。

笔记

  • 在任何给定的形式中,您实际上可以拥有应用程序需要的任意数量的按钮;即多于或少于此处演示的四个。此示例中的Stay按钮有效地发布当前状态并重新加载相同的表单。请注意,这在功能上等同于执行服务器处理程序。可能的用途是例如。加载默认数据或将现有数据从/保存到数据库/工作表。

  • 请注意.setText(value)在客户端处理程序中使用该方法。使用 Chrome 浏览器,如果我切换到TextBox's.setValue(value).setValue(value, fireEvents)方法中的任何一个,我会收到奇怪的运行时错误。

  • Script Property我尝试(未成功)使用 a而不是隐藏的 TextBox来实现此逻辑。这需要使用服务器处理程序而不是客户端处理程序。行为不稳定,向我暗示异步服务器端事件是在表单提交事件之后发生的。

于 2014-07-27T20:14:05.507 回答