Google Apps ScriptのHTML Serviceで擬似的に画面遷移【GAS】

Google Apps Scriptでは、ウェブアプリケーションを作れるわけなのですが、基本的には1ファイル1ページオンリーで、画面遷移というものが出来ません。スプレッドシート上で表示するダイアログなどでは、いくつものHTMLダイアログを表示は出来ますが、お互いは独立したページなので干渉が出来ません。その為、ウェブアプリケーションとして出力した場合には、出来ることとしたら、DIVの書換えで対処するしかありません。

しかし、その場合、1つのHTMLファイルが非常に冗長になり、長いコードを1ファイルに書かなければいけないデメリットが生じます。そこで今回の策は、複数のHTMLファイルをプロジェクト内に用意して、メインとなるHTMLより、コールバックでデータを呼び寄せて、それをdocument.getElementById().innerHTMLで、まるごと書き換えるという手法です。これならば、1つ1つのファイルは独立してるので、メンテナンスしやすく、擬似的に画面遷移が実現できます。

使用するメソッド・クラス、準備するもの

ソースコード

HTML Serviceを使った画面の入れ替え

createTemplateFromFileを使った事例。予め、起動時に2つのHTMLをGAS側から呼び出して於いて、アクションがあったら、innerHTMLで書き換えて遷移を実現します。getContentでHTML自体を取得させています。

今回はONE PAGE LOVEというサイトのテンプレートを二枚それぞれtest.htmlとtaro.htmlに入れてみました。CSSも呼び出してcreateTemplateFromFileでレンダリングさせています。

GAS側コード

//ウェブアプリケーション出力
function kinoko() {
  var html = HtmlService.createTemplateFromFile('page').evaluate()
      .setSandboxMode(HtmlService.SandboxMode.IFRAME);
  
  SpreadsheetApp.getUi().showModalDialog(html, "書換テスト");
}

//遷移先画面1 
function testman(){
  var html = HtmlService.createTemplateFromFile('test').evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME).getContent();
  return JSON.stringify(html);
}

//遷移先画面2
function testman2(){
  var html = HtmlService.createTemplateFromFile('taro').evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME).getContent();
  return JSON.stringify(html);
}
  • kinokoでまず本体を呼び出します。
  • testman, testman2はそれぞれ、kinokoで呼び出したtest.html内から呼び出される関数です。
  • 差し替えるHTMLをここで中身を受け取って返しています。それぞれは、別のHTMLファイルです(本体はpage.html、呼び出す側がtest.htmltaro.htmlそれぞれ用意しておく)。

HTML側コード(page.html)

<script>
 var app = "";
  var app2 = "";
  google.script.run.withSuccessHandler(onSuccess).testman();
  google.script.run.withSuccessHandler(onSuccess2).testman2();
  
  function onSuccess(data){
    app = JSON.parse(data);
  }
  function onSuccess2(data){
    app2 = JSON.parse(data);
  }  
  function test(){
   document.getElementById("test").innerHTML = app;
  }
  function test2(){
   document.getElementById("test").innerHTML = app2;
  }
  
</script>
<div id="test">
ここに差し替えるデータ
</div>
<a href="#" onclick="test()">書換1</a>
<a href="#" onclick="test2()">書換2</a>

doGetのパラメータで切り替え

こちらは起動時にGETにてパラメータを受け取り、そのパラメータによって画面を切り替える手法です。こちらの手法の場合、画面遷移だけでなく、Google Sitesにガジェットで貼り付ける時に、1つのプロジェクトで複数のガジェットを実現可能になる利点もあります。この仕組自体はGoogle Apps ScriptでGET・POSTにて一度紹介しています。

GAS側コード

//GETパラメータで画面分岐
function doGet(e) {  
  //セクションパラメータを受け取る
  var filterparam = e.parameter.section;
  var html;
  
  switch(filterparam){
    case "taro":
      var html = HtmlService.createTemplateFromFile('taro').evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
      break;
    case "test":
      var html = HtmlService.createTemplateFromFile('test').evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
      break;
  }
  
  //htmlを返す
  return html;
  
}
  • ウェブアプリケーションとして公開をしてテストをが可能です。
  • 公開URLにsection=testsection=taroと繋げることで、それぞれ違うページをロードしてくれます。これを画面遷移の遷移先として利用するわけです。
  • 変数などを渡したい場合には、スクリプトプロパティなどを利用して渡すと良いでしょう。

jQuery Mobileでのページ内遷移

