2017-06-12 9 views
0

私はこの問題を抱えています...私はドキュメントを読んでいますが、できません。サイドバーのhtmlフォームからgoogleスクリプトに値を渡す

私はGoogleドキュメントのサイドバーに小さなHTMLフォームを作成したいと考えています。 このフォームで連絡先グループが連絡先からプルされ、ユーザーはこれを選択してスクリプトに渡すことができます。

これは私がやったことです:私は上をクリックすると

Page.html

<!DOCTYPE html> 
<html> 
    <head> 
    <base target="_top"> 
    </head> 
    <body> 
    Hello, world! <input type="button" value="Close" onclick="google.script.host.close()" /> 
    </body> 
</html> 

menu.gs

function doGet() { 
    return HtmlService 
     .createTemplateFromFile('Page') 
     .evaluate(); 
} 

function onOpen() { 
    DocumentApp.getUi() // Or DocumentApp or FormApp. 
     .createMenu('Custom Menu') 
     .addItem('Show sidebar', 'showSidebar') 
     .addToUi(); 

} 

function showSidebar() { 

    var html = HtmlService.createHtmlOutputFromFile('Page') 
     .setTitle('Chose the Contact Group') 
     .setWidth(300); 

    var groups = ContactsApp.getContactGroups(); 

    // add this to the html file Page.html 
    html.append ('<form onsubmit="google.script.run.myFunction(formObject)">'+ 
       '<select>'); 

    for (var i = 0; i < groups.length; i++) { 
    html.append('<option name="chosenGroup" value="' + groups[i].getName() + '">' + groups[i].getName() + '</option>'); 
    } 

    html.append('</select><input type="submit">'); 

    //this is commented because I was testing it 
    //html.append("<script>function handleFormSubmit(formObject) { google.script.run.myFunction(formObject); } </script>"); 

    DocumentApp.getUi() // Or DocumentApp or FormApp. 
     .showSidebar(html); 

} 

Code.gs

myFunction (formObject) { 

Logger.log(formObject.chosenGroup); 

} 

を送信ボタンを押すと新しい空白ページが開き、次のようなURL:

https://n-wuewuewuee98efgdsf98769s8d76f9s76df-0lu-script.googleusercontent.com/userCodeAppPanel

答えて

2

これは 'form'タグの 'action'属性のために起こります。フォームを送信すると、ブラウザは 'action'属性で指定されたルートにリダイレクトされます。通常、このURLパターンは、フォームで投稿されたデータを受信するサーバー上のコードにマップされます。

最初に対処する必要がありますあなたのコード内の他の問題があります。

1)のdoGet()関数を使用すると、Webアプリケーションとしてスクリプトを展開する場合にのみ必要とされているが。 doGet()のコードは、ブラウザでそのアプリのURLを開くと、つまりアプリに「GET」リクエストを送信すると実行されます。あなたのスクリプトは文書にバインドされているので、doGet()の必要はありません。

2)ビジネスロジックを分離してください。 showSideBar()は、それが行うべきもの、つまりサイドバーを表示するだけでなければなりません。

3)変数をHTMLページに渡し、テンプレート化されたHTMLを使用して動的にUIを作成できることを覚えておいてください。行ごとに行を追加する必要はありません! https://developers.google.com/apps-script/guides/html/templates

4)最後に、別のページへのリダイレクトは、jQueryを使用することで簡単に解決できます。

下記のサンプルコードを参照してください。私のスクリプトはスプレッドシートにバインドされていたので、SpreadsheetAppをDocumentAppに置き換えてください。

Serverコード(main.gs)

function onOpen(){ 

var ui = SpreadsheetApp.getUi(); 

ui.createMenu('Menu') 
    .addItem('Show sidebar', 'showSidebar') 
    .addToUi(); 


} 


function showSidebar() { 

var ui = SpreadsheetApp.getUi(); 
var template = HtmlService.createTemplateFromFile('sidebar'); 

template.contactGroups = getContactGroups(); //adding contactGroups as a property of the template object. 

ui.showSidebar(template.evaluate()); //Calling evaluate() executes the inline JS code in sidebar.html, populating the dropdown list 


} 

function getContactGroups(){ 

try { 

var contactGroups = ContactsApp.getContactGroups(); 

} catch(error) { 

Logger.log(error); 

} 

return contactGroups; 

} 

function processFormResponse(formObject){ 


Logger.log(formObject.chosenGroup); 



} 

そして、ここではsidebar.htmlです。 htmlファイル内のインラインコードの特別な構文に注意してください。 e.preventDefault()を呼び出すと、別のページへのリダイレクトが処理されます。テンプレートオブジェクトにcontactGroupsをプロパティとして追加するので、evaluate()が呼び出されたときにこの変数を使用できます。以下のインラインコードは、ドロップダウンリストにグループ名を動的に設定します。

<!DOCTYPE html> 
    <html> 
     <head> 
     <base target="_top"> 
     </head> 
     <body> 
     Hello, world! <input type="button" value="Close" onclick="google.script.host.close()" /> 

     <form> 
     <select name="chosenGroup"> 

     <? for (var i=0; i < contactGroups.length; i++) { ?> 

     <option value="<?= contactGroups[i].getName()?>"><?= contactGroups[i].getName()?></option> 


     <?}?> 
     </select> 
     <input type="submit" value="Submit"> 
     </form> 



     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
     <script> 

     $(document).ready(function(){ 

       $('form').submit(function(e){ 

       e.preventDefault(); 

       google.script.run.processFormResponse(this); 


       }); 


     }); 

     </script> 


     </body> 
    </html> 

UPDATE

のjQueryについての特別なものは何もありません。これは、DOMツリーを簡単にナビゲートできるように設計されたJSライブラリですが、ブラウザ内の同じDOM APIの上に構築されています。要するに、この結果を得るためにjQueryは必要ありません。 1) 'フォーム'タグに一意のIDを割り当てます(例:

<form id="form"> 

2) 'submit'イベントをリッスンするフォームにイベントリスナーを追加する関数を作成します。 2番目の引数はイベントハンドラ関数です。 'submit'の代わりに 'click'を使用すると、idでテキストフィールドを参照してユーザー入力を取得することによって、フォームオブジェクトを手動で作成するよう強制されます。

<script> 
     function addEventListeners() { 

     document.getElementById('form').addEventListener('submit', function(e){ 

     e.preventDefault(); 
     google.script.run.processFormResponse(this); 


     }); 



     } 
     </script> 

最後に、この関数を読み込み時に呼び出します。

<body onLoad="addEventListeners()"> 

私の前の例のjQueryコードはまったく同じことでしたが、はるかに読みやすく維持しやすいものでした。

+0

ありがとうございましたAntonさん、それは動作していますが、私はここでjqueryが必要な理由を理解できません。「google.script.run.processFormResponse(this)」を追加することはできません。オンリックで?私はこのページを誤解しているかもしれません:https://developers.google.com/apps-script/guides/html/communication#forms(ウェブアプリケーションのためのフォームスクリプトです。) – Kintaro

+0

更新された答えをご覧ください。 –

関連する問題