LiftでAjax

LiftのAjaxライブラリにはjQueryが採用されていますが、あまりjQueryを知らなくても、SnippetだけでAjaxなWebアプリが組めるように工夫されています。

前回エントリの最後にちょっとだけ言及した「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} の他にもいろいろありますが、次回以降(自分もまだ全部は把握していません)。


同じカテゴリのエントリ
1.Lift再入門 / 8.javascriptからsubmitできない / 7.Ajax Form / 6.Radio、Checkboxについて / 5.行列型の編集FORM / 4.サーバーサイドバリデーションとサーバサイド関数 / 3.ログインFORM - S.param使ったら負け / 2.Snippetメソッドとして許される型 / sbt0.12.xで依存jar抽出タスク / scala2.10+lift2.5+NetBeans7.2 / Scalaで入門関数プログラミング / reactive-webを試してみました / Lift2.2M1のテンプレート機能 / Scala Compiler Plugin / View Bound/Context Bound / ScalaZa01参加してきました / Akka Frameworkチュートリアルの次 / Akka Frameworkチュートリアルその2 / Akka Frameworkチュートリアル / LiftでJCaptcha / Url Rewrite Filter / sbt-android-plugin / Android SDK for Scala / 祝Lift2.0リリース / Liftの携帯対応まとめ / Scala2.8への移行 / Lift 2.0-scala280-SNAPSHOT/sbt0.7.1 / Scalaお絵かき環境 - Kojo / Lift+Quartzでバッチ / Scala&Liftを採用した理由 / Liftでdate_select系ヘルパーを作る / LiftでAjax / LiftのSubmitかしこい / lift-mapperのpaginateを使う / snippetをspecする / Lift Mapperを拡張する / LiftのDBをMySQLに / Liftプロジェクト環境を整える / Scala本読み比べてみました / NetBeans6.7&scala / じつはScalaはライトな言語 / Scalaバザ~ル / lift1.0所感 / specsを読む / implicit def / ScalaならNetBeansがサイコー / scala勉強会@東北がスタート / それでも俺はLiftをやるってのか / Scala&Liftセットアップ / ブログリニューアル /
コメント

コメントしてください

closed.