みんなに優しく、解りやすくをモットーに開設しています。 以下のルールを守りみんなで助け合いましょう。
1.ファイルメーカーで解らない事があればここで質問して下さい。 何方でも、ご質問・ご回答お願いします。 (優しく回答しましょう)
You are not logged in.
お世話になります
FMP19 Win10です。
FMPのコミュニティで適切か今一自信が有りませんがご容赦ください。
現在DBのフィールド内でJSONデータを管理していますが、
このデータを元にWebViewerでテーブル表示をさせるところで躓いております。
FMPからはWebViewer内のJS関数に対してJSONデータを引数に起動をかける部分は動いていて
データが無事に渡っているのですが、テーブル表示の更新がうまく行きません。
WebViewerの中のライブラリは諸事情でAlpinejs3を使っています。
転送後JS内の表示ボタンを押せば表示させられますが、転送だけで再表示したいのが要望です。
(このテーブル内で絞込みやデータ抽出をやってFMPに戻しています)
Alpineではx-dataディレクティブの内側=テーブルで表示するスコープ内でのデータ更新はそのまま
テーブル表示に反映されるのですが、今回のように外部(FMP等)から呼ばれる関数内で変数を
変更した場合にデータが変わってもテーブル更新ができずにハマっています。
変数をグローバルにして見たり、Alpie.storeを使ってみたりと色々やっているのですがうまく行きません。
データがそこそこ大きいためにテーブル表示はx-forを使っていてfor文でテーブルを一々再構成するパターンは避けたいです
因みに、FMPのレコードを単純にWebViewer上でテーブル表示する方法は分かっていますがfor文で構成するタイプでした
この辺りの知見がある方いらっしゃいましたら是非ともご教授お願いしたいです。
宜しくお願いします。
Offline
Alpinejs多用しています。
このコミュニティでの題材からは少し離れていて、かつこのライブラリーを日本で使われている方は極々稀ですのでなかなかコメントは付きにくいでしょう。自分はJQueryは使わずAlpine.js一辺倒ですが。
このようなケースでは、自分は基本的にリセット(最初からデータ組み立て)し、再構築する事が多いです。
x-dataで指定したオブジェクト内のメソッドは外部から(FileMakerから)は叩けないので、グローバルのAlpine.storeを使う場面もありますが、あまり分散させると管理が面倒になるので。
表示するデータ部分だけx-dataの外部に外出ししておいて、その部分を都度置換し、再度Alpine.init()関数でリロードさせればいいと思います。なかなかうまく説明できませんが。
Offline
Alpine.storeにx-data(以下ではalpineData)全体を入れると外部から変更できるはずです。
以下ではchangeFirstName(string)をFileMakerから叩けば変更が反映されると思います。
動かして確認はしていませんが、多分。
実際はその変更する部分は大きめの配列とかになっていると思うので、置換できるようにダミーテキストを配置しておいて、都度置換し、更新関数を叩くというパターンでどうでしょう。
<script>
document.addEventListener("alpine:init", () => {
Alpine.store("alpineData", {
lastName: "tanaka",
firstName: "taro"
});
});
//この関数を外部から叩くとfirstNameの値が反映される
const changeFirstName = (string) => {
Alpine.store("alpineData").firstName = string;
};
</script>
Offline
calafateさん、
返信ありがとうございます。
Alpinejsが未だ希少な上にバージョン3でやろうとしていることから経験者情報が極端に少なくて
苦労していました。chatGPTに聞くと、x-dataディレクティブの外からは表示の再起動はかけられない的な返答もあり、
Alpine.storeを使う案やグローバルを使う案等色々提案されて試しましたが、いずれもダメで・・ひょっとして経験者が
こちらにいらっしゃるかもと思い投稿してみました。Alpinejsは使ってみたところFMPのWebViewer上で扱いやすく感じ
今後も使っていきたいなと感じております。
明日ご提案の方法を試したいと思います。
Offline
Alpineは触ったこと無いですが...
転送後JS内の表示ボタンを押せば表示させられますが、...
という事なら、そのボタンに id を振って、
$id.click();
を実行するとか。
以下で実行できます。
Web ビューアで JavaScript を実行 [ オブジェクト名: "WEBビューア名"; 関数名: "(()=>{$id.click();})" ]Offline
qb_dp様、
コメントありがとうございます。
JS内のbuttonをFMPから呼べるという事でしょうか?
現状はFMPから転送したJSONデータは間違いなくHTML内の変数に格納されていて
問題は表示が更新されないというところだけです。
Javascriptを実行するだけかと思っていましたが、明日実験してみます
Offline
実際に記述されているコードサンプルを少し貼って頂ければ助かります。
更新関数もx-dataで指定したオブジェクト内ですよね?
Offline
更新関数もx-dataで指定したオブジェクト内ですよね?
HTML構造全体は以下のようになっています。(テストコードが混じっていてぐちゃぐちゃですみません)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Elapseit Viewer</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.17/tailwind.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.11.1/dist/cdn.min.js"></script>
<style>
</style>
<script>
/**テスト用json*/
var json5 = [{"value":[
{ "ID": 1, "Code": 'Code is here', "Name": 'Name is here', "Description":"json data" }
]}];
var jsonX = [{"value":[
{ "ID": 1, "Code": 'Code is here', "Name": 'Name is here' }
]}];
</script>
</head>
<body>
<div class="container">
<div
x-data="{
...
tableData: [],
...
}
}"
x-init="myXinit"
><!-- x-data定義ここまで-->
<!--
検索エリアの定義
-->
<div class="sticky top-0 z-50 bg-white">
<button @click="tableData = loadTableData(JSON.stringify(jsonX))" class="button">Show Projects</button>
</div><!--End of search box-->
<!--
テーブル定義
-->
<div class="table-container">
<table class="min-w-full divide-y divide-gray-200">
<thead class="table-header tracking-wider">
<tr>
</th>
...
</thead>
<tbody class="bg-white divide-y divide-gray-200 height-100px">
<template x-for="item in filteredItems()">
<tr>
</tr>
</template>
</tbody>
</table>
<script>
/**
x-data定義時の初期設定関数
*/
function myXinit() {
this.tableData = loadTableData(JSON.stringify(json5)); /*テーブルの表示するデータを初期化する */
console.log('tableData:',this.tableData);
}
/**
FilemakerからキックされるJS関数
*/
window.fmToWeb = function(inJSON) {
const inArray = convertJSONString(inJSON);
const sjson = JSON.stringify(inArray);
const newData = loadTableData(sjson);
jsonX = newData;
Alpine.store('tableData', newData);
return tableData;
}
/**
jsonで渡される引数をテーブルデータに設定する
*/
function loadTableData(inJSON) {
const json = JSON.parse(inJSON);
console.log('selected value of tableData:',tableData);
Alpine.store('tableData',tableData);
return tableData;
}
</script>
</div><!--End of table contents-->
</div><!--End of container-->
</body>
</html>
現状起動する(WebViewerページを表示)とテーブルヘッダとjson5の内容が表示されます。
その後FMPからjsonデータを転送し(その時点で表示更新はされない)
@clickでloadTableData()をやってあげると転送済みのjsonが表示されます。
最終目標はFMPからjson転送終了と同時にテーブル表示更新です。
Offline
以下で実行できます。
Web ビューアで JavaScript を実行 [ オブジェクト名: "WEBビューア名"; 関数名: "(()=>{$id.click();})" ]
なのですが、今遭遇している問題ですとボタン、alpineの場合は
<button @click="tableData = loadTableData(JSON.stringify(jsonX))" class="button">Show Projects</button>
で、このボタン自体は動作してテーブル表示更新しますがFMPから呼ばれる関数内でloadTableDataを呼んでもテーブル表示用データは更新できていてもテーブル内容表示が更新できないという問題なのでダメな気が・・・
基本的には変数スコープの問題な気はしているのですがまだわかっていません。
Offline
buttonタグに id='$btLoadTableData' を追加して、
<button id='$btLoadTableData' @click="tableData = loadTableData(JSON.stringify(jsonX))" class="button">Show Projects</button>FileMakerから以下で button をクリックできます。
Web ビューアで JavaScript を実行 [ オブジェクト名: "WEBビューア名"; 関数名: "(()=>{$btLoadTableData.click();})" ]Offline
その部分を都度置換し、再度Alpine.init()関数でリロードさせればいい
alpinejs3ではAlpine.Init()は廃止なんですよね?
残っているのはAlpine.data, Alpine.store, Alpine.bindだけで、あとはみんなディレクティブに行ってしまったようです。
x-initもディレクティブなんで、呼ぶといってもなんかわかりません(苦笑)
Offline
Web ビューアで JavaScript を実行 [ オブジェクト名: "WEBビューア名"; 関数名: "(()=>{$btLoadTableData.click();})" ]
このclick()部分は<button>内で呼ばれる関数の事だと思うのですが(今回だとloadTableData)
FMP関係なしにbutton内で実行してtableData[]にloadTableDataで変数を入れると動くのですが
button内でtableData[]に変数を入れる関数(loadTableDataを呼ぶ関数)を置くとテーブルが変わりません。
この辺が今回の問題の根本な気はします。
Offline
手動でクリックして動作するなら、
$btLoadTableData.click(); コレで動作する可能性が高いので試してみては。
Offline
FileMaker側から jsonX を書き換えて、
$btLoadTableData.click(); で、button をクリックすれば動作しそうな気がします。
Offline
FileMaker側から jsonX を書き換えて、
$btLoadTableData.click(); で、button をクリックすれば動作しそうな気がします。
なんと!!!動きました!!!
ありがとうございました!(半月の苦労は何だったのか...^^;)
Offline
qb_dp wrote:FileMaker側から jsonX を書き換えて、
$btLoadTableData.click(); で、button をクリックすれば動作しそうな気がします。なんと!!!動きました!!!
と、ぬか喜びしましたが、FilemakerCloudでは動作しないようです。
やはり根本的に考えないとだめかもしれませんね。
Offline
WebViewerは完全にクライアント上で動いてるので、サーバがクラウドでも関係ないはずですよね?
動作しないとしたら、大元のデータ生成部分とかクライアントの実行環境とか、全然別の原因だと思いますが...
WebViewerは完全にクライアント上で動いてるので、サーバがクラウドでも関係ないはずですよね?
動作しないとしたら、大元のデータ生成部分とかクライアントの実行環境とか、全然別の原因だと思いますが...
そうなんですが、FilemakerCloudに関してはアプリ版とで動作が違う現象が少なからずあります。
例えば、新規ウインドウにWebViewer表示を出そうとした場合カード型でしか表示できなかったり(これも今問題になってはいます)の現象が有ります。
とりあえず、簡単なボタンでFMCから叩けるかやってみます。
Offline
ん?
クラウドのクライアントに、ProでなくWebDirectを使ってるってことですか?
だとしたら、クラウドだからというのとはまた別の話ですが...
単純な数値の配列でサンプルを書きますと
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Elapseit Viewer</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.17/tailwind.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.11.1/dist/cdn.min.js"></script>
<style>
</style>
<script>
/**テスト用json*/
const json1 = [1,2,3,4,5]
</script>
</head>
<body>
<div class="container">
<div x-data="alpineData">
<ul>
<template x-for="item in tableData" >
<li x-text="item"></li>
</template>
</ul>
</div>
<script>
const alpineData = {
tableData: [],
init(){this.tableData = json1},
changeTableData(json) {
const data = JSON.parse(json);
this.tableData = data;
},
}
document.addEventListener('alpine:init', () => {
Alpine.store('alpineData', alpineData)
})
</script>
</body>
</html>
上のhtmlをwebビューワで表示させます。
テキストを挿入で変数$htmlに上記htmlをまるっとペーストしてください。
webビューワの設定でwebビューワのオブジェクト名を指定して、actionはurlへ移動として、$htmlを計算式の中に指定。
この状態で1,2,3,4,5と縦に並んで表示されているはずです。
もう一つスクリプトを作成して、
[0,1,2,3]
のように数値の配列を作成し、変数$arrayに入れておく。サンプルとして。
そしてwebビューワでJavaScriptを実行で以下の式を記入
"(Alpine.store(\"alpineData\").changeTableData)"
で、下段の引数に$arrayを指定。
このスクリプトを叩くと、webビューワ内の値が$arrayの中の数値の配列で表示されるはずです。
alpineの初期化関数init()はver3になって指定しなくても自動で実行してくれるようになっただけで、廃止ではないです。
x-dataの中のメソッドchangeTableDataを外部から叩くには
document.addEventListener('alpine:init', () => {
Alpine.store('alpineData', alpineData)
})
としてグローバルストアにalpineData自体を持たせます。そしてFileMakerから叩く時はAlpine.store(\"alpineData\").changeTableDataとしてメソッドを指定してあげればいいです。
これならボタンを設定する必要はなく、都度FileMaker内のデータを自由に表示できます。
あとはこれをテーブルとして組み立てればいいです。
私もここは結構悩んだ箇所ですが、上記のやり方でうまくいっています。
ちなみにFileMaker Cloud環境だから出来ないってのはないと思いますよ。
Offline
ん?
クラウドのクライアントに、ProでなくWebDirectを使ってるってことですか?
だとしたら、クラウドだからというのとはまた別の話ですが...
ProでデバッグしてWebDirectで運用してます。
わたしCloudと言ってたのはWebDirectです。
で、Proでの動作とWebDirectでの動作が(仕様上動かないと明記されているもの以外で)結構違うので
今回のclickもその系統かな?と思ったわけです。
Offline
私もここは結構悩んだ箇所ですが、上記のやり方でうまくいっています。
詳細なご指導ありがとうございます。
明日実験してみます。
Offline
WebDirectでWebViewerはiframe内になる(最近のバージョンは見てませんが、そこは変わってないと思います)ので、その点の違いが色々出ます。
calafateさんのサンプルのやり方で、FMPからストア内メソッドを叩いてテーブル表示更新できたのですが
やはりWebDirectでやろうとするとメソッドが叩かれないようです。
メソッドが叩けないとデータ転送もできていないので再表示ボタンを置いてもダメですよね…
Offline
自己レスです
WebDirectでやろうとするとメソッドが叩かれないようです
だったので、通常のJS関数でラップしてみたところ、WebDirectでもうまく動作しました。
Offline
[ Generated in 0.010 seconds, 9 queries executed - Memory usage: 639.34 KiB (Peak: 671.88 KiB) ]