Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Naftoli Gugenheim
Those names seem counterintuitive to me. ajaxSubmit submits an ajax form but 
submitAjaxForm submits a non-ajax form? submitAjaxForm implies that it should 
be the reverse, no?

-
Mariusmarius.dan...@gmail.com wrote:

Instead of

 submit - SHtml.submit(Parse, () = ())

use:

 submit - SHtml.ajaxSubmit(Parse, () = ())

you can also send normal forms via ajax like:

SHtml.submitAjaxForm(formId, () = {

  /// Do your stuff here. This function will be called after form
field functions are executed.
 Noop
})


Br's,
Marius

On Jan 21, 9:03 pm, Kris Nuttycombe kris.nuttyco...@gmail.com wrote:
 *thump* *thump* Hello, is this thing on? :)

 On Wed, Jan 20, 2010 at 10:20 AM, Kris Nuttycombe

 kris.nuttyco...@gmail.com wrote:
  On Wed, Jan 20, 2010 at 9:51 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com wrote:
  On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com 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
   }
  }

  On second thought, that FormElement implementation as a monad is wrong
  because toNodeSeq would cause strict evaluation of the closure when
  used in the SHtml.* case. Maybe FormElement just has to be a functor
  and not a monad.

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


-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Kris Nuttycombe
On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com wrote:
 Instead of

  submit - SHtml.submit(Parse, () = ())

 use:

  submit - SHtml.ajaxSubmit(Parse, () = ())

 you can also send normal forms via ajax like:

 SHtml.submitAjaxForm(formId, () = {

  /// Do your stuff here. This function will be called after form
 field functions are executed.
  Noop
 })


 Br's,
 Marius

Thanks, Marius. I've just updated from M1 to the snapshot to get
ajaxSubmit; however, it doesn't address my question as to why the
function passed to AjaxSubmit doesn't return a JsCmd that can be used
to refresh the page.

Also, any thoughts on my proposal?

Kris



 On Jan 21, 9:03 pm, Kris Nuttycombe kris.nuttyco...@gmail.com wrote:
 *thump* *thump* Hello, is this thing on? :)

 On Wed, Jan 20, 2010 at 10:20 AM, Kris Nuttycombe

 kris.nuttyco...@gmail.com wrote:
  On Wed, Jan 20, 2010 at 9:51 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com wrote:
  On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com 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
   }
  }

  On second thought, that FormElement implementation as a monad is wrong
  because toNodeSeq would cause strict evaluation of the closure when
  used in the SHtml.* case. Maybe FormElement just has to be a functor
  and not a monad.

  Kris

 --
 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.




-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




[Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Marius


On Jan 21, 11:15 pm, Kris Nuttycombe kris.nuttyco...@gmail.com
wrote:
 On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com wrote:
  Instead of

   submit - SHtml.submit(Parse, () = ())

  use:

   submit - SHtml.ajaxSubmit(Parse, () = ())

  you can also send normal forms via ajax like:

  SHtml.submitAjaxForm(formId, () = {

   /// Do your stuff here. This function will be called after form
  field functions are executed.
   Noop
  })

  Br's,
  Marius

 Thanks, Marius. I've just updated from M1 to the snapshot to get
 ajaxSubmit; however, it doesn't address my question as to why the
 function passed to AjaxSubmit doesn't return a JsCmd that can be used
 to refresh the page.

The ajaxSubmit has the signature:

def ajaxSubmit(value: String, func: () = Any, attrs: (String, String)
*)

returns an Any because Lift looks for the following:

JsCmd,
NodeSeq
JsCommands
LiftResponse

however for consistency reasons I think I should change it to  func:
() = JsCmd


 Also, any thoughts on my proposal?

I don't really see the benefits in doing that.


 Kris



  On Jan 21, 9:03 pm, Kris Nuttycombe kris.nuttyco...@gmail.com wrote:
  *thump* *thump* Hello, is this thing on? :)

  On Wed, Jan 20, 2010 at 10:20 AM, Kris Nuttycombe

  kris.nuttyco...@gmail.com wrote:
   On Wed, Jan 20, 2010 at 9:51 AM, Kris Nuttycombe
   kris.nuttyco...@gmail.com wrote:
   On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
   kris.nuttyco...@gmail.com 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
    }
   }

   On second thought, that FormElement implementation as a monad is wrong
   because toNodeSeq would cause strict evaluation of the closure when
   used in the SHtml.* case. Maybe FormElement just has to be a functor
   and not a monad.

   Kris

  --
  You received this message because you are subscribed to the Google Groups 
  Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to 
  liftweb+unsubscr...@googlegroups.com.
  For more options, visit this group 
  athttp://groups.google.com/group/liftweb?hl=en.
