連載
» 2008年03月03日 00時00分 公開

パターンとライブラリで作るAjaxおいしいレシピ(5):jQuery UIで実現! Ajaxで複数選択ドラッグ&ドロップ (3/4)

[志田裕樹,アークウェブ株式会社]

今回のサンプルの基本的な情報

 ここまででDraggables、Droppables、Selectablesの基本的な使い方が分かったと思いますので、いよいよここからは、応用編のサンプル解説をしていきます。もう一度サンプルを見てみましょう。

今回のサンプル・プログラム(拡大表示はこちら※Firebugを有効にしていると動作が鈍くなることがあります

サンプルの基本設計

 このサンプルの基本設計は次のようになります。

  1. ディレクトリが2つあり、それぞれを親要素とするファイルが3つずつぶら下がる
  2. ディレクトリをselectable()にする
  3. ファイルをdraggable()にする
  4. ただし、初期状態は'disable'にしておき、ファイルが選択されたときに'enable'にする
  5. ディレクトリをdroppable()にする
  6. ファイルがディレクトリにドロップされたら、そのファイルが、そのドロップされたディレクトリの子要素になるようにDOMの操作を行う

複数要素のドラッグ

 ここで1つ難しいのは、複数ファイルが選択された場合のドラッグです。WindowsなどのOSが提供するファイルのドラッグでは、ファイルを複数選択し、その選択されたファイルのうち1つを「つかんで」移動すれば、選択されたファイルすべてが、マウスの動きにあわせて移動できます。しかし、jQueryのdraggable()は、「つかんだファイル」しか移動できません。

 ここでは、「つかんでいない選択ファイル」も移動する方法を別途実装しなければなりません。この課題に対して、今回は次のような手法を使いました。

  1. ドラッグ開始時に、すべての選択中のファイルのそれぞれの開始位置を保持しておく
  2. ドラッグ中、「つかんだファイル」の、開始位置からの移動距離を測る
  3. 「つかんでいない選択中のファイル」を、それ自身の開始位置から、「つかんでいるファイル」の移動距離分移動させる

 このような方法のほかにもDraggablesのオプションhelperを使い、ドラッグ時は実際のファイルを動かさずに、新たに複数のファイルに対応するヘルパを作成しドラッグ時はそれを表示する、という方法もあるかもしれません。

サンプルのHTMLソース

 それでは、サンプルのHTMLソースを見てみます。まず今回読み込むライブラリは、次の8つのファイルです。

  1. jquery-1.2.3.min.js
  2. jquery.dimensions.js
  3. ui.mouse.js
  4. ui.draggable.js
  5. ui.draggable.ext.js
  6. ui.droppable.js
  7. ui.droppable.ext.js
  8. ui.selectable.js

 また9つ目として、今回のアプリケーションのために作成したファイル「filer.js」も読み込みます。ディレクトリやファイルに対応する部分のHTMLは、次のようになります。

<div id='filer'>
  <ul class='directory' id='directory1'>
    <li class='file'>file 1</li>
    <li class='file'>file 2</li>
    <li class='file'>file 3</li>
  </ul>

  <ul class='directory' id='directory2'>
    <li class='file'>file 4</li>
    <li class='file'>file 5</li>
    <li class='file'>file 6</li>
  </ul>
</div>

 上記のように、<div id='filer'>の中に2つの<div class='directory'>があり、その下にそれぞれ3つの<div class='file'>が並ぶ構造になっています。

jQuery UIのテクニックがどのように使われたか

 次から、先ほど行った基本設計と対応させながら、部分的なコードを見ながら解説していきます。

 部分的に見て理解しやすいようにコードを一部変更してありますが、先に完全な形のソースコード全体を確認されたい場合は、こちらを参照してください。

ディレクトリをselectableにする

$('.directory').each(function() {
    $(this).selectable({
        selected: onSelected,
        unselected: onUnselected
    });
}

 この処理は、ページが読み込まれた際に一度だけ行われるディレクトリの初期化処理に当たります。ここでは、すべてのディレクトリに対して、selectable()を設定しています。onSelected、onUnselectedイベントハンドラについては後で解説します。

ディレクトリをdroppableにする

$('.directory').each(function() {
    $(this).droppable({
        hoverClass: 'ui-droppable-hover',
        accept: isAccept,
        drop: onDrop
    });
});

 この処理も、ページが読み込まれた際に一度だけ行われるディレクトリの初期化処理に当たります。ファイルがディレクトリに重なった際に、「'ui-droppable-hover'」というCSSのクラスが付与されるようにしています。ドロップが可能な要素かどうかの判定にisAcceptという関数を指定しています。isAcceptの内容や、onDropイベントハンドラについては後述します。

 最後に次ページでは、引き続き今回紹介したテクニックがサンプルでどのように使われたか徹底解説して、さらに複数ファイルのドラッグの実装について話します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。