パターンとライブラリで作るAjaxおいしいレシピ
連載一覧へ
パターンとライブラリで作るAjaxおいしいレシピ(5)

jQuery UIで実現! Ajaxで複数選択ドラッグ&ドロップ


アークウェブ株式会社
志田 裕樹
2008/3/3


ファイルをdraggableにし、初期状態はdisableにしておく


$('.file').draggable({
    containment: '#filer',
    start: onStartDrag,
    drag: onDrag,
    stop: onStopDrag
}).draggable('disable');
- PR -

 この処理は、ページが読み込まれた際に一度だけ行われるファイルの初期化処理に当たります。ここでは、全ファイルに対してdraggable()を設定しています。この際、ディレクトリの親要素である<div id='filer'>の範囲のみドラッグ可能となるようにしています。onStartDragonDragonStopDragイベントハンドラについては後で解説します。

 ファイルは選択状態にならなければドラッグできないようにしますので、いったんdraggableを設定した後に、'disable'で無効化しています。

選択(または、選択解除)されたファイルのドラッグの有効化(または、無効化)


onSelected: function(e, ui) {
    var file = $(ui.selected);
    file.draggable('enable');
},
onUnselected: function(e, ui) {
    var file = $(ui.unselected);
    file.draggable('disable');
},

 これらのメソッドは、ファイルのドラッグによる選択を行ったときと、選択解除を行ったときに呼び出されます。onSelectedイベントハンドラ、onUnselectedイベントハンドラはそれぞれ下記2つの処理を行っています。

  1. 選択されたファイルのドラッグを有効化
  2. 選択解除されたファイルのドラッグを無効化

dropの条件の設定


isAccept: function(draggable) {
    var oldDirectory = $(draggable).parent().get(0);
    var newDirectory = this.get(0);
    if (newDirectory.id != oldDirectory.id) {
        return true;
    }else {
        return false;
    }
}

 このメソッドはファイルをディレクトリの上に重ねた際に、そのファイルがディレクトリにドロップ可能かどうかを調べるために呼び出されます。このメソッドの中では、ドロップ前後のディレクトリを調べ、ドラッグ前に所属していたディレクトリと同一のディレクトリにドロップしていた場合は、ドロップできないようにしています。「get(0)」は配列の0番目を返すメソッドです。

ドロップされたらそのディレクトリの子要素になるようにすげ替える


onDrop: function(e, ui) {
    var directory = ui.instance.element;
    var files = $('.ui-selected');
    files.appendTo(directory)
         .css('top', '0px')
         .css('left', '0px')
         .removeClass('ui-selected')
         .draggable('disable');
}

 このメソッドはファイルをディレクトリにドロップした際に呼び出されます。ドロップ対象のディレクトリを取得し、すべての選択されたファイルをそのディレクトリ配下に入るようにします。その後、各ファイルの位置を初期化し、その後、選択をすべて解除し、ドラッグを無効化します。jQueryのメソッドチェーンのおかげですっきり書くことができますね。

複数ファイルのドラッグの実装

 最後に、複数ファイルのドラッグの実装について解説していきます。

ドラッグ開始時に開始位置を保持しておく


onStartDrag: function(e, ui) {
    var helper = ui.helper.get(0);
    var parentId = $(helper).parent().get(0).id;
    helper.selectedFiles = $('#' + parentId + ' .ui-selected');
    helper.selectedFiles.each(function() {
        this.startTop = parseInt($(this).css('top'));
        this.startLeft = parseInt($(this).css('left'));
    });
},

 このメソッドはドラッグが開始される際に呼び出されます。まず以下の処理で、「つかんでいるファイル」を取得しています。

    var helper = ui.helper.get(0);

 その後、以下の処理でそのファイルが所属しているディレクトリを取得します。

    var parentId = $(helper).parent().get(0).id;

 そして、以下の処理では、セレクタ部分が、例えば、「#directory1 .ui-selected」といった文字列になるので、これでドラッグ対象となるすべてのファイルを選択できます。

    helper.selectedFiles = $('#' + parentId + ' .ui-selected');

 これらを、「つかんでいるファイル」のオブジェクトに、selectedFilesというプロパティとして保持させています。その後、ドラッグ対象となるすべてのファイルそれぞれに、開始位置を保持させています。

「つかんだファイル」の開始位置からの移動距離の計算


