Google脚本:一个项目中有多个doPost

时间:2013-01-10 01:07:38

标签: google-apps-script

请求摘要:

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

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

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

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

如果无法实现上述目标,是否意味着每个项目仅限于具有单一的doPost(e)功能?

谢谢,

2 个答案:

答案 0 :(得分: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);
}

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

我们的想法是,您可以使用FormPanel的setAction(“url”)方法将给定表单中的信息发送到某些URL。 使用此方法,您可以将表单内容发送到将处理查询的网页。因此,如果您将此方法的字符串值设置为您的网络应用的网址,则会将Google脚本表单的内容发送到此应用。这个应用程序将使用其doPost函数来处理查询。

这个选项开发起来有点困难,并且存在目前根本没有处理来自FileUpload的Blob的缺点。

希望它能帮到你

干杯

尼古拉斯

答案 1 :(得分:2)

注意:在doPost()将控制转移到的子例程中,请务必使用UiApp.getActiveApplication()方法。在我的匆忙中,我花了更多的时间来承认,因为我在每个子例程中调用了UiApp.createApplication()方法。

修改

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

代码使用单个&#34;隐藏&#34;状态(此处在TextBox中可视化)和多个SubmitButton以允许用户在表单序列中前进和后退,以及验证表单的内容。另外三个SubmitButton&#34;重新布线&#34;使用ClientHandler只需在表单提交之前修改隐藏状态。

备注

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

  • 请注意在客户端处理程序中使用.setText(value)方法。使用Chrome浏览器,如果我切换到TextBox的{​​{1}}或.setValue(value)方法,我会收到奇怪的运行时错误。

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