読者です 読者をやめる 読者になる 読者になる

Lift2.3でAjaxのフォームのパラメータを複数用意すること

備忘録です。
大多数の人はこんなこと悩まないはずですね。。


Lift2.3でごにょごにょものを作っていたときに
ふとAjaxで値を受け取って処理して結果を画面に出したくなりました。
inputでパラメータを受け取って、

<form class="lift:form.ajax">

で受け取って・・・
とやれば簡単に実装できるのでLiftは楽しいです。


と思っていたら複数のパラメータを受け取ろうと思ったら
あれ?となってしまいドツボにはまりました。。
解決するとなんでこんなことに・・・状態です。


HTML側は単純に下のようになります。

          <form class="lift:form.ajax">
            <div class="lift:AjaxSample">
              hoge: <input name="hoge"><br>
              <div id="result"></div>
              <input type="submit" value="Submit">
            </div>
          </form>


Scala側ではまず

import net.liftweb._
import http._
import common._
import util.Helpers._
import js._
import JsCmds._
import JE._
import scala.xml.NodeSeq

とインポートしておいてからobjectを作ります。

object AjaxSample {
  def render = {
    // inputから値を受け取る変数
    var hoge = ""

    // ブラウザに戻されて実行される処理
    // 実際はjsに内部変換されている?
    def process(): JsCmd= {
        // ここに何かメインの処理を書いていく
      }
    }

    // 画面から値を受け取って変数に格納、結果を画面へ
    "name=hoge" #> (SHtml.text(hoge, hoge = _) ++ SHtml.hidden(process))
  }
}

となります。
いろいろやってますが

"name=hoge" #> (SHtml.text(hoge, hoge = _) ++ SHtml.hidden(process))

の部分で画面の入力値を変数へバインドして処理して画面へ返しています。


さてこれは画面入力値が1つの時。
2個、3個と増えたときどうする?というのが今回の詰まったポイントでした。
HTMLは下のようにしました。

          <form class="lift:form.ajax">
            <div class="lift:AjaxSample">
              hoge: <input name="hoge"><br>
              piyo: <input name="piyo"><br>
              <div id="result"></div>
              <input type="submit" value="Submit">
            </div>
          </form>

先ほど

"name=age" #> (SHtml.text(hoge, hoge = _) ++ SHtml.hidden(process))

と書いたこの部分にどう複数のパラーメタを渡せばいいのか悩んでしまったのです。。


まずやった動くけどイマイチな例

object AjaxSample {
  def render = {
    var hoge = ""
    var piyo = ""

    def process(): JsCmd= {
        // メインの処理
      }
    def dummy(): JsCmd= {
        // 何もしない
      }
    }

    "name=hoge" #> (SHtml.text(hoge, hoge = _) ++ SHtml.hidden(dummy)) &
    "name=piyo" #> (SHtml.text(piyo, piyo = _) ++ SHtml.hidden(process))
  }
}

最初の

    "name=hoge" #> (SHtml.text(hoge, hoge = _) ++ SHtml.hidden(dummy)) &

の部分で何もしないdummyメソッドを呼んで、
処理はせずに変数に値を格納するというもの。
"#>"による値のセットは"&"で続けられますので悪用(?)しました。
動きますけど・・・ですね。


上のように書きながら視野が狭くなってましたが
画面から値を受け取る方法は

"name=hoge" #> SHtml.text(hoge, hoge = _, "id" -> "hogehoge") &
"name=piyo" #> (SHtml.text(piyo, piyo = _) ++ SHtml.hidden(process))

が正解のようです。
SHtml.textはこういう使い方もできるんですね。
3番目の引数でHTMLのinputタグのidを指定しています。
ですのでHTML側を

hoge: <input name="hoge" id="hogehoge"><br>

と修正してやれば完成です。


・・・とここまでやって気がつきました。

"name=hoge" #> SHtml.text(hoge, hoge = _) &
"name=piyo" #> (SHtml.text(piyo, piyo = _) ++ SHtml.hidden(process))

で良いのです。
はじめから難しく考えすぎず素直にやってれば良かったんですね。


ただ単にSHtml.textの使い方を知らなさ過ぎただけですね・・・。
ちゃんと勉強しないとダメですね・・・。

Simply Lift -
http://stable.simply.liftweb.net/#toc-Chapter-4