onDrag: function(e, ui) {
    var helper = ui.helper.get(0);
    var topDistance = ui.position.top - helper.startTop;
    var leftDistance = ui.position.left - helper.startLeft;

 このメソッドはドラッグ中に呼び出されます。最初に、現在の「つかんでいるファイル」の位置と開始位置の差を求め、移動距離を計算しています。

「つかんでいない選択中のファイル」の移動

 下記は、上記のコードの続き部分になります。

    helper.selectedFiles.each(function() {
        if (this.selectedFiles == null) {
            var newTop = this.startTop + topDistance;
            var newLeft = this.startLeft + leftDistance;
            $(this).css('top', newTop + 'px')
                   .css('left', newLeft + 'px');
        }
    });
},

 「つかんでいるファイル」には、ドラッグ対象のファイルの配列である、selectedFilesというメンバが設定されていますので、このメンバが設定されていないファイルが、すなわち「つかんでいない選択中のファイル」になります。これらのファイルそれぞれに対して、自分自身の開始位置と「つかんだファイル」の移動距離を足して、その位置に移動をさせています。

ドラッグ終了時の終了処理


onStopDrag: function(e, ui) {
    var helper = ui.helper.get(0);
    helper.selectedFiles = null;
},

 このメソッドはドラッグが終了した際に呼び出されます。ドラッグが終了したら、「つかんだファイル」のselectedFilesのメンバを削除します。

 以上でソースコードの解説は終わりです。

ドラッグ&ドロップによるユーザビリティの向上を

 今回はjQuery UIのドラッグ&ドロップ機能に注目し、個々の使い方を解説し、その後に、要素を複数選択してドラッグ&ドロップを行うサンプルについて解説しました。

 サービスサイト、会員サイト、イントラネットなど、ユーザーにある程度長い時間、Webページ上で作業を行わせるようなサイトでは、ドラッグ&ドロップを利用することで作業効率をアップできるケースがあると思います。jQueryのドラッグ&ドロップ機能は非常にオプションが豊富でカスタマイズがしやすいので、きめ細かなアプリケーションの構築が可能です。ぜひチャンレンジしてみてください(参考:jQueryサンプル

 また、今回は取り上げなかった、Sortable、Resizableも非常に便利です。これらも、気軽に導入し、ユーザービリティ向上に役立てることができるライブラリですので、ぜひ試してみてください。

 今回のすべてのソースコードはこちらになります(サンプルのライセンスはGPL 2となります)。

@IT関連記事


古くて新しいAjaxの真実を見極める
「Webインターフェイスの新しい手法」「画期的なWebアプリケーションの仕組み」であるとして開発者たちの人気を集めるAjaxとは何なのか、その真実を見極めてみよう
Web Client & Report」フ ォーラム 2005/8/2

Ajax解体新書

よりAjaxを深く理解するために、ブラウザ上の「見た目」だけに注目するのではなく、実際に目に見えない舞台裏の通信内容をモニタリングしてみよう

最終更新 2006/11/22

Ajax うきうき Watch

Ajaxという流行技術の定義を明確にしながら、Ajaxの動向からうきうきするような面白いもの、確実に押さえておきたいものを厳選してお届けしていく

最終更新 2008/5/26

JavaScriptプログラミング再入門

 Ajax全盛のいま、オブジェクト指向ベースのJavaScript知識は不可欠。過去を振り返りつつ、まずは最新開発事情をチェック

最終更新 2007/9/25

プロフィール:志田 裕樹(しだ ゆうき)

株式会社アークウェブ取締役。Webシステムのシステムエンジニアとして開発に従事している。
Ajax、Ruby on Railsなどを使用したWeb 2.0的システムの開発実績を持つ。
オープンソースのECサイト用CMS、Zen Cartの日本語コミュニティでコミッターとして活動している。

 

1-2-3-4

 INDEX
パターンとライブラリで作るAjaxおいしいレシピ(5)
jQuery UIで実現! Ajaxで複数選択ドラッグ&ドロップ
  Page1
今回は「jQuery UI」のより進んだ活用例
ドラッグを可能にする「Draggables」
  Page2
ドロップを可能にする「Droppables」
ドラッグによる複数選択を可能にする「Selectables」
  Page3
今回のサンプルの基本的な情報
jQuery UIのテクニックがどのように使われたか
Page4
複数ファイルのドラッグの実装
ドラッグ&ドロップによるユーザビリティの向上を


リッチクライアント&帳票 全記事一覧へ

TechTargetジャパン

リッチクライアント & 帳票 フォーラム 新着記事

@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

RSSフィード

キャリアアップ

@IT Sepcial

イベントカレンダー

PickUpイベント

- PR -
もっと見る

お勧め求人情報

ホワイトペーパーTechTargetジャパン

@IT Sepcial
ソリューションFLASH