クリック画像の実寸表示

段ボール箱を机にした猫 ファイルメーカー(filemaker)のちらしの裏のメモ書き

TOP  >  FileMakerでDrag&Dropを実現する
作成日:2025年06月09日

FileMakerでDrag&Dropを実現する

イメージイラスト
にゃん太

どうも、にゃん太です

先日、FileMakerでもDrag&Dropで操作したいという要望がありました

そうした操作へは対応してこなかったので、この機会に少し調べてみたいと思います

今回のメモでは、FileMakerで実行可能なDrag&Dropについて書いていきます


テキストのDrag&Drop

FileMakerは、テキストのDrag&Dropに対応しています
選択した内容を別のフィールドへドロップすると、内容が複製して登録されます
この時、テキストフィールド以外では、上書きされてしまいます
テキストフィールドは指定の場所へ差し込みを行います


この処理で注意したい点が2つあります
一つは、「取り消し」ができない事です
テキストフィールドであれば、ドロップされた情報を破棄すれば復元は可能です
しかし、それ以外のフィールドでは値が上書きされてしまい、元の情報に戻す事ができません
もう一つは、強制保存される点です
「レコードの変更を自動的に保存する」のチェックを外しておいた場合でも、自動的にドロップされた結果が保存されいます
これは、同一レコードの場合は「保存しない」で元に戻す事ができます
しかし、別のレコードや別のアプリケーションなどからドロップした場合は何故か保存されてしまい、メッセージも表示されません
個人的には誤操作が怖いので、ドラッグ&ドロップの許可を外す事を推奨しています

Drag&Dropの禁止
これでも外部からのドロップは禁止できませんが、誤操作リスクは大きく下がると思います

オブジェクトのDrag&Drop

項目を分けましたが、基本的にはテキストのDrag&Dropと同じです
異なるフィールドへオブジェクトを複製する事ができます
違う点としては、オブジェクトフィールド以外へのドロップが行えない点があります
テキストのDrag&Dropの場合は、ドロップされた後に入力規則のチェックによりエラーメッセージが表示されましたが、オブジェクトの場合はドロップ自体を受け付けません
他には、「選択テキストのドラッグ&ドロップを許可する」のチェックを外していてもDrag&Dropを実行できる点です
この機能は、写真データの取り込みを行う場合や、外部ファイルのインポートを行う場合に便利に使用できます
他にも、例えばこちらのサイトの様に工夫すれば、色々な事ができそうです

Webビューアを使用したDrag&Drop

FileMakerで実行できる基本的なDrag&Dropを説明してきましたが、複雑な処理を行おうと思うと、色々と機能面で不足する事があります
そんな時は、Webビューアを使用してJavascriptで実現する方法もあります
今回は、基本的なやり方を説明していきます
オブジェクトを移動できる様にする
まずはオブジェクトを移動させてみましょう
HTMLに配置したオブジェクトは、基本的には動かせません

HTML

<!DOCTYPE html> <html lang='ja'> <head> <meta charset='UTF-8'> <meta http-equiv='content-language' content='ja'> <meta name='viewport' content='width=device-width, initial-scale=1.0, user-scalable=1'> </head> <body> <div id='dragBox'> <div id='dragObject' class='obj'></div> </div> </body> </html>


動かすにはその為のスクリプトを記述する必要があります
方法は色々ありますが、クリックイベントを基軸に考えてみましょう
単純ですが、こんな動きを作成してみましょう

Javascript

const obj = document.getElementById('dragObject'); var drag = false; var position = { x: null, y: null }; obj.addEventListener('mousedown', function(e){ drag = true; position.x = e.clientX; position.y = e.clientY; }); obj.addEventListener('mousemove', function(e){ if(drag){ obj.style.top = parseInt(window.getComputedStyle(obj).top) + e.clientY - position.y + 'px'; obj.style.left = parseInt(window.getComputedStyle(obj).left) + e.clientX - position.x + 'px'; position.x = e.clientX; position.y = e.clientY; } }); obj.addEventListener('mouseup', function(e){ drag = false; position = { x: null, y: null }; });


枠外に出た場合などのエラー処理は出来ていませんが、オブジェクトのドラッグは出来る様になりました
とはいえ、こんな風に動かすだけの処理を作る事はあまりないでしょう
もう少し、実用性のありそうな動きを考えてみましょう
どうでしょうか
これなら、応用次第で実用的な処理になりそうです
もう少し、動作を詰めてみましょう
そのまま使える処理ではなさそうですが、応用は出来そうです
この処理を作成してみましょう

