jQueryではじめるAjax

第5回jQuery UIによるユーザインターフェースの改良

今回は、jQuery UIを使用してサンプルアプリケーションのユーザインターフェースを改良したいと思います。 jQuery UIが提供する「Dialog」⁠Draggables」⁠Droppables」⁠Sortables」を使用して、ビデオプレーヤーとお気に入り機能を実装します。

jQuery UIってなに?

jQuery UIとは、マウス操作やユーザインターフェースを拡張するjQueryのライブラリです。 現在の最新版jQuery UI 1.5bでは、以下の機能が提供されています。

表1 jQuery UI 1.5bの機能
ライブラリ説明
Draggables DOM要素をドラッグできるようにする
Droppables DraggableなDOM要素をドロップできるようにする
Sortables マウス操作でDOM要素の順番を入れ替えられるようにする
Selectables DOM要素をマウスで選択できるようにする
Resizables DOM要素の大きさをマウスで変更できるようにする
Accordion 折りたたみ可能な領域をサポートするコンポーネント
Datepicker 日付選択のためのコンポーネント
Dialog 高機能なダイアログコンポーネント
Slider スライダーコンポーネント
Tabs タブ機能を提供するコンポーネント

詳細な解説とデモは、以下の場所で見ることが出来ます。

参考

今回は、⁠Dialog」⁠Draggables」⁠Droppables」⁠Sortables」を使ってサンプルをより使いやすく拡張したいと思います。

準備

jQuery UI 1.5bはjQuery UI: Widgets, Components, and Interactionからダウンロードできます。⁠jQuery UI 1.5b」のリンクをクリックすると、ダウンロードページが開きます。

図1 jQuery UIダウンロード
図1 jQuery UIダウンロード

アーカイブの内容

アーカイブの内容は以下のようになっています。

表2 jQuery UI 1.5bアーカイブの内容
ディレクトリ/ファイル説明
datepicker/ 「Datepicker」のライブラリとデモ
demos/ jQuery UI 1.5bのデモ
themes/ 標準で提供されるテーマ「Flora」のスタイルシート及び画像
GPL-LICENSE.txt GNU General Public License Ver 2のテキスト
jquery-1.2.3.min.js jQuery 1.2.3
jquery.dimensions.js 座標計算のためのプラグイン
MIT-LICENSE.txt MIT Licenseのテキスト
ui.accordion.js 「Accordion」コンポーネントのファイル
ui.dialog.js 「Dialog」コンポーネントのファイル
ui.draggable.ext.js 「Draggables」機能の拡張オプションのファイル
ui.draggable.js 「Draggables」機能のファイル
ui.droppable.ext.js 「Droppables」機能の拡張オプションのファイル
ui.droppable.js 「Droppables」機能のファイル
ui.mouse.js マウス操作を管理するプラグイン
ui.resizable.js 「Resizables」機能のファイル
ui.selectable.js 「Selectables」機能のファイル
ui.slider.js 「Slider」コンポーネントのファイル
ui.sortable.ext.js 「Sortables」機能の拡張オプションのファイル
ui.sortable.js 「Sortables」機能のファイル
ui.tabs.ext.js 「Tabs」コンポーネントの拡張オプションのファイル
ui.tabs.js 「Tabs」コンポーネントのファイル

今回使用する「Dialog」⁠Draggables」⁠Droppables」⁠Sortables」に必要なファイルは以下の通りです。

  • themes/
  • jquery-1.2.3.min.js
  • jquery.dimensions.js
  • ui.mouse.js
  • ui.resizable.js
  • ui.dialog.js
  • ui.draggable.js
  • ui.draggable.ext.js
  • ui.droppable.js
  • ui.droppable.ext.js
  • ui.sortable.ext.js
  • ui.sortable.js

jQuery UI 1.5bを使うために、今回は同梱されているjQuery 1.2.3を使うことにします。バージョンが上がりますが、これまでのサンプルの動作に影響はありません。

ライブラリの設定

ライブラリの各ファイルを、head要素の子要素に以下のように指定しますリスト1⁠。

