7.Ajax Form

Ajax型のFORMを作るのも簡単で、全てSnippet 1ソースだけで完結します。JavaScriptをごにょごにょしたり、remoteなんとかファイルをごにょにごにょしたりなどしない。

HTML要素を作るとき、

 SHtml.text( currentValue , funcOnSubmit )

という形を、

 SHtml.ajaxText( currentValue , funcOnBlur )

に変えるだけです。 funcOnBlurは、HTML要素をonBlur時に発動する、(String) => JsCmd 型のサーバーサイド関数です。

Ajaxを実装するにも関わらず、書かなければならないJavaScriptは、サーバサイド関数実行後のブラウザアクション(JsCmd)だけです。

ログインFORMをAjaxで実装してみます。テンプレートには、Ajaxによる入力エラー通知をするエリアを用意してみました。

■テンプレート:

  <form data-lift="loginFormAjax?form=post">
    ログインID:
    <input type="text" name="login" size="24" maxlength="24"/>
    <span class="invalid" id="login_error"></span><br/>
    パスワード:
    <input type="password" name="password" size="24" maxlength="24"/>
    <span class="invalid" id="password_error"></span><br/>
    <input type="submit" value="ログイン" />
  </form>

■Snippet:

class LoginFormAjax {
  
  object login extends SessionVar("")
  object password extends SessionVar("")
  
  def render = {
    
    def testLogin(s:String)  : JsCmd = {
      if( s.isEmail ){
        login(s)
        Noop
      }else{
        val msg = "メールアドレスを\n正しく入力してください".encJs
        Run("""
        alert(%s);
        $("input[type=text]").css("border-color","red");
        """.format(msg))
      }
    }
    def testPassword(s:String) : JsCmd = {
      if( s.length >= 4 ){
        password(s)
        S.error("password_error","")
      }else{
        S.error("password_error","パスワードを4文字以上で入力してください")
      }
    }
    
    def process : JsCmd = {
      User.authenticate( login, password ) match {
        case Full(user) =>
          S.redirectTo("mypage")
        case _ =>
          Run("""alert("ログインできません");""")
      }
    }

    "name=login" #> SHtml.ajaxText( login.is, testLogin(_) ) &
    "name=password" #>
      SHtml.ajaxText( password.is, testPassword(_),"type"->"password") &
    "type=submit" #> SHtml.ajaxButton( <span>Join !</span>, process _ )
  }
}

※この例ではすべての要素をAjaxにしていますが、使いたい要素にだけ使ってOKです。統一しなければならないというルールもありません。

注目点は、

  • 複数のリクエストで完結するので、login/passwordのスコープはSessionVar。
  • onBlurのコールバック関数の型は、(String)=>JsCmd 。
  • JsCmdは、関数実行後にブラウザ上で実行されるJavaScriptのラッパー。Run("")で生JSが書ける。Noopは何もしないJS(UnitはNoopに変換される)。
  • JavaScriptを壊しそうな文字列(改行やクォーテーションなど)は、String.encJsでエスケープできる。
  • S.errorは、Ajaxに対応している。

JsCmdには、DOMの書き換えや条件分岐などを安全にできるラッパーが用意されているので、APIリファレンスでサブタイプを参照してください。過去のエントリLiftでAjaxも少し役立つかもしれません。


このシリーズ

1.Lift再入門
2.Snippetメソッドとして許される型
3.ログインFORM - S.param使ったら負け
4.サーバーサイドバリデーションとサーバサイド関数
5.行列型の編集FORM
6.Radio、Checkboxが鬼門?
7.Ajax Form
8.javascriptからsubmitできない

動作確認サンプルコード github
Simply Lift(必読)


同じカテゴリのエントリ
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.