( ꒪⌓꒪) ゆるよろ日記

( ゚∀゚)o彡°オパーイ!オパーイ! ( ;゚皿゚)ノシΣ フィンギィィーーッ!!!

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が指定されているので、サーバから返されたjavascriptJQueryによって自動的に実行される。


では、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が返されていることが確認できる。