リスト1 ライブラリファイルの設定
<script type="text/javascript" src="jquery-1.2.3.min.js"></script>
<script type="text/javascript" src="jquery.dimensions.js"></script>
<script type="text/javascript" src="ui.mouse.js"></script>
<script type="text/javascript" src="ui.resizable.js"></script>
<script type="text/javascript" src="ui.dialog.js"></script>
<script type="text/javascript" src="ui.draggable.js"></script>
<script type="text/javascript" src="ui.draggable.ext.js"></script>
<script type="text/javascript" src="ui.droppable.js"></script>
<script type="text/javascript" src="ui.droppable.ext.js"></script>
<script type="text/javascript" src="ui.sortable.js"></script>
<script type="text/javascript" src="ui.sortable.ext.js"></script>

テーマの設定

jQuery UIではテーマがサポートされ、コンポーネントの外観をカスタマイズできるようになっています。 標準ではFloraテーマが同梱されていますので、それを使用することにします。

まず、head要素の子要素に以下のように指定してFloraテーマのcssファイルをリンクしますリスト2⁠。

リスト2 Floraテーマcssファイルのリンク
<link rel="stylesheet" href="themes/flora/flora.all.css" type="text/css" media="screen" title="Flora" />

body要素にfloraクラスを設定しますリスト3⁠。

リスト3 Floraテーマクラスの設定
<body class="flora">

これで準備は完了です。それでは実装をはじめましょう。

ビデオプレーヤーの実装(1)-Dialog

今までは、検索結果のサムネイルをクリックすると、Youtubeのプレーヤのページを新しく開いていました。 今回は、⁠Dialog」コンポーネントを使って、ダイアログ上でビデオを再生できるようにします。

ビデオプレーヤーの構成

図2 ビデオプレーヤーの構成
図2 ビデオプレーヤーの構成

上部にYoutubeのビデオを表示します。下部にビデオの投稿者、投稿日、再生回数、説明を表示します。

ビデオプレーヤー表示

前回作成したYoutube.jsに、ビデオプレーヤー表示のメソッドを追加しますリスト4⁠。

リスト4 ビデオプレーヤー表示
// --- プレーヤー表示 ---
showPlayer: function(options) {
    $("<div/>")
        .append('<object width="425" height="355"><param name="movie" value="'+ options.url +'"></param><param name="wmode" value="transparent"></param><embed src='+ options.url +' type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>')
        .append('<br/>')
        .append(options.info.show())
        .dialog({
            title: options.title,
            width: 465,
            height: 520,
            close: function(){$(this).parents(".ui-dialog").remove()}
        });
},

まず、コンテナとなるdiv要素を生成します。

$("<div/>")

次に、Youtubeのビデオを埋め込む要素を生成します。

.append('<object width="425" height="355"><param name="movie" value="'+ options.url +'"></param><param name="wmode" value="transparent"></param><embed src='+ options.url +' type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>')

この要素は、Youtubeのプレーヤーページの「埋め込み」にあるタグを、引数のurlプロパティを使用して生成しています。

図3 ⁠埋め込み」タグ
図3 「埋め込み」タグ

引数で渡されるビデオ説明の要素を追加します。show()メソッドを呼び出しているのは、サムネイル上では非表示にしているからです。この要素の生成については後で説明します。

.append(options.info.show())

そして、ダイアログコンポーネントを生成し、表示します。

「Dialog」を使うには、ダイアログとして表示したい要素に対して、dialogメソッドを呼び出すだけです。とても簡単ですね。dialogメソッドには様々なオプションが用意されています。

表3 dialogメソッドのオプション(抜粋)
プロパティ説明デフォルト値
autoOpen trueを指定すると、ダイアログを生成した後、自動的に表示する true
draggable trueを指定すると、タイトルバーをドラッグしてダイアログを移動できる true
height ダイアログの高さを指定する 200
modal モーダルモードでダイアログを表示するかどうかを指定する false
resizable サイズ変更可能が可能かどうかを指定する true
itle タイトルバーに表示する文字列を指定する なし
width ダイアログの横幅を指定する 300

他のオプションについては、UI/Dialog/dialog - jQuery JavaScript Libraryをご覧ください。

ダイアログ生成のコードは次のようになりますリスト5⁠。

