こんにちは。ふだん、何かとjQuery Mobileを使っている中山です。
先日、なにげなくjQuery Mobileの情報を探していると、以下のような記事が見つかりました。
Remove nested listview feature
Nested list alternative now that it's deprecated
な、なんだってー!!
jQuery Mobileの「階層化リストビュー」の機能が、バージョン1.3.0からは非推奨、1.4.0からは機能自体削除される、と書かれているではないですか!
jQuery Mobileの現時点(2013年9月時点)の安定版は、バージョン1.3.2です。
そろそろ、「階層化リストビュー」が使えない、ということを言い訳にして、最新版に移行しないわけにもいきません。
「・・・よし、作るか。」
かくして、「階層化リストビュー」を自作するための、挑戦がはじまったのでした。
階層化リストビューとは
jQuery Mobileの「階層化リストビュー」は、「<ul>」「<li>」のタグを階層的に並べていくだけで、サブリストを持つリストビューを簡単に実現できる、という大変便利な機能でした。(詳しくはこちら)
jQuery Mobileの「階層化リストビュー」の機能を使うと、サブリストを表示する際に、jQuery Mobileが自動的に「ページ」オブジェクトを生成するようです。
その新しく生成されたページに、サブリストの内容が自動的に描画され、表示される、という仕組みのようです。
この、
「サブリストがあった場合に、動的にページを生成して、そこに内容を描画する」
という部分を、うまく再現することができれば、自作「階層化リストビュー」もスムーズに実現できるのかもしれません。
階層化リストビューを自作してみる
リストビューのデータを用意する
まずは、リストビューに表示する項目のデータを用意します。
var listitems = { "Animals":[ "Dog", "Cat", "Elephant" ], "Fruits":[ "Apple", "Orange", "Grape" ], "Shapes":[ "Circle", "Rectangle", "Triangle" ] };
本来は、このようなデータは、どこからのサーバから動的に取得する、という形になるのかもしれませんね。
動的に生成するページのテンプレートを用意する
リストビューのサブ階層を表示する場合は、その時点で動的に新しいページを作成します。
この新しいページのテンプレートを、あらかじめ用意しておきます。
<!-- Sub page template --> <div id="subpage-template" data-role="page"> <div data-role="header"> <a data-rel="back">Back</a> <h1 id="title-template">Sub page</h1> </div> <div data-role="content"> <ul id="listview-template" data-role="listview"></ul> </div> </div>
リスト項目をタップしたときの処理を実装する
リスト項目をタップしたときのイベントハンドラを用意して、タップした項目のサブ項目を、リストビュー表示させます。
// リスト項目タップ時イベントハンドラ $(document).on('click', '.listitem', function() { var subPageId = this.id; // 新しいページをテンプレートから生成します createSubPage(subPageId); // 新しいページのタイトルに、タップした項目の名称を設定します $('#title-' + subPageId).text(subPageId); // 新しいページ内のリストビューに、サブ項目を設定します var subitems = listitems[subPageId]; var html = ''; for (var i=0; i<subitems.length; i++) { var subitem = escapeHtmlTags(subitems[i]); html += '<li>' + subitem + '</li>'; } // サブ項目追加後、jQuery Mobileの「listview()」メソッドを呼び出し、リストを更新します $('#listview-' + subPageId).empty().append(html).listview('refresh'); // 新しいページに遷移します $.mobile.changePage($('#subpage-' + subPageId), { transition:"slide" }); });
完成
意外とシンプルに実現することができました。
実際に動作するサンプルは、以下をご参照ください。
(※Chromeブラウザの場合、サブリストページからの「Back」ボタンが正しく動作しないかもしれません。フルスクリーン表示だと問題ないかも。)