ドラッグアンドドロップでタスクを移動させる ガントチャートをWebアプリとしてつくる(4)
drag-drop-task-js

カテゴリを作成してドラッグアンドドロップでカテゴリの表示順序やタスクを別カテゴリに移動できるようにします。

⇒ 動作確認はこちらから

前回への追加と変更

まずHTML部分を示します。task1.jsは一部を除き前回のカレンダーをポップアップ表示させるで作成したJavaScriptと同じです。

前回との変更部分ですが、グローバル変数と最初に実行するInitPopupCalendar関数だけ以下のように変更します。

task1.js

今回追加する部分ですが、最初にグローバル変数として要素内のクリックされた位置と要素の位置の差を保存しておく変数を用意しておきます。そしてドラッグアンドドロップに対応できるようにイベントリスナーを追加します。

task2.js

カテゴリを追加する

最初にカテゴリ追加ボタンをクリックしたら新しいカテゴリを追加する処理を追加します。ここではカテゴリ名を設定するためのテキストボックスとタスクに追加ボタンを表示させます。

要素のうえにマウスが移動したときに移動可能であることがわかるようにマウスポインタの形状を変えます。それからclassを調べればカテゴリであることがわかるようにclass =”category”にするとともに、テキストボックスをクリックしたときはドラッグアンドドロップの処理が始まらないようにclass =”no-drag”にしておきます。

task2.js

タスクを追加する

次にタスクを追加する処理を追加します。

タスク名と担当者名を設定するためのテキストボックスを表示させるとともに、日時を表示しクリックしたらカレンダーで日時を変更できる要素を追加します。そしてクリックされたらカレンダーを表示できるようにイベントリスナーを追加しておきます。

カテゴリと同様に要素のうえにマウスが移動したときに移動可能であることがわかるようにマウスポインタの形状を変えます。それからclassを調べればタスクであることがわかるようにclass =”task”にするとともに、テキストボックスや日時を変更する要素をクリックしたときはドラッグアンドドロップの処理が始まらないようにclass =”no-drag”にしておきます。

ドラッグアンドドロップで移動する処理

ドラッグアンドドロップに関する処理を追加します。ドラッグアンドドロップが終わるまでは実際の移動処理は行なわず枠だけの矩形を描画してここに移動されることがわかるようにします。

以下は実際に移動させる要素と枠だけの矩形を描画するための要素を保存しておくグローバル変数です。

マウスボタンが押されたときの処理

PCとスマホ両方に対応できるようにしているのですが、スマホでは使いにくいと思います。

クリックされた要素のclassを調べて”no-drag”であればなにもしません。そうでない場合は移動しようとしているのがカテゴリなのかタスクなのかを調べます。どちらでもない場合はなにもしません。

デフォルトの動作だと文字が選択されている状態でドラッグが開始されると期待している動きとは異なる現象がおきる場合があります。そこでデフォルトの動作ではなく自分でコントロールできるようにしています。

要素の座標とカーソルの座標の差をグローバル変数に保存し、移動中であることを示す枠だけの矩形を描画するための要素(ここでは movingElement)を生成します。また前回の残骸が残っている場合は先に削除しておきます。

マウスカーソルが動いたときの処理

以下はマウスカーソルが動いたときに実行される処理です。マウスが動いた場所にmovingElementを移動させます。

マウスボタンが離されたときの処理

以下はマウスボタンが離されたときに実行される処理です。

movingElementが存在しない場合はなにもしません。存在する場合は取り除き、movingElementにはnullを代入します。ドロップされた場合それはカテゴリかもしれないし、タスクかもしれません。そこでclassからどちらなのか判断し、それぞれに応じた処理を別の関数でおこなっています。

先にカーソルが外れたときの処理を示します。ここでやっているのは移動中であることを示す枠だけの矩形を消去してmovingElementにnullを代入しているだけです。

カテゴリがカテゴリの上にドロップされたときの処理を示します。上から何番目のカテゴリにドロップされたかを調べて並べ替えているだけです。

categorysElementのなかにはカテゴリ以外の要素があるかもしれません(いまのところない)。そこでカテゴリ要素だけ集めて返す関数を作成します。

タスクがカテゴリの上にドロップされたときの処理を示します。

まずどのカテゴリの上にドロップされたのかを調べます。以下の処理で取得できます。

それからカテゴリ要素にはボタンやラベルなどタスク要素以外のものが存在します。カテゴリ要素のなかにあるタスク要素を取得する必要があります。

どのカテゴリの上にドロップされたのかがわかったら、次にどのタスクの上にドロップされたのかを調べます。