-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 

Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Kris Nuttycombe
On Thu, Jan 21, 2010 at 2:43 PM, Marius marius.dan...@gmail.com wrote:


 On Jan 21, 11:15 pm, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:
 On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com wrote:
  Instead of

   submit - SHtml.submit(Parse, () = ())

  use:

   submit - SHtml.ajaxSubmit(Parse, () = ())

  you can also send normal forms via ajax like:

  SHtml.submitAjaxForm(formId, () = {

   /// Do your stuff here. This function will be called after form
  field functions are executed.
   Noop
  })

  Br's,
  Marius

 Thanks, Marius. I've just updated from M1 to the snapshot to get
 ajaxSubmit; however, it doesn't address my question as to why the
 function passed to AjaxSubmit doesn't return a JsCmd that can be used
 to refresh the page.

 The ajaxSubmit has the signature:

 def ajaxSubmit(value: String, func: () = Any, attrs: (String, String)
 *)

 returns an Any because Lift looks for the following:

 JsCmd,
 NodeSeq
 JsCommands
 LiftResponse

 however for consistency reasons I think I should change it to  func:
 () = JsCmd


 Also, any thoughts on my proposal?

 I don't really see the benefits in doing that.

The benefit is predictability; with the current functionality, as I
understand it, the order of evaluation of closures associated with
form elements is dependent upon the order in which those elements are
added to the form. What my proposal does is (1) eliminate the need to
close over local vars and (2) eliminate the dependence upon order of
declaration.

In essence, my proposal is to give the user the ability to, in
addition to having those closures invoked automatically on the
processing of a form, be able to explicitly invoke them during form
processing.

I really dislike the pattern:

def mySnippet(xhtml: NodeSeq) {
  var a: Option[String] = None

  bind(a, xhtml,
 value - text(. s = a = Some(s)),
 submit - submit(Submit, () = a.foreach(doSomething _)
  )
}

With my proposal, this would become:

def mySnippet(xhtml: NodeSeq) {
   val aField = text(s, s = s)

  bind(a, xhtml,
 value - aField,
 submit - submit(Submit, () = doSomething(a!))
  )
}

This becomes really advantageous, I think, when you're talking about
15 or 20 different form elements. The var solution in that case
becomes totally unwieldy because of the unwrapping of all of the
Options.

Kris



 Kris



  On Jan 21, 9:03 pm, Kris Nuttycombe kris.nuttyco...@gmail.com wrote:
  *thump* *thump* Hello, is this thing on? :)

  On Wed, Jan 20, 2010 at 10:20 AM, Kris Nuttycombe

  kris.nuttyco...@gmail.com wrote:
   On Wed, Jan 20, 2010 at 9:51 AM, Kris Nuttycombe
   kris.nuttyco...@gmail.com wrote:
   On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
   kris.nuttyco...@gmail.com 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 

Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Kris Nuttycombe
On Thu, Jan 21, 2010 at 2:43 PM, Marius marius.dan...@gmail.com wrote:


 On Jan 21, 11:15 pm, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:
 On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com wrote:
  Instead of

   submit - SHtml.submit(Parse, () = ())

  use:

   submit - SHtml.ajaxSubmit(Parse, () = ())

  you can also send normal forms via ajax like:

  SHtml.submitAjaxForm(formId, () = {

   /// Do your stuff here. This function will be called after form
  field functions are executed.
   Noop
  })

  Br's,
  Marius

 Thanks, Marius. I've just updated from M1 to the snapshot to get
 ajaxSubmit; however, it doesn't address my question as to why the
 function passed to AjaxSubmit doesn't return a JsCmd that can be used
 to refresh the page.

 The ajaxSubmit has the signature:

 def ajaxSubmit(value: String, func: () = Any, attrs: (String, String)
 *)

 returns an Any because Lift looks for the following:

 JsCmd,
 NodeSeq
 JsCommands
 LiftResponse