リスト5 ダイアログ生成
.dialog({
    title: options.title,
    width: 465,
    height: 520,
    close: function(){$(this).parents(".ui-dialog").remove()}
});

タイトルに、引数から与えられたビデオのタイトルを設定します。横幅を465、高さを520としています。

closeプロパティに設定しているのは、ダイアログが閉じられたときに実行されるコールバック関数です。 ドキュメントには記述がありませんが、closeプロパティに指定することができます。ここでは、ダイアログの要素を削除しています。

ここで指定している、$(this).parents(".ui-dialog")とは何でしょうか。ダイアログは、対象となる要素をいくつかのdiv要素でwrapして構成されています図4⁠。

図4 ダイアログの構成図
図4 ダイアログの構成

まず、ダイアログは<div class="ui-dialog">という要素でwrapされています。その子要素には、<div class="ui-dialog-container">という要素があり、さらにその子要素に、タイトルバーの<div class="ui-dialog-titlebar">とdialogメソッドを呼び出した要素を格納する、<div class="ui-dialog-content">があります。

一度生成したダイアログは、dialog("open")で表示、dialog("close")で閉じることが出来ますが、このアプリケーションではダイアログに表示するコンテンツは毎回異なります。また、プレーヤーを複数表示できるようにするので、表示するたびにダイアログを生成することにします。そうすると際限なくダイアログ要素が増えてしまいますので、閉じるときにダイアログの要素を削除しています。

ドキュメントには、dialog("destroy")でダイアログの要素を削除できるとかいてありますが、エラーが出てうまく動作しません。よって、親要素の<div class="ui-dialog">を辿り、removeメソッドで削除しています。

ビデオプレーヤーの生成、表示部分が完成したところで、サムネイルからの呼び出し処理を実装します。

ビデオプレーヤーの実装(2)-Dialog

ビデオプレーヤーの起動

前回までの実装では、サムネイルのクリックイベントハンドラは次のように記述されていました。

.click(function(){window.open(group.media$player[0].url, null)})

この部分を削除し、ビデオプレーヤーを表示するように修正しますリスト6⁠。

リスト6 サムネイル クリックイベントハンドラ
// クリックしたらプレーヤーを表示
.click(function(){
    if (video_url == '') {
        // プレーヤーページ(Youtube)
        window.open(group.media$player[0].url, null)
    } else {
        // プレーヤー(ダイアログ)
        yt.showPlayer({
            url  : video_url,
            title: item.title.$t,
            info : video_info
        });
    }
})

showPlayerメソッドのurlプロパティに指定しているvideo_urlは、YoutubeビデオのURLです。feed.entry[n].media$group[n].media$content[0].urlで取得することができます。

なお、Youtubeにはリクエストによる埋め込み無効なビデオ(Youtubeのプレーヤページでのみ表示が可能なビデオ)が存在します。その場合はmedia$contentプロパティが存在しません。よって、video_urlは次のように定義しましたリスト7⁠。

リスト7 埋め込み用ビデオのURLの取得
// 埋め込み用ビデオのURL
var video_url = group.media$content == null ? '' : group.media$content[0].url;

もし、video_urlが空の場合は、今までどおりYoutubeのプレーヤページを表示するように処理を振り分けています。

showPlayerメソッドのtitleプロパティに指定しているのは、Youtubeビデオのタイトルです。feed.entry[n].title.$tで取得することができます。

showPlayerメソッドのinfoプロパティに指定しているのは、プレーヤの下部に表示するビデオの詳細情報を格納した要素です。次のように定義しましたリスト8⁠。

リスト8 ビデオ詳細情報
// プレーヤーの下に表示する詳細項目
var video_info = $("<div/>").addClass("video_info")
    .append($("<span/>").addClass("title").text("投稿者 :")).append(item.author[0].name.$t).append('<br/>')
    .append($("<span/>").addClass("title").text("投稿日 :")).append(item.published.$t.replace(/^(\d{4})-(\d{2})-(\d{2}).*/, "$1年$2月$3日")).append('<br/>')
    .append($("<span/>").addClass("title").text("再生回数:")).append(((item.yt$statistics == null) ? "0" : item.yt$statistics.viewCount)).append('<br/>')
    .append($("<span/>").addClass("title").text("説明  :")).append(item.content.$t).append('<br/>')

