0

私の理解では、Google Apps Script アプリケーションで一意の doPost() をトリガーできる doGet() は 1 つだけです。

ユーザーがファイルをアップロードするか、フォームにリビジョン情報を入力して送信を次のステップにプッシュするソフトウェア発行システムを実行したいと思います。最後のページには、入力情報が表示され、男性にメールが送信され、すべての操作が完了します。

しかし、送信ボタンが押された後に次のフォームに入力するにはどうすればよいですか?

次のコードのように、 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;    
}
4

3 に答える 3

0

まず、モグスダッドに敬意を表します。彼の投稿は、私をここに導いた暗く文書化された道のガイドライトでした. これは、複数ページのフォームを示す実際のコード です。つまり、最初のフォームを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の を使用して、ユーザーがフォーム シーケンスを前後に進めたり、フォームの内容を検証したりできるようにします。2 つの余分なは、フォーム送信前に非表示の状態を変更するだけの をSubmitButton使用して「再配線」されます。ClientHandler

ノート

  • .setText(value)クライアント ハンドラでのメソッドの使用に注意してください。Chrome ブラウザーを使用して、またはメソッドTextBoxのいずれかに切り替えると、奇妙なランタイム エラーが発生します。.setValue(value).setValue(value, fireEvents)

  • Script Property非表示の TextBoxの代わりに を使用して、このロジックを実装しようとしました (失敗しました) 。これには、クライアント ハンドラーの代わりに、サーバー ハンドラーを使用する必要があります。動作が不安定で、フォーム送信イベントの後に非同期のサーバー側イベントが発生していることを示唆しています。

于 2014-08-10T01:51:11.673 に答える
0

この回答は、前のデータに基づいて、フォームに新しいページを動的に作成することから完全にコピーされます。ページ

このUiAppサービスを使用するdoGet()と、1 つのdoPost()機能が得られますが、これらを拡張して動的なマルチパート フォームをサポートする方法を次に示します。(コード例はこの回答から借用されています。)

フォームのpart1doGet()をビルドするだけです。ただし、フォームでは、次のように名前でフォームを識別する必要があります。

  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 に動的に追加できます。

于 2013-07-15T13:01:03.497 に答える
0

必要なすべての項目を含む doGet 関数で 3 つ (またはそれ以上) の異なるパネルを使用し、それらの可視性を操作する方が簡単だと思います。

最初は最初のパネルのみが表示され、ユーザー入力に応じて (クライアント Handlers を使用してそれを処理します)、次のパネルが表示されます (最終的に最初のパネルが非表示になります)。

最終的に、送信ボタンは doPost を呼び出し、doGet からすべてのデータを取得します。

于 2013-07-15T12:07:38.433 に答える