Javascript計算エンジンとしてのWebビューア

FileMaker Pro 8.5で導入されたWebビューアは、単にGoogleマップを表示するための窓というだけではありません。FileMakerとWebの標準技術をつなげる重要な機能の一つであり、今でも進化を続けています。
今回はSeedCodeのJason Youngさんのブログ記事を紹介します。


seedcode logo

Javascript計算エンジンとしてのWebビューア
The FileMaker Web Viewer as a Javascript Calculation Engine (CSV to JSON example)


2014/4/29

FileMaker 13v2のアップデートでは、fmp:プロトコルがすべての展開方法で利用可能になったことが話題になりました。以前は、ローカルで実行されているファイルでは、Goやサーバでホストされた場合とは異なる挙動をしていました。そのために、この強力な新機能を使うことを躊躇する場合があったかもしれません。

しかしようやくこの例のようにその機能をフルに活用できるようになりました。今後はますます多くのデベロッパーがユーザインターフェイス(やその他)の機能をWebビューアで実装するようになると予想しています。

この方法はとても理にかなっています。Javascriptは今最盛期にあり、多岐にわたるフリーのライブラリが整備され、あらゆる場面で利用されるWebブラウザのユーザとのインタラクションを操っています。FileMakerのモジュール性の弱さに不満を持つデベロッパーは多いですが、この技術はその状況を変える可能性の一つだということができるでしょう。FileMakerソリューションにこの豊富な財産を利用しなければ、貴重な機会を失うことになります。

しかし、強力なユーザインターフェイス機能だけが、Javascriptを使うメリットというわけではありません。Javascriptで書かれた豊富なデータ処理用ツールを手に入れることができ、それをWebビューアを使って簡単にFileMakerに組み込むことができます。性能的には純正のスクリプトや計算式と同レベルの強力な機能を持たせることが可能です。これは元々同僚のTanner Ellenから聞いたアイデアでした。その時はピンと来なかったのですが、ようやく理解することができました。

最初、JavascriptライブラリをWebビューアに読み込む枠組みを準備するのに少し手間がかかりますが、ひとたびそれを解決してしまえば、さらにライブラリを追加して新しい機能を利用できるようにするのは、Webでカスタム関数を参照するのと同じくらい簡単になります。

サンプルファイルをダウンロード:FM2JSON.fmp12

Webビューアと簡単なJavaScriptを使ってFileMakerデータをJSON形式に変換する例を見てみましょう。

このサンプルでは、Githubで見つけた2つのJavaScriptライブラリを利用しています。1つ目は、

https://github.com/cparker15/csv-to-json

で、それがさらに次のライブラリを参照しています。

https://github.com/douglascrockford/JSON-js/blob/master/json2.js

csv-to-jsonを少し修正して、呼び出す関数を1つ追加しましたが、コードを特に深く理解する必要はなく、わずか数分で書くことができました。json2は修正していません。

ライブラリを展開する

これらのライブラリをWebビューアのHTMLに読み込ませる方法はいくつかあります。私の場合は、tempディレクトリへそれらをエクスポートして外部参照するようにしています。メインのHTMLからそれを参照する形にすることで、HTMLが複雑にならず読みやすくなります。もちろん、ライブラリ全体をHTML本体に単純に挿入する方法もあります。

私は、DBファイルにレイアウトを作成して、そこにライブラリを静的なテキストとして貼り付け、名前をつけます。そして、GetLayoutObjectAttribute ( <objectname> ; “Content” ) でライブラリのテキストを取得してグローバルフィールドに挿入し、.jsの拡張子のファイルをtempディレクトリにエクスポートし、ファイルパスを変数に設定します。変数の値は次のようになります。

“<script src=\"file:///private/var/.../csvtojson.js\" type=\"text/javascript\"></script>
<script src=\"file:///private/var/.../json2.js\" type=\"text/javascript\"></script>”

HTMLに埋め込むインライン方式の場合は、関数から直接HTMLにテキストを挿入できます。

HTMLテンプレートを作成する

ライブラリをtempディレクトリにエスクポートしてファイルパスを変数に設定したら、データ処理用のWebビューアに設定するHTMLテンプレートを組み立てることができます。私はそれをグローバルフィールドに書き込む方法を好んで使いますが、その方がデータビューアでグローバル変数を見るよりも読みやすくできるからです。ですが、どちらの方法でも問題ありません。

ここで使用するHTMLテンプレートはかなりシンプルです。

data:text/html, 
<!DOCTYPE html> 
<html lang="en"> 
<head> 
<script src="file:///private/var/folders/.../csvtojson.js" type="text/javascript"></script> 
<script src="file:///private/var/folders/.../json2.js" type="text/javascript"></script> 
<script type="text/javascript"> 