まず、class="video_info"で定義されるdiv要素を作成します。

子要素に投稿者、投稿日、再生回数、説明を格納したspan要素を追加します。

なお、Youtube APIが返す投稿日などの日時データは、RFC 3339フォーマットです。

  • 例⁠⁠ "2007-12-09T23:58:53.000-08:00"

この文字列からreplaceメソッドを使用して年月日を抜き出しています。

replace(/^(\d{4})-(\d{2})-(\d{2}).*/, "$1年$2月$3日")

お気に入り機能のための情報の保持

この後実装するお気に入り機能のために、ビデオのURL、YoutubeのプレーヤページのURL、ビデオの詳細情報を非表示にして保持しておきましょうリスト9⁠。

リスト9 お気に入り機能のための情報の保持
.append($("<span/>").addClass("video_url").text(video_url).hide())                  // お気に入りのための非表示要素(video_url)
.append($("<span/>").addClass("player_url").text(group.media$player[0].url).hide()) // お気に入りのための非表示要素(player_url)
.append(video_info.hide())

以上で、ビデオプレーヤーの実装は終了です。今回修正したサムネイル生成部分のソースは次のようになりましたリスト10⁠。

リスト10 サムネイル生成
// プレーヤーの下に表示する詳細項目
var video_info = $("<div/>").addClass("video_info")
    .append($("<span/>").addClass("title").text("投稿者 :")).append(item.author[0].name.$t).append('<br/>')
    .append($("<span/>").addClass("title").text("投稿日 :")).append(item.published.$t.replace(/^(\d{4})-(\d{2})-(\d{2}).*/, "$1年$2月$3日")).append('<br/>')
    .append($("<span/>").addClass("title").text("再生回数:")).append(((item.yt$statistics == null) ? "0" : item.yt$statistics.viewCount)).append('<br/>')
    .append($("<span/>").addClass("title").text("説明  :")).append(item.content.$t).append('<br/>')

// 埋め込み用ビデオのURL
var video_url = group.media$content == null ? '' : group.media$content[0].url;

// サムネイルを生成
$("<div/>").addClass("thumbnail")
    .append($("<img/>").attr("src", group.media$thumbnail[0].url)).append("<br/>")
    .append($("<span/>").addClass("title").text(item.title.$t)).append("<br/>")
    .append($("<span/>").addClass("info").text("再生回数:" + ((item.yt$statistics == null) ? "0" : item.yt$statistics.viewCount)))
    .append($("<span/>").addClass("video_url").text(video_url).hide())                  // お気に入りのための非表示要素(video_url)
    .append($("<span/>").addClass("player_url").text(group.media$player[0].url).hide()) // お気に入りのための非表示要素(player_url)
    .append(video_info.hide())                                                          // お気に入りのための非表示要素(video_info)
    // クリックしたらプレーヤーを表示
    .click(function(){
        if (video_url == '') {
            // プレーヤーページ(Youtube)
            window.open(group.media$player[0].url, null)
        } else {
            // プレーヤー(ダイアログ)
            yt.showPlayer({
                url  : video_url,
                title: item.title.$t,
                info : video_info
            });
        }
    })
    .appendTo("#videos");

お気に入りの実装(1)-Draggables / Droppables / Sortables

次は、⁠Draggables」⁠Droppables」⁠Sortables」を使用して、お気に入り機能を実装したいと思います。

図5 お気に入り機能
図5 お気に入り機

ビデオのサムネイル領域の右に表示され、サムネイルからドラッグ&ドロップで、ビデオを追加することができます。また、お気に入り内のアイテムは、マウス操作で並び替えができます。

実装のイメージをつかみやすくするため、先に完成版の第5回サンプルをご紹介します。

お気に入り領域

お気に入りの領域を作成します。以下のようにHTMLを追加しますリスト11⁠。