今回トリッキーな方法、しかしモバイルの世界では割とポピュラーな手法として、ライブラリを使ったページ内遷移で擬似的に画面遷移を実現してみました。複数のHTMLを用意せず、1枚のHTML内でセクションを用意し、それらをライブラリの力で画面遷移用に切り分けて表示する仕組みです。

GAS側コード

function sectionman() {
  var html = HtmlService.createTemplateFromFile('transition').evaluate()
      .setSandboxMode(HtmlService.SandboxMode.IFRAME);
  
  SpreadsheetApp.getUi().showModalDialog(html, "切り替えテスト");

HTML側コード(transition.html)

<!DOCTYPE html> 
<html> 
  <head>
    <link rel="stylesheet" href="https://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.css" />  
          <script type="text/javascript" src="https://code.jquery.com/jquery-1.5.min.js"></script>
    <script type="text/javascript" src="https://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.js"></script>
  </head> 
  <body> 
    <!--最初に表示されるページ -->
    <section id="page1" data-role="page">
      <header data-role="header" data-add-back-btn="false"><h1>パッションフルーツの魅力</h1></header>
      <div class="content" data-role="content">
        <p>
        パッションフルーツとは、まだ世間一般では流通していない南国フルーツです。<br>
        しかし、東京でも栽培が可能で、関東では千葉県や八丈島などでも栽培されてるフルーツです。しかし、このフルーツ暑さに弱いという性質がある。<br>
        けれど、1年に2回収穫が可能で、なおかつ他の作物にくらべて、病気にかかりにくく害虫も少ない。<br>
        主に生食が中心だけれども、その葉っぱもお茶として利用でき、種は絞れば非常に良い油が手に入ります。
        </p>
        <p><a href="#page2">いちごの魅力を知りたい</a></p>
      </div>
      <footer data-role="footer"><h1>jQueryで疑似画面遷移</h1></footer>        
    </section>
    
    <!--次に表示されるページ -->
    <section id="page2" data-role="page">
      <header data-role="header" data-add-back-btn="false"><h1>いちごの魅力</h1></header>
      <div class="content" data-role="content">
        <p>
        いちごは、主に寒い地方で栽培される草の実。フルーツとしては非常に身近な存在です<br>
        しかし、暑い地域では栽培が難しく、また、冬の寒さを経験しないと翌年花を咲かせない特徴があるため、暑い地域では食味の劣る四季成りいちごが栽培の中心<br>
        主に栃木県や福岡県が栽培の名所であるが、静岡や千葉、徳島などでも盛んに栽培され、世界一の品種改良が進められている。
        バラ科の植物なので害虫も多く、また、疫病にも弱いため、非常に手間の掛かるフルーツでもある。<br>
        けれど、ベランダ農園も可能なほど手軽な植物でもあるので、おすすめしたい一品。
        </p>
        <p><a href="#page1">パッションフルーツの魅力</a></p>
      </div>
      <footer data-role="footer"><h1>jQueryで疑似画面遷移</h1>
      </footer>
    </section>
  </body>
</html>
  • sectionにIDを振り、jQuery Mobileの力で、2枚のページを実現しています。
  • ページ間はそれぞれのIDつまりアンカーの指定で移動します。
  • もちろん、hrefに別のHTMLやURLを指定すれば、移動することは可能です。

ポイント

  • createTemplateFromFileの場合にはスクリプトレットが使用できますが、createOutputFromFileの場合には使用することができません。
  • 呼び出す時に今回はTemplateFromFileなので、evaluateしてます。結果はJSONで受け渡しをしてますが、OutputFromFileの場合には、JSON関係なく、直接returnすれば表示できると思います。
  • HtmlService.SandboxMode.IFRAMEならば様々なライブラリが利用できます。そうでない場合にはjQueryなどの限定された機能だけしかライブラリは使用できないことを念頭に於いて呼び出しましょう。
  • CSSやJavaScriptもHTMLファイルとして分離してスクリプトレットなどで直接位置を指定して呼び出せます。
  • いずれの場合でも、.getContent()メソッドで中身を表示するのではなく、変数に取得しています。それをreturnで返して、page.htmlに反映しています。
  • 今回は、test.htmlもtaro.htmlも少ない内容なので、直接書き換えるのと見た目は変わりませんが、本格的なウェブアプリケーションを作るときには効果を発揮します。2ペインや3ペインのUIで作ると良いと思います。
  • この他にFramework7というGUIフレームワークを使ったインライン画面遷移を使うテクニックもあります。

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)