jqMobiのはじめかた(Ajax編)

jqMobiを使って、みんな大好きAjaxを使ったサンプルを書いてみる。
Ajaxのサンプルといえば、Twitter Search APIJSONPで叩くというのが世のならわしなのでそれに従う。(そうなの?

土台のHTML

まずはpanel要素。検索フィールドを置いて、結果を#resultsにつっこむという算段。

<div id="search" class="panel" title="Twitter Search">
<form id="search-form" action="#" method="get">
<input id="search-word" type="search" name="q" placeholder="Input search word." />
</form>
<ul id="results"></ul>
</div>

Ajaxでリクエストを投げる

続いてJavaScript。#search-form.submit()を捉えて、Ajaxリクエストに変える。

$('#search-form').bind('submit', function() {
  $.ui.showMask();
  $('#results').empty();
  var q = $('#search-word').val();
  var url = 'http://search.twitter.com/search.json?callback=?&q=' + encodeURIComponent(q);
  var onSuccess = function(data) {
    console.log(data);
    $.ui.hideMask();
  };
  var onError = function() {
    console.log(arguments);
    $.ui.hideMask();
    alert('Error!');
  };
  $.jsonP({
    url: url,
    success: onSuccess,
    error: onError
  });
  return false;
});

jQueryだとgetJSONでJSONPを処理する感じなのだが、jqMobiではjsonPという別メソッドが用意されているのでこちらを使う。
$.ui.showMask()、$.ui.hideMask()はローディングインジケーターを表示・非表示にするメソッド。jQuery MobileのshowPageLoadingMsg/hidePageLoadingMsgに相当。
ちなみにjQUiではwindow.alertとかを置き換えてるらしく、独自のUIで表示される。

表示する

さて、戻ってきた結果を表示したいところだが、タグを文字列連結とかやりたくないのでテンプレートエンジンが欲しい。pluginsディレクトリにjq.template.jsというのがあるのでとりあえずそれで。
jq.templateについての説明はチートシートに書いてある。…が、その通りにやっても動かないので気をつけろ。
簡単な使い方は以下の通り。

$.template('<li><%= name %></li>', {name: 'jhoshina'});
// => '<li>jhoshina</li>'

では、テンプレの追加とonSuccessの実装。

<script id="status-tmpl" type="text/x-jq-template">
<li class="status">
  <figure>
    <img src="<%= profile_image_url %>" />
  </figure>
  <div>
    <span class="user_name"><%= from_user_name %></span>
    <span class="screen_name"><%= from_screen_name %></span>
    <div class="text"><%= text %></div>
  </div>
</li>
</script>
var onSuccess = function(data) {
  var results = data.results;
  var i, tags = '';
  var tmpl = $('#status-tmpl').html();
  for (i = 0; i < results.length; i++) {
    var r = results[i];
    tags += $.template(tmpl, r);
  }
  $('#results').html(tags);
  $.ui.hideMask();
};

内容的にはだいたい表示されるのだが、jq.ui.cssで

ul > li { height: 48px; }

とかふざけた定義がされているので、もろもろ見た目の修正を入れる。

#search-form {
  display: block;
  text-align: center;
  margin: 8px;
}
#search-form [type="search"] {
  display: block;
  width: 90%;
  margin: 0 auto;
  padding-left: 0.5em;
  padding-right: 0.5em;
  font-size: 200%;
}
.status {
  display: -webkit-box;
  height: auto;
}
.status > :first-child {
  display: block;
  width: 50px;
  -webkit-box-sizing: border-box;
  padding: 1px;
}
.status > :last-child {
  -webkit-box-flex: 1;
  -webkit-box-sizing: border-box;
  padding: 4px 8px;
}

f:id:jhoshina:20120325211217p:plain

うまく表示できたようですね。めでたしめでたし。

ソースはこちらで。