var mydataRaw = "<<MYDATA>>"; 
var mydata = csvToJson(mydataRaw) ; 
var p = encodeURIComponent(mydata) ; 
var url = "fmp://$/FM2JSON?script=WriteJSON&param=" + p ; 
window.location = url ; 

</script> 
</head> 
</HTML>

すべてのアクションは<head>内のJavascriptにあります。該当部分の5行を順に見ていきましょう。

var mydataRaw = "<<MYDATA>>";

この行は変換したいCSVデータのための変数を宣言しています。これはテンプレートで文字列の<<MYDATA>>をプレースホルダーとして使用しています。CSVデータを取得したらこの値を置き換えてWebビューアにHTMLを送ります。

var mydata = csvToJson(mydataRaw) ;

この行ではCSVデータをcsv-to-jsonライブラリの関数に渡し、結果をmydataという別の変数に代入しています。この時点でJSONが取得できたので、それをFileMakerに返します。

var p = encodeURIComponent(mydata) ;

fpm:// URLプロトコルを使用して、取得したJSONを引数としてFileMakerファイルの中でスクリプトを実行します。これはURLなので、JSONをエンコードする必要があります。Javascript関数のencodeURIComponentは、FileMakerのGetAsURLEncoded関数と似ています。この行はJSONをエンコードして、新しく宣言された変数pに代入しています。

var url = "fmp://$/FM2JSON?script=WriteJSON&param=" + p ;

次にFileMakerスクリプトを実行するためのURLを組み立てて、変数urlに代入します。  FM2JSONはFilemakerファイルの名前です。このテンプレートをFileMakerで生成しているので、“fmp://$/” & Get ( ファイル名 ) & “?.. という計算式でURLを組み立てることでスクリプトの可搬性が多少向上します。“$”は、これがローカルファイルであることを意味するので、ホストされているファイルの場合は不要です。WriteJSONはスクリプト名で、その中身は1行だけでスクリプト引数をグローバルフィールドに書き込みます。

window.location = url ;

これでURLができあがったので、Javascriptの標準のオブジェクトであるwindow.locationを使用してURLを読み込んでスクリプトを実行します。以上で終わり…ではありません。

Internet ExplorerのURLの制限

残念ながらInternet ExplorerにはURLの文字数制限があり、URL全体で2083文字、パス部分が2048文字となっています。これはFileMakerにfmp:プロトコル経由で引数を送り返すときに大きな制限になります。今回のJSONのサンプルでは、2083文字では検索結果どころか1レコード分のデータを保持するにも不十分です。しばしネットで調べたり頭を悩ませた結果、ある回避方法を見つけることができました。IEは他のブラウザとは違い、以下のようにclipboardDataオブジェクトを使用することで、ダイアログを出さずにシステムのクリップボードとやりとりができるのです。

window.clipboardData.setData( 'Text' , mydata );

これによって、URLに大きな引数を付けることで悩むことなく、単にクリップボードの内容をグローバルフィールドにペーストするスクリプトを呼び出すだけでよくなりました。つまりWindows用のJavascriptは以下のようになります。

var mydata = csvToJson(mydataRaw) ;
var url = "fmp://$/FM2JSON?script=WriteJSON"
window.clipboardData.setData( 'Text' , mydata );
window.location = url ;

クリップボードを使用するのは最善の方法ではないかもしれませんが、Windows上のFileMakerでデータを返せるようにするための、今のところ我々が見つけた唯一の解決策です。

CSVを取得する

最初にCSVを取得するためにFileMakerを使用します。それをテンプレートの<<MYDATA>>と置き換えて、テンプレートのHTMLでWebビューアを設定します。ExecuteSQLは、FileMakerの計算式に使用するCSVを生成するのに一番簡単な方法で、この手法は元々はSQLExplorerのWebビューアポータルを作成するために考え出されました。また私は、現在の検索結果をCSV形式でtempディレクトリにエスクポートした後に「URL から挿入」を使用してCSVをFileMakerのグローバルフィールドに書き込むという手法も好んで使います。エスクポート時にFileMakerが付ける余分な引用符をsubstitute関数で削除しなくてはいけないという手間はありますが、それ以外は問題なく動作します。

サンプルファイルをダウンロード:FM2JSON.fmp12

今回紹介したのは、FileMakerのソリューションに外部のスクリプトと計算機能を利用する小さなサンプルですが、この方法によって実現できることは無限です。今度もし、再帰をネストしたカスタム関数の大作をゼロから書く機会があったら、一度GithubかStack Overflowをさっと検索して、誰かがすでにその問題を解決していないか確認してみてはいかがでしょうか?

追記:この記事の「パート2(元の英文記事)」をここから参照してください。

Leave a Reply