FileMakerでQRcodeを生成してみます。
テーブルは1個
フィールドはこれだけ。
「えっ!QRcodeを生成するテーブルとデータテーブルを分けないの?」
はい、分けません。
だって、生成側の源泉になるのがグローバルフィールドですし、リレーションやポータルのオーバーヘッドが無いし、スクリプトやレイアウトが1つのテーブル内で完結してるから印刷とか、後々一括生成とかも楽に作りたいから。
あと、APIも使いません。
それはPCやGOとかローカル環境も想定しているからです。(今回のは繋いだ状態)DCN方法はサンプルファイルに記載しています。
なによりもメンテが楽です。
今回は住所をQR化しています。
ダウンロード(win11,FMP19.6以降)
(すみません、デザインとか何も考えてません)
ということで、簡単な流れを書きます。
①JavaScriptのQRcode生成ライブラリを読み込む。もしくはDCNで埋め込む。
②①で生成させたQRは一時的にWebビューアーに表示させる。
(FileMakerでダイレクトにQRコードを画像化させることはできません)
③DOM(ドム) = Document Object Model側に描画された後にPNG化して画像として表示させる。(SVGやCanvas化されたものをBase64形式に変換する)
①JavaScriptのQRcode生成ライブラリを読み込む。もしくはDCNで埋め込む。
についてですが、ローカルで使う場合は読込先のコードをまるっきし埋め込んで使ってもよいと思います。
で、今回のqr-code-stylingという読込先。
FileMakerとの相性はいい方だと思いますよ。
昔からある GitHub: davidshimjs/qrcodejs については
もう少しJavaScriptの知識が無いとFileMakerとの連携が難しいです。
JavaScript側に「FileMakerへの指示(スクリプト呼び出し)」を明示的に組み込まないと、FileMakerとの連携は行われません。Base64変換も FileMakerへのデータ返却もなにもされないので、JavaScript側からFileMaker側に引数を取らせてLOOPさせるとか、けっこう大変です。
工数ばかりかかるし、レイアウトをまたぐと意外と厄介だったりするので、同テーブルにqr-code-stylingなら20分作業!みたいな感じでいいのかと思います。
DATA::g_QRテンプレートHTML
これにhtmlを入れます。htmlの中身は省略します。
サンプルにはJavaScriptのコメント入れてありますのでご参考に。
Webビューアーには
DATA::g_住所QR
これだけ入れておきます。
g_QRテンプレートHTML
(これにhtmlの中身を入れておく)
FileMakerのスクリプトで
DATA::g_住所QRにg_QRテンプレートHTMLの中身を渡す。
webビューアーに表示させる。
Base64でPNG画像に変換してWebビューアーの表示を消す。
ここでFileMaker側のスクリプトは2つ必要となります。
QR_webビューアーに表示
qrcode (JavaScript側で動かすのでスクリプト名は変えないように)
QR_webビューアーに表示について
今回は住所をQR化しているので、QRを読み込んだ後、GoogleMAPで開きます。
FileMaker側のスクリプト
変数を設定[$mapURL;値:
Substitute (
"https://www.google.com/maps?q=" & GetAsURLEncoded ( DATA::住所 ) ;
"'" ; "%27"
)]
の"%27"は 16進数でのASCIIコード 0x27
= 10進数で 39
ASCIIコード 39番は → シングルクォート '
大事なのはスクリプト内の
変数を設定[ $html ; 値 : Substitute ( $template ; "<<MAP_URL>>" ; $mapURL )]
ですね。
これはg_QRテンプレートHTML内の"<<MAP_URL>>"をFileMaker側の住所データに置き換えているってことです。
<<MAP_URL>>
FileMakerなどでスクリプトから置換されるプレースホルダの事です。
しかし、本来は
DATA::g_QRテンプレートHTML内に
htmlのbody内でいうと
<div id="qrcode"></div>
<script>
const qr = new QRCodeStyling({
width: 300,
height: 300,
data: "", // ← 初期データは空(doItからセット)
image: "",
dotsOptions: { color: "#000", type: "square" },
backgroundOptions: { color: "#fff" },
qrOptions: { errorCorrectionLevel: "L" }
});
function doIt(mapURL) {
// URLをセットしてQRコード更新
qr.update({ data: mapURL }); //ここで遅くなる
// QRコード描画(1回のみ)
const target = document.getElementById("qrcode");
target.innerHTML = ""; // ← 再生成時の二重描画防止
qr.append(target);
// 少し待って画像として取得 → FileMakerに渡す
setTimeout(() => {
qr.getRawData("png").then(blob => {
const reader = new FileReader();
reader.onloadend = () => {
const base64data = reader.result.split(",")[1];
if (window.FileMaker) {
FileMaker.PerformScript("qrcode", base64data);
}
};
reader.readAsDataURL(blob);
});
}, 300);
}
</script>
にするのですが、
ちょっと処理が遅く感じます。
qr.update({ data: xxx })は、一度オブジェクトが生成された後に、値を書き換えて、再描画して〇〇という処理になるので、任意のタイミングをとってQR変換させるにはいいけど、一回っきりの<<MAP_URL>>にした方がダイレクトで処理は速いし、一括でLOOP発行させるときも楽。FileMakerっぽくて好きかなと。
なので、html全文
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>QR</title>
<script src="https://cdn.jsdelivr.net/npm/qr-code-styling@1.5.0/lib/qr-code-styling.js"></script>
</head>
<body style="margin:0;display:flex;justify-content:center;align-items:center;height:100vh;">
<div id="qrcode"></div>
<script>
const qr = new QRCodeStyling({
width:300,
height:300,
data: "<<MAP_URL>>", //ここにダイレクトにデータを読み込ませ
image: "",
dotsOptions: { color: "#000", type: "square" },
backgroundOptions: { color: "#fff" },
qrOptions: { errorCorrectionLevel: "L" } // LとかMとかHとか
});
qr.append(document.getElementById("qrcode"));
// Base64エクスポートしてFileMakerに渡す
setTimeout(() => {
qr.getRawData("png").then(blob => {
const reader = new FileReader();
reader.onloadend = () => {
const base64data = reader.result.split(",")[1];
if (window.FileMaker) {
FileMaker.PerformScript("qrcode", base64data);
}
};
reader.readAsDataURL(blob);
});
}, 500); // SVG生成完了後に画像化
</script>
</body>
</html>
Web ビューアで JavaScript を実行 [ オブジェクト名: "Web" ; 関数名: "doIt" ; 引数: $mapURL ]
qr
オブジェクトの初期化時にすでに済んでいるのでエラーにはならず条件付きで動くんです。関数名: "doIt" は動いていないけど、取ってしまうと全く動かなくなる。
サンプルですが、グローバルフィールド内のhtml文が丸ごと消えていたら
下に「万が一html復活」というボタンを用意しましたので復活してください
0 件のコメント:
コメントを投稿