Javascript

const basePosition = [ {x:5, y:5}, {x:65, y:5}, {x:125, y:5}, {x:185, y:5}, {x:245, y:5}, ]; var drag = [false, false, false, false, false]; var position = { x: null, y: null }; const targetBox = document.getElementById('target'); const targetPosition = { xs: targetBox.offsetLeft, xe: targetBox.offsetLeft + targetBox.offsetWidth, ys: targetBox.offsetTop, ye: targetBox.offsetTop + targetBox.offsetHeight, }; const objs = document.getElementsByClassName('obj'); for(let i = 0; i < objs.length; i++){ objs[i].style.top = basePosition[i].y + 'px'; objs[i].style.left = basePosition[i].x + 'px'; objs[i].addEventListener('mousedown', function(e){ drag[i] = true; position.x = e.clientX; position.y = e.clientY; objs[i].style.zIndex = 10; }); objs[i].addEventListener('mousemove', function(e){ if(drag[i]){ objs[i].style.top = parseInt(objs[i].style.top) + e.clientY - position.y + 'px'; objs[i].style.left = parseInt(objs[i].style.left) + e.clientX - position.x + 'px'; position.x = e.clientX; position.y = e.clientY; } }); objs[i].addEventListener('mouseup', function(e){ let x = e.clientX; let y = e.clientY; if(x >= targetPosition.xs && x <= targetPosition.xe && y >= targetPosition.ys && y <= targetPosition.ye){ for(let j = 0; j < objs.length; j++){ objs[j].style.top = basePosition[j].y + 'px'; objs[j].style.left = basePosition[j].x + 'px'; } objs[i].style.top = targetPosition.ys + 2 + 'px'; objs[i].style.left = targetPosition.xs + 2 + 'px'; alert('オブジェクト' + i + 'をセットしました'); }else{ objs[i].style.top = basePosition[i].y + 'px'; objs[i].style.left = basePosition[i].x + 'px'; } drag[i] = false; position = { x: null, y: null }; objs[i].style.zIndex = 2; }); };


色々半端な造りではありますが、概ね望む挙動となっているかと思います
これをベースに応用すれば、色々な処理が作成できそうです

draggable属性を使用する
先ほどとは別の方法として、draggable属性を使用する方法があります
ドロップ先の制御などはこちらの方が簡単に出来ます
以下の条件で処理を作成してみましょう

スクリプト

const basePosition = [ {x:5, y:5}, {x:65, y:5}, {x:125, y:5}, {x:185, y:5}, {x:245, y:5}, ]; const endPosition = [ {x:185, y:5}, {x:65, y:5}, {x:245, y:5}, {x:5, y:5}, {x:125, y:5}, ]; const objs = document.getElementsByClassName('obj'); const targets = document.getElementsByClassName('target'); for(let i = 0; i < objs.length; i++){ objs[i].style.top = basePosition[i].y + 'px'; objs[i].style.left = basePosition[i].x + 'px'; objs[i].draggable = true; objs[i].addEventListener("dragstart", function(e){ e.dataTransfer.setData("id", event.currentTarget.id); }); targets[i].style.bottom = endPosition[i].y + 'px'; targets[i].style.left = endPosition[i].x + 'px'; targets[i].addEventListener("dragover", function(){ event.preventDefault(); }); targets[i].addEventListener("drop", function(e){ let dropTarget = e.currentTarget.id.slice(-1); let dragTarget = e.dataTransfer.getData("id").slice(-1); if(dropTarget == dragTarget){ objs[dragTarget].style.bottom = endPosition[dragTarget].y + 2 + 'px'; objs[dragTarget].style.left = endPosition[dragTarget].x + 2 + 'px'; objs[dragTarget].style.top = 'auto'; } }); };
動作テスト
※objectタグで上手く埋め込めなかったので、ここだけリンクになります



以上で今回のメモ書きは終了です
FileMakerに組み込むところまでは書きませんでしたが、Webビューアを使用したDrag&Drop処理の基礎はこれで分かると思います
また機会があれば、もっと実用的な使い方を書いてみます

メモ書き終了の案内イラスト

以上で今日のメモ書きは終了です

内容はいかがでしたか?

もしご意見やご要望、誤りの指摘などありましたら、下記フォームよりお気軽にご連絡ください

ご連絡フォーム