On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
<[email protected]> wrote:
> Hi, all,
>
> I'm working on an AJAX form and feel like I'm missing something:
> namely, how to update the page based upon the result of the form
> submission.
>
> The three ajaxForm methods in SHtml have the following signatures:
>
> def ajaxForm(body : NodeSeq)
> def ajaxForm(body : NodeSeq, onSubmit : JsCmd)
> def ajaxForm(body : NodeSeq, onSubmit : JsCmd, postSubmit : JsCmd)
>
> In these signatures, onSubmit is called by the client prior to form
> submission, and postSubmit is called by the client after successful
> submission. My question is, why is there not a signature like this:
>
> def ajaxForm(body: NodeSeq, result: () => JsCmd)
>
> for which the specified result function will be called, and the JsCmd
> returned to the browser for evaluation after processing of the form
> contents on the server?
>
> Right now, I'm using the following to achieve this effect, but it
> seems really hacky:
>
>        val (psId, psJs) = ajaxCall(JsRaw("dsl_text.value"), text =>
> After(20, SetHtml("results", parse(text))))
>
>        ajaxForm(
>            bind("plan", xhtml,
>                 "dsl" -> SHtml.textarea("", s => (), "id" ->
> "dsl_text", "rows" -> "40", "cols" -> "120"),
>                 "submit" -> SHtml.submit("Parse", () => ())
>            ),
>            psJs.cmd
>        )
>
> Here, JsCmd is actually doing the heavy lifting prior to form
> submission, with noop implementations for handling of the form
> elements. Seems really hacky.
>
> I feel like I've got to be missing something here, like there's got to
> be a better way to implement this such that the parsing of the
> textarea contents can be done by the closure passed to the
> SHtml.textarea call. How can I do this?
>
> Here's an idea I've been toying with for a while; it would be a
> somewhat significant change to Lift but I feel like there would be
> some benefits.
>
> Instead of SHtml.* having signatures like (String, () => Any, (String,
> String)*) => NodeSeq, imagine that there was a parameterized class
> (call it FormElement) that all of the SHtml methods returned, and then
> an implicit conversion from FormElement to NodeSeq. Might look
> something like this:
>
> trait FormElement[T] {
>  def !: T
>  def toNodeSeq: NodeSeq
> }

An addendum: there's an obvious extension available here:

trait FormElement[T] { self =>
  def !: T

  def toNodeSeq: NodeSeq

  def map[U](f: T => U): FormElement[U] = new FormElement[U] {
    lazy val !: U = f(self!)
    lazy val toNodeSeq: NodeSeq = self.toNodeSeq
  }

  def flatMap[U](f: T => FormElement[U]): FormElement[U] = new
FormElement[U] {
    private lazy val cache = f(self!)
    lazy val !: U = cache!
    lazy val toNodeSeq = self.toNodeSeq ++ cache.toNodeSeq
  }
}

Kris
-- 
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.


Reply via email to