リスト11 お気に入り領域
<!-- お気に入り -->
<div id="favorites">
    <!-- ヘッダ -->
    <div class="header">
        <div class="submenu"><a id="clear_fav">クリア</a></div>
        <div class="caption">お気に入り</div>
    </div>

    <!-- お気に入りリスト -->
    <ul></ul>
</div>

id=favoritesとしてdiv要素を定義します。⁠お気に入り」というタイトルと、検索履歴を消去するid=clear_favのa要素「クリア」を定義します。また、お気に入りのリストを保持するul要素を定義します。

お気に入りをマウスで並び替え可能にする

お気に入り領域の各要素をマウスで並べ可能にします。sortableメソッドを呼び出すだけで並べ替えが可能になります。とても簡単ですね。 sortableメソッドには様々なオプションが用意されています。UI/Sortables/sortable - jQuery JavaScript Libraryをご覧ください。

お気に入りをマウスで並び替え可能にする実装は次のようになります。
$(function(){・})の初期処理に追加しますリスト12⁠。

リスト12 並び替えを可能にする
$("#favorites &gt ul")
    // お気に入りを並び替え可能にする
    .append("<li/>").sortable({axis: "y"}).empty()

sortableメソッドのオプションには、axisプロパティに"y"を指定しています。これにより縦方向のみに操作を制限しています。

