0

在我现在的理解中,只有一个 doGet() 可以在 Google Apps 脚本应用程序中触发唯一的 doPost()。

我想执行一个软件发布系统,用户上传文件或在表格中填写修订信息并推送提交到下一步。最后一页将显示输入信息,发送电子邮件给伙计们并完成所有操作。

但是按下提交按钮后如何输入下一个表单?

我尝试了一种在doPost()中创建第二步和第三步表单的方法,并使用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;    
}
4

3 回答 3

0

我认为在 doGet 函数中使用 3 个(或更多)不同的面板来处理您需要的所有项目并利用它们的可见性会更简单。

起初只有第一个面板是可见的,并且根据用户输入(使用客户端处理程序来处理)显示下一个面板(并最终隐藏第一个面板)。

最后提交按钮将调用doPost并从doGet获取所有数据。

于 2013-07-15T12:07:38.433 回答
0

首先向 Mogsdad 致敬。他的帖子在将我带到这里的黑暗记录的道路上指路明灯。这是一些演示多页表单的工作代码 ,即它执行初始操作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 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;
}

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

笔记

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

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

于 2014-08-10T01:51:11.673 回答
0

这个答案完全是从根据上一个数据动态创建一个表单中的新页面复制而来的。页

使用该UiApp服务,您拥有一个doGet()和一个doPost()功能......但这是一种扩展它们以支持动态多部分表单的方法。(示例代码是从这个答案中借来的。)

doGet()只需构建表单的第 1 部分。但是,在表单中,您需要通过 name来标识您的表单,如下所示:

  var form = app.createFormPanel().setId("emailCopyForm");

然后,您doPost()会将 post 操作的处理传递给不同的函数,具体取决于已提交的表单。见下文。(还包括: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;
}

为了生成每个表单部分,后续的表单处理程序可以使用在前面的部分中检索到的数据来动态地将新的表单对象添加到 ui。

于 2013-07-15T13:01:03.497 回答