I think I must be misunderstanding something - should I expect the
following to work?

var text: Option[String] = None
ajaxForm(
bind(plan, xhtml,
 dsl - textarea(, s = text = Some(s), id -
dsl_text, rows - 40, cols - 120),
 submit - ajaxSubmit(Create Plan, () =
SetHtml(results, buildPlan(text.get)))
)
)

where there is div id=results/ in the rendered page? I don't seem
to get the expected results back, though it's clear from logging that
this is being processed correctly.

Kris

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Kris Nuttycombe
On Thu, Jan 21, 2010 at 4:36 PM, Kris Nuttycombe
kris.nuttyco...@gmail.com wrote:
 On Thu, Jan 21, 2010 at 2:43 PM, Marius marius.dan...@gmail.com wrote:


 On Jan 21, 11:15 pm, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:
 On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com wrote:
  Instead of

   submit - SHtml.submit(Parse, () = ())

  use:

   submit - SHtml.ajaxSubmit(Parse, () = ())

  you can also send normal forms via ajax like:

  SHtml.submitAjaxForm(formId, () = {

   /// Do your stuff here. This function will be called after form
  field functions are executed.
   Noop
  })

  Br's,
  Marius

 Thanks, Marius. I've just updated from M1 to the snapshot to get
 ajaxSubmit; however, it doesn't address my question as to why the
 function passed to AjaxSubmit doesn't return a JsCmd that can be used
 to refresh the page.

 The ajaxSubmit has the signature:

 def ajaxSubmit(value: String, func: () = Any, attrs: (String, String)
 *)

 returns an Any because Lift looks for the following:

 JsCmd,
 NodeSeq
 JsCommands
 LiftResponse

 I think I must be misunderstanding something - should I expect the
 following to work?

        var text: Option[String] = None
        ajaxForm(
            bind(plan, xhtml,
                 dsl - textarea(, s = text = Some(s), id -
 dsl_text, rows - 40, cols - 120),
                 submit - ajaxSubmit(Create Plan, () =
 SetHtml(results, buildPlan(text.get)))
            )
        )

 where there is div id=results/ in the rendered page? I don't seem
 to get the expected results back, though it's clear from logging that
 this is being processed correctly.

 Kris


A bit more, intriguing information: is SetHtml size-limited? It seems
to work fine if what I'm passing back is just a URL or something, but
if I pass back a 1.5k error message, the message never seems to
appear.

Kris

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread David Pollak
On Thu, Jan 21, 2010 at 4:04 PM, Kris Nuttycombe
kris.nuttyco...@gmail.comwrote:

 On Thu, Jan 21, 2010 at 4:36 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:
  On Thu, Jan 21, 2010 at 2:43 PM, Marius marius.dan...@gmail.com wrote:
 
 
  On Jan 21, 11:15 pm, Kris Nuttycombe kris.nuttyco...@gmail.com
  wrote:
  On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com
 wrote:
   Instead of
 
submit - SHtml.submit(Parse, () = ())
 
   use:
 
submit - SHtml.ajaxSubmit(Parse, () = ())
 
   you can also send normal forms via ajax like:
 
   SHtml.submitAjaxForm(formId, () = {
 
/// Do your stuff here. This function will be called after form
   field functions are executed.
Noop
   })
 
   Br's,
   Marius
 
  Thanks, Marius. I've just updated from M1 to the snapshot to get
  ajaxSubmit; however, it doesn't address my question as to why the
  function passed to AjaxSubmit doesn't return a JsCmd that can be used
  to refresh the page.
 
  The ajaxSubmit has the signature:
 
  def ajaxSubmit(value: String, func: () = Any, attrs: (String, String)
  *)
 
  returns an Any because Lift looks for the following:
 
  JsCmd,
  NodeSeq
  JsCommands
  LiftResponse
 
  I think I must be misunderstanding something - should I expect the
  following to work?
 
 var text: Option[String] = None
 ajaxForm(
 bind(plan, xhtml,
  dsl - textarea(, s = text = Some(s), id -
  dsl_text, rows - 40, cols - 120),
  submit - ajaxSubmit(Create Plan, () =
  SetHtml(results, buildPlan(text.get)))
 )
 )
 
  where there is div id=results/ in the rendered page? I don't seem
  to get the expected results back, though it's clear from logging that
  this is being processed correctly.
 
  Kris
 

 A bit more, intriguing information: is SetHtml size-limited? It seems
 to work fine if what I'm passing back is just a URL or something, but
 if I pass back a 1.5k error message, the message never seems to
 appear.