この処理で、わざわざ、空のli要素を追加append("<li/>")して、最後にli要素を削除empty()しているのは、ソート対象の子要素が存在しない状態でsortableメソッドを実行すると、エラーとなるためです(並び替え要素が変更されたときに実行するsortable("refresh")などでは発生しません⁠⁠。

サムネイルをドラッグ可能にする

次に、サムネイルの各アイテムをドラッグ可能にします。draggableメソッドを呼び出すだけでドラッグが可能になります。とても簡単ですね。 draggableメソッドには様々なオプションが用意されています。

表4 draggableメソッドのオプション(抜粋)
プロパティ説明デフォルト値
axis ドラッグできる方向を制限する。'x'で横方向、'y'で縦方向を指定できる 'x', 'y'
containment ドラッグの範囲を制限する。指定した要素内でのみドラッグが可能になる。'parent'(親要素内⁠⁠、'document'(ドキュメント内⁠⁠、DOM要素、jQueryセレクタを指定できる なし
helper ドラッグ中の表示方法を指定する。'clone'を指定すると、要素を複製して表示するghostingエフェクトが適用される。また、DOM要素を返す関数オブジェクトを指定して、独自のエフェクトを設定することができる 'original'
zIndex ドラッグ要素のz-indexを数値で指定する なし

他のオプションについては、UI/Draggables/draggable - jQuery JavaScript Libraryをご覧ください。

ドラッグを可能にする実装は次のようになります。Youtube.jsのsearchメソッド内でサムネイルを生成している箇所に追加します($.ajaxのsuccessイベントハンドラ。リスト13⁠。

リスト13 ドラッグを可能にする
$("<div/>").addClass("thumbnail")
・・・中略・・・
.draggable({helper: 'clone', zIndex: 10})  // ドラッグを可能にする

helperプロパティに'clone'を指定して、ghostingエフェクトを有効にしました。

また、ドラッグ中の要素が確実に前面に来るように、zIndexを10に設定しました(他のプロパティやDroppablesの設定、ブラウザの組み合わせにより、ドラッグ中に他の要素の後ろに表示されることがあるためです⁠⁠。

サムネイルを掴んで動かしてみてください。

お気に入りの実装(2)-Draggables / Droppables / Sortables

お気に入りをドロップ可能にする

ドラッグしたサムネイルをお気に入りドロップ可能にします。droppableメソッドを呼び出すだけでドラッグが可能になります。とても簡単ですね。 droppableメソッドには様々なオプションが用意されています。

表5 droppableメソッドのオプション(抜粋)
プロパティ説明デフォルト値
accept ドロップを受け入れる要素を指定する。jQueryセレクタで記述する なし
activeClass ドロップ可能な要素がドラッグを開始したときに適用するクラス名を指定する なし
hoverClass ドロップ可能な要素が通過したときに適用するクラス名を指定する なし
drop 要素がドロップされたときに呼び出されるコールバック関数を指定する なし

他のオプションについては、UI/Droppables/droppable - jQuery JavaScript Libraryをご覧ください。

ドロップを可能にする実装は次のようになります。
$(function(){・})の初期処理に追加しますリスト14⁠。

リスト14 ドロップを可能にする
$("#favorites > ul")
    // お気に入りを並び替え可能にする
    .append("<li/>").sortable({axis: "y"}).empty()
    // ドロップ可能にする
    .droppable({
        activeClass: "droppable-active",    // draggableアイテムがアクティブになったときのクラス
        hoverClass: "dropped-hover",        // draggableアイテムが通過するときのクラス
        accept: ".thumbnail",               // thumbnailクラスの要素をドロップ可能にする
        drop: function(ev, ui) {            // ドロップしたときの処理
            // 同じお気に入りがあるかどうか
            var exists = $.grep($("#favorites li"), function(item, index){
                return $(item).children("img").attr("src") == $(ui.draggable).children("img").attr("src");
            });

            // 新しいお気に入り
            if (exists.length == 0) {
                // 要素を複製
                var item = $(ui.draggable).clone();
                // 追加するli要素を作成
                $("<li/>")
                    .append(item.children("img")).append("<br/>")
                    .append(item.children(".title").clone())
                    .append($("<a/>").addClass("del").append("[x]").click(function(){$(this).parent().remove()}))
                    // クリックしたらプレーヤーを表示
                    .click(function(){
                        if (item.children(".video_url").text() == '') {
                            // プレーヤーページ(Youtube)
                            window.open(item.children(".player_url").text(), null)
                        } else {
                            // プレーヤー(ダイアログ)
                            yt.showPlayer({
                                url  : item.children(".video_url").text(),
                                title: item.children(".title").text(),
                                info : item.children(".video_info").clone()
                            });
                        }
                    })
                    .prependTo(this);   // 最上位に追加
            } else {
                $(exists)
                    .prependTo(this);   // 最上位に移動
            }

            $(this).sortable("refresh");    // 並び替え項目に変更があったことを知らせる
        }
    });

まず、activeClassプロパティに、"droppable-active"、hoverClassに"dropped-hover"を指定しています。droppable-activeクラスとdropped-hoverクラスはcssで次のように定義しましたリスト15⁠。

リスト15 droppable-active / dropped-hoverの定義
.droppable-active {
    background-color: #b0c4de;
}

.dropped-hover {
    background-color: #6495ed;
}

ドラッグ中にドラッグ先が分かるように、また、ドロップ要素の上を通過していることが一目で分かるように背景色を変えています。

図6 ドラッグ中(activeClass)
図6 ドラッグ中(activeClass)
図7 ドロップ要素の上を通過中(hoverClass)
図7 ドロップ要素の上を通過中(hoverClass)

acceptプロパティには、 ドロップを受け入れる要素として、thumbnailクラスの要素を指定しています。

dropプロパティには、 ドロップされたときに実行されるコールバック関数を指定しています。

drop: function(ev, ui) {            // ドロップしたときの処理
    ・・・
});

このコールバック関数は2つの引数が渡されます。

1つめの引数は、イベントオブジェクトです。
2つめの引数は、ドロップされたdraggable要素に関するオブジェクトです。たとえば、この引数をuiと定義した場合、ui.instanceとすることでドロップされた要素を取得することができます。

その他の詳細については、UI/Droppables/droppable - jQuery JavaScript Libraryをご覧ください。

まず、アイテムの重複を避けるため、既にお気に入りに同じアイテムが存在しているかどうかをチェックします。 ここでは、同じURLのimg要素を持っているかどうかで同じアイテムかどうかを判別しています。

// 同じお気に入りがあるかどうか
var exists = $.grep($("#favorites li"), function(item, index){
    return $(item).children("img").attr("src") == $(ui.draggable).children("img").attr("src");
});

この変数existsには、お気に入りに重複したアイテムが存在した場合、そのli要素を含む配列が返されます。もし、存在しない場合は、空の配列が返されます。よって、重複があるかどうかを判別するには次のように記述します。

if (exists.length == 0) {    // 存在しない

} else {    // 存在する

}

重複したお気に入りが存在しない場合

新しいお気に入りアイテムを作成します。

まず、ドロップされた要素を複製します(要素を複製しないでそのまま追加すると、移動してしまいます⁠⁠。

// 要素を複製
var item = $(ui.draggable).clone();

次に、リストのli要素を作成します。

// 追加するli要素を作成
$("<li/>")

サムネイル画像、タイトル、削除ボタンを追加します。

.append(item.children("img")).append("<br/>")
.append(item.children(".title").clone())
.append($("<a/>").addClass("del").append("[x]").click(function(){$(this).parent().remove()}))

クリック時のイベントハンドラを追加します。この処理は、サムネイルのクリックイベントハンドラど同じです。 サムネイルの要素から、ビデオのurl、タイトル、ビデオの詳細情報をコピーして、プレーヤーを起動します。

// クリックしたらプレーヤーを表示
.click(function(){
    if (item.children(".video_url").text() == '') {
        // プレーヤーページ(Youtube)
        window.open(item.children(".player_url").text(), null)
    } else {
        // プレーヤー(ダイアログ)
        yt.showPlayer({
            url  : item.children(".video_url").text(),
            title: item.children(".title").text(),
            info : item.children(".video_info").clone()
        });
    }
})

そして、作成したli要素を最上位に追加します。

.prependTo(this);   // 最上位に追加

重複したお気に入りが存在する場合

見つかったアイテムを最上位に移動します。

$(exists)
    .prependTo(this);   // 最上位に移動

並び替え可能な要素の変更を通知

最後に、並び替え可能な要素の変更を通知します。これを忘れると、マウスで並び替えることができない要素ができてしまいます。

$(this).sortable("refresh");    // 並び替え項目に変更があったことを知らせる

以上で全ての実装が終了しました。サンプルを実行して動作を確認してみてください。

また、今回のサンプルアプリケーションのソースコード一式をアーカイブしました。ダウンロードして動作と実装を確認してみてください。

まとめ

今回はjQuery UIの「Dialog」⁠Draggables」⁠Droppables」⁠Sortables」を使ってビデオプレーヤとお気に入り機能を実装してみました。 かなり使いやすくなったと思います。jQuery UIを使うと、操作性の高いUIを簡単に実装することができますね。

今回実装したお気に入り機能は、ブラウザを閉じると消えてしまいます。 もし、将来的にYoutube APIで、Youtubeのお気に入りに登録できるAPIが公開されたら、それと連携するのもいいかもしれません。

Ajaxの使いどころ

さて、今回で、⁠jQueryではじめるAjax」は終了です。最後にAjaxの使いどころをまとめて終わりたいと思います。

Ajax技術はこれまでのWebアプリケーションの実装をすべて置き換えるものではありません。 どのような時に適用するのが効果的でしょうか。

データのリクエストのために、ユーザの操作を妨げたくないとき

通常のWebアプリケーションでは、リクエスト毎にページの切り替えが発生するため、そこでユーザの操作が一時中断されてしまいます。

たとえば、第4回で実装したSuggest機能ですが、リクエストの度に画面が切り替わっては、検索キーワードの入力が非常に不便になります。

効果的に使えば、操作性の優れたアプリケーションになります。

「必要なとき」「必要なだけ」データを使いたいとき

アプリケーションによっては、いま、クライアントで保持しているデータに、ユーザの操作等によって生じた差分データがほしい場合があります。

たとえば、Google Mapでは、ユーザの地図のドラッグによって、地図データの差分が必要になります。 逆にいうと差分だけあればアプリケーションは動作することができます。

これまでは、画面を切り替えて、必要な全ての地図データを含めたHTMLを再描画しなければなりませんでしたが、Ajaxを使えばデータの通信量を小さく抑えることができ、操作性も向上させることができます。

そのほかにも、チャットアプリケーションや、株価を表示するようなアプリケーションのようなものが考えられます。

最後に

本連載では、初めてAjaxを実装する方へ、jQueryを使った基本的な実装方法を解説しました。 連載をご参考にして、よりよいWebアプリケーションを作ってください!それでは。

おすすめ記事

記事・ニュース一覧