前回エントリの最後にちょっとだけ言及した「AjaxもSnippetだけでできますよ」的発言の補足になります。
「triggerをクリックしたら、
placeholderをサーバサイドから返るDOMで書き換える。」
ということをやるViewとSnippetは次のようになります。
■View
<lift:surround with="admin" at="content">
<lift:ajaxSandbox.simple>
<f:trigger />
<div id="placeholder" />
</lift:ajaxSandbox.simple>
</lift:surround>
■Snippet
import _root_.scala.xml._
import _root_.net.liftweb.http._
import _root_.net.liftweb.util._
import Helpers._
import js._
import js.JE._
class AjaxSandbox {
def simple(xhtml: NodeSeq):NodeSeq = {
bind("f", xhtml,
"trigger" -> SHtml.ajaxButton( "push" , doSimple _ )
)
}
def doSimple(): JsCmd = {
println("サーバーサイドの処理")
//ブラウザの実行コマンド
JsCmds.SetHtml( "placeholder", <h1>Ajax!</h1> )
}
}
ボタンではなく、他のエレメントをトリガーにしたければ、
"trigger" -> <span
onclick={SHtml.ajaxInvoke(doSimple _)._2}>Press</span>
サーバサイド関数に引数を持たせる場合は、
"trigger" -> <button
onclick={SHtml.ajaxCall(Str("a"), doSimple _)._2}>Press</button>
def doSimple(s:String): JsCmd = {
println( s + " passed by client")
JsCmds.SetHtml( "placeholder", <h1>Ajax!</h1> )
}
■JsCmd/JsExp
net.liftweb.http.js.{JsCmd,JsExp}は、ブラウザで実行するJavaScriptを生成するヘルパーです。
JsCmd(のサブタイプ)を組み立てるには、JsExp(のサブタイプ)を構成要素にします。
doSimpleの戻りJsCmdは、JavaScriptに展開後ブラウザ上に返されて実行されます。
出来上がったJavaScriptは、JsCmd.toJsCmd(String型)で確認できるので、コンソールなどで試してみると良いと思います。
>mvn compile scala:console -DmainConsole=LiftConsole
scala> import _root_.net.liftweb.http._
scala> import _root_.net.liftweb.util.Helpers._
scala> import js._
scala> import js.JsCmds._
scala> import js.JE._
scala> implicit def writer( cmd:JsCmd ) = new {
def w = println( cmd.toJsCmd )
}
(おしりに"w"つけるとJavaScriptに展開するようにしておく)
scala> SetHtml("placeholder" , <span>Yes</span> ) w
try{jQuery("#placeholder").each(function(i) {this.innerHTML = "<span>Yes</span>"
;});} catch (e) {}
scala> JsShowId("div_id") w
jQuery('#'+"div_id").show();
scala> After( 10 minutes , JsShowId("div_id") ) w
setTimeout(function() {jQuery('#'+"div_id").show();}, 600000);
scala> JsCrVar( "name", JsVar("takeda") ) w
var name = takeda;
・・・など。複雑なJavaScriptを組もうと思ったら、JsDoWhile/JsIfとかもありますが、ぶっちゃけこんなことしていられないので、生JavaScriptのラッパー・Runを使いましょうw
scala> Run("""alert('hello')""") w
alert('hello')
JsCmd/JsExpはタイプセーフにJavaScriptを組んでやる仕組みのようです。慣れないと大変そうなので、複雑なことをやりたければ、
・Runを使う、または、
・jQueryを生でコーディングしてブラウザにロード&Runでメソッドキック
くらいで十分ではないかなと思います。
■JsExpについて補足
SHtml.ajaxCall(Str("a"), doSimple _)
で出てきたStrはJsExpのサブタイプです。
ブラウザでのJsExp(が生成したJavaScript)の実行結果が、doSimpleへの引数に渡されます。
(前の続き)
scala> implicit def writer( exp:JsExp ) = new {
def w = println( exp.toJsCmd )
}
scala> Str("a") w
"a"
scala> Call("some_function") w
some_function()
scala> ValById("user_name") w
document.getElementById("user_name").value
どんな動きするのかは、慣れるまではJavaScriptに展開してみないとわからない感じですが、一応jQueryは隠蔽されていて(w)重要だと思うので何度もいいますが、SnippetだけでAjaxが出来ています。
トリガー設定方法は、SHtml.{ajaxButton,ajaxCall,ajaxInvoke} の他にもいろいろありますが、次回以降(自分もまだ全部は把握していません)。