scalaのWebフレームワーク liftで遊ぶ(7) - Ajaxでもっとこんにちわ世界
目次はこちら。
scalaのWebフレームワーク liftで遊ぶ 目次 - ゆろよろ日記
「Ajax!Ajax!世界!」
ってことで、今回はLiftでのAjaxのお話です。
いまどきのWebアプリケーションフレームワークはAjaxサポートなんか当たり前なんだぜ?
は今回で終了です。
Ajaxなフォーム
まずはhtml作るよ。これは今まで特に変わったところはない。
src/main/webapp/helloFormAjax.html
<lift:surround with="default" at="content"> <h1>Hello FormAjax</h1> <lift:HelloFormAjax.show> Hello <hello:who/><br/> <label for="whoField">Who :</label><hello:whoField/> <hello:submit/> </lift:HelloFormAjax.show> </lift:surround>
お次はsnipeet作る。
src/main/scala/com/yuroyoro/lift/hellodrawin/snippet/HelloFormAjax.scala
package com.yuroyoro.lift.hellodarwin.snippet import scala.xml.NodeSeq import net.liftweb.http.S._ import net.liftweb.http.SHtml._ import net.liftweb.util.Helpers._ import net.liftweb.http.js.{JsCmd, JsCmds} class HelloFormAjax { def whoNode(str: String) = <span id="who">{str}</span> def updateWho(str: String): JsCmd = { println("updateWho on " + str) JsCmds.Run("$('#who').text('"+str+"')") } def show(xhtml: NodeSeq): NodeSeq = { bind("hello", xhtml, "whoField" --> text("world", null) % ("size" -> "10") % ("id" -> "whoField"), "submit" --> <button type="button">{?("Send")}</button> % ("onclick" -> ajaxCall("$('#whoField').attr('value')", s => updateWho(s))), "who" --> whoNode("world") ) } }
では、中身について説明するわ。
- 前回も出てきたとおり、国際化されたラベルの
% ("onclick" -> ajaxCall("$('#whoField').attr('value')", s => updateWho(s)))
- ここがAjaxのキモ。<button>タグにonclick属性を追加している。
- onclickに追加されるjavascriptは,net.liftweb.http.SHtmlのajaxCallメソッドで生成される。
- ajaxCallの第1引数:javascriptを設定する。ここで渡したjavascriptを実行した結果がサーバに送信される値となる。
- ajaxCallの第2引数:サーバ側の処理を行う関数を設定する。ここでは、updateWhoメソッドを指定している。
updateWho(str: String): JsCmd = { ...
- Ajaxで呼び出された際のサーバ側の処理
- 戻り値は、サーバから送信するデータとなる。ここでは、JsCmdオブジェクトを返しており、クライアントがレスポンスを受け取った際に実行するjavascriptを返している。
- JsCmds.Run("$('#who').text('"+str+"')")
- 引数に渡した文字列をjavascriptとしてクライアントで実行する。
- 例では、JQueryの$を使って、id=whoの中身のテキストを置き換えている。
実行してみると、ページを切り替えなくてもAjax的に表示が切り替わっていることが確認できる。
実際に出力されたHTMLやJavascriptおよびXmlHttpRequestのデータなどをFirebugを使って確認してみた。
出力されたHTML,Javascript
<h1>Hello FormAjax</h1> Hello <span id="who">world</span><br /> <label for="whoField">Who :</label><input size="10" name="F19942950186540_PQI" type="text" value="world" id="whoField" /> <button type="button" onclick="jQuery.ajax( {url: '/ajax_request', type: 'POST', timeout: 10000, cache: false, data: 'F19942950786393_VJU='+encodeURIComponent($('#whoField').attr('value')), dataType: 'script'});">Send</button>
onclickにjQuery.ajax()を呼び出している。送信先は/ajax_request。
data:〜の部分に、ajaxCallメソッドで設定したjavascriptが設定されている。
datatype:scriptが指定されているので、サーバから返されたjavascriptがJQueryによって自動的に実行される。
では、XmlHttpRequestのデータはどうなっているか?
リクエストヘッダー
Host localhost:8080 User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1 Accept text/javascript, application/javascript, */* Accept-Language ja,en-us;q=0.8,en;q=0.5,fr;q=0.3 Accept-Encoding gzip,deflate Accept-Charset Shift_JIS,utf-8;q=0.7,*;q=0.7 Keep-Alive 300 Connection keep-alive Content-Type application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With XMLHttpRequest Referer http://localhost:8080/helloFormAjax Content-Length 28 Cookie JSESSIONID=6whzshpmsw35 Pragma no-cache Cache-Control no-cache
POSTデータ
F19942950786393_VJU hogehoge <|| レスポンス >|| $('#who').text('hogehoge')
フォームの入力値がPOSTデータに設定されて送信され、レスポンスにupdateWho(str: String)メソッドで返したJsCmdオブジェクトのjavascriptが返されていることが確認できる。