It's not size limited AFAIK.  Some browsers may have a limit on String
length or the ability to parse super-long JavaScript, but you're probably
looking at 16M (24 bits).



 Kris

 --
 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.comliftweb%2bunsubscr...@googlegroups.com
 .
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.




-- 
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Surf the harmonics

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Kris Nuttycombe
Okay, I think I may have found a bug.

My returned content contains unescaped braces. In one failure case
(this is parsing a DSL) I was testing a parse of a missing end brace -
and part of the error message is the original text passed in (with
mismatched braces).

Figured it out by passing in content with a superfluous end brace -
that error returns fine. :)

Thought I was going nuts.

Kris

On Thu, Jan 21, 2010 at 5:08 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:


 On Thu, Jan 21, 2010 at 4:04 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 On Thu, Jan 21, 2010 at 4:36 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:
  On Thu, Jan 21, 2010 at 2:43 PM, Marius marius.dan...@gmail.com wrote:
 
 
  On Jan 21, 11:15 pm, Kris Nuttycombe kris.nuttyco...@gmail.com
  wrote:
  On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com
  wrote:
   Instead of
 
    submit - SHtml.submit(Parse, () = ())
 
   use:
 
    submit - SHtml.ajaxSubmit(Parse, () = ())
 
   you can also send normal forms via ajax like:
 
   SHtml.submitAjaxForm(formId, () = {
 
    /// Do your stuff here. This function will be called after form
   field functions are executed.
    Noop
   })
 
   Br's,
   Marius
 
  Thanks, Marius. I've just updated from M1 to the snapshot to get
  ajaxSubmit; however, it doesn't address my question as to why the
  function passed to AjaxSubmit doesn't return a JsCmd that can be used
  to refresh the page.
 
  The ajaxSubmit has the signature:
 
  def ajaxSubmit(value: String, func: () = Any, attrs: (String, String)
  *)
 
  returns an Any because Lift looks for the following:
 
  JsCmd,
  NodeSeq
  JsCommands
  LiftResponse
 
  I think I must be misunderstanding something - should I expect the
  following to work?
 
         var text: Option[String] = None
         ajaxForm(
             bind(plan, xhtml,
                  dsl - textarea(, s = text = Some(s), id -
  dsl_text, rows - 40, cols - 120),
                  submit - ajaxSubmit(Create Plan, () =
  SetHtml(results, buildPlan(text.get)))
             )
         )
 
  where there is div id=results/ in the rendered page? I don't seem
  to get the expected results back, though it's clear from logging that
  this is being processed correctly.
 
  Kris
 

 A bit more, intriguing information: is SetHtml size-limited? It seems
 to work fine if what I'm passing back is just a URL or something, but
 if I pass back a 1.5k error message, the message never seems to
 appear.

 It's not size limited AFAIK.  Some browsers may have a limit on String
 length or the ability to parse super-long JavaScript, but you're probably
 looking at 16M (24 bits).


 Kris

 --
 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.




 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 --
 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.


-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



[Lift] Re: A better approach to ajax forms?

2010-01-20 Thread Kris Nuttycombe
On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
kris.nuttyco...@gmail.com 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 lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




[Lift] Re: A better approach to ajax forms?

2010-01-20 Thread Kris Nuttycombe
On Wed, Jan 20, 2010 at 9:51 AM, Kris Nuttycombe
kris.nuttyco...@gmail.com wrote:
 On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com 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
  }
 }

On second thought, that FormElement implementation as a monad is wrong
because toNodeSeq would cause strict evaluation of the closure when
used in the SHtml.* case. Maybe FormElement just has to be a functor
and not a monad.

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