iUIを使ったiPhone用Webサイト作成 - JSONデータを動的にリスト表示

id:fits:20100713 で作成した Sinatra のサーバーロジックをそのまま使って、iPhone用のWebページを作成してみました。(ただし、iPhone 上で動作確認してません)
今回使った環境は以下の通り。

iUI は今のところ、JSON データを取得して画面に反映するような使い方は想定されていないようですので(サーバーから HTML の断片を受け取って表示を切り替える機能はある)、今回は JSON 取得や HTML 要素の変更処理に jQuery を使いました。
今回のような用途では Sencha Touch や jQTouch の方が使い易いかもしれません。

なお、今回作成したサンプルの画面構成は以下のようになっています。

  • (1) DBのリスト表示画面
  • (2) テーブルのリスト表示画面
  • (3) テーブルの詳細表示画面

Firefox 3.6 では (3) の画面や戻るボタンが正常に表示されないようなので注意。(Safari 5.0 では問題なく表示されます)

(1) DBのリスト表示画面

(2) テーブルのリスト表示画面(mysql 選択時)

(3) テーブルの詳細表示画面(columns_priv 選択時)

iUI でのリスト表示

iUI の説明のため、まず静的な HTML で今回の画面構成を書いてみます。

iUI では、各画面を ul や div 等の要素で記載し、id や title 属性を設定します。(リスト表示するには ul を使用)
selected="true" を設定している要素がメイン画面として表示され、a 要素で指定した画面(href 属性に "#遷移先画面のid" を設定)に遷移するようになっています。
また、class 属性で特殊な UI(toolbar, button, panel 等)を指定できるようになっており、ツールバー(class="toolbar")に戻るボタンの設定(id="backButton")をしておくと、画面遷移時に前の画面に戻るためのボタンが自動的に構成されます。

index_static.html (information_schema と CHARACTER_SETS のリンクのみ有効)
<!DOCTYPE html>
<html>
<head>
  <title>Nested List Sample</title>
  <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
  <meta name="apple-touch-fullscreen" content="yes" />
  <style type="text/css" media="screen">@import "iui/iuix.css";</style>
  <script type="text/javascript" src="iui/iuix.js"></script>
</head>
<body>
  <!-- ツールバー -->
  <div class="toolbar">
    <h1 id="pageTitle">Nested List Sample</h1>
    <!-- 前画面への戻るボタン -->
    <a href="#" class="button" id="backButton"></a>
  </div>
  <!-- (1) DBのリスト表示画面 -->
  <ul title="DB" id="home" selected="true">
  	<!-- (2) へのリンク -->
  	<li><a href="#information_schema">information_schema</a></li>
  	<li><a href="#mysql">mysql</a></li>
  </ul>
  <!-- (2) テーブルのリスト表示画面 -->
  <ul title="information_schema" id="information_schema">
  	<!-- (3) へのリンク -->
  	<li><a href="#information_schema___CHARACTER_SETS">CHARACTER_SETS</a></li>
  	<li><a href="#information_schema___COLLATIONS">COLLATIONS</a></li>
  </ul>
  <!-- (3) テーブルの詳細表示画面 -->
  <div class="panel" title="CHARACTER_SETS" id="information_schema___CHARACTER_SETS">
    <fieldset>
      <div class="row">
        <label>table_name</label>
        <span>CHARACTER_SETS</span>
      </div>
      <div class="row">
        <label>table_type</label>
        <span>SYSTEM VIEW</span>
      </div>
    </fieldset>
  </div>
</body>
</html>

JSON データの動的リスト表示

それでは本題の JSON による動的なリスト変更を実装します。

初期表示時に table_schema の一覧を JSON で取得し、(1) DBのリスト表示画面(id="home" の ul 要素)への追加と (2) テーブルのリスト表示画面用の ul 要素を作成します。
(1) で DB をクリックした際に、該当するテーブル情報を JSON で取得し、(2) と (3) テーブルの詳細表示画面用の要素作成を行います。

index.html
<!DOCTYPE html>
<html>
<head>
  <title>Nested List Sample</title>
  <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
  <meta name="apple-touch-fullscreen" content="yes" />
  <style type="text/css" media="screen">@import "iui/iuix.css";</style>
  <script type="text/javascript" src="iui/iuix.js"></script>
  <script type="text/javascript" src="jquery-1.4.2.min.js"></script>
  <script type="text/javascript">
    $(function() {
      $("#home").empty();

      $.get("informations/databases", null, function(res){
        $.each(res, function() {
          var db = this.table_schema;

          //DB毎の (2) を作成
          $(document.body).append("<ul id='" + db + "' title='" + db + "'></ul>");
          //(1) にDB毎の (2) へのリンクを追加
          $("#home").append("<li><a id='" + db + "_link' href='#" + db + "'>" + db + "</a></li>");

          $("#" + db + "_link").click(function(e) {
            $("#" + db).empty();

            $.get("informations/tables/" + db, null, function(res2){
              $.each(res2, function() {
                //(3) を作成
                var link = createDetailsPanel(db, this);

                //(2) にテーブル毎の (3) へのリンクを追加
                $("#" + db).append("<li><a href='#" + link + "'>" + this.table_name + "</a></li>");
              });
            }, "json");
          });
        });
      }, "json");
    });

    /**
     * 詳細表示パネルを作成する
     */
    function createDetailsPanel(db, item) {
      var id = db + "___" + item.table_name;

      $("#" + id).remove();

      $(document.body).append("<div id='" + id + "' title='" + item.table_name + "' class='panel'></div>");

      var headers = ["table_name", "table_type", "engine", "create_time"];

      var html = "<fieldset>";

      $.each(headers, function() {
        html += "<div class='row'>";
        html += "<label>" + this + "</label>";
        html += "<span>" + item[this] + "</span>";
        html += "</div>";
      });

      html += "</fieldset>";

      $("#" + id).append(html);

      return id;
    }
  </script>
</head>
<body>
  <!-- ツールバー -->
  <div class="toolbar">
    <h1 id="pageTitle">Nested List Sample</h1>
    <!-- 前画面への戻るボタン -->
    <a id="backButton" class="button" href="#"></a>
  </div>
  <!-- (1) DBのリスト表示画面 -->
  <ul id="home" title="DB" selected="true"></ul>
  <!-- (2) や (3) の画面は jQuery を使って動的に追加 -->
</body>
</html>