On Thu, Jan 21, 2010 at 2:43 PM, Marius <[email protected]> wrote:
>
>
> On Jan 21, 11:15 pm, Kris Nuttycombe <[email protected]>
> wrote:
>> On Thu, Jan 21, 2010 at 12:23 PM, Marius <[email protected]> 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 <[email protected]> wrote:
>> >> *thump* *thump* Hello, is this thing on? :)
>>
>> >> On Wed, Jan 20, 2010 at 10:20 AM, Kris Nuttycombe
>>
>> >> <[email protected]> wrote:
>> >> > On Wed, Jan 20, 2010 at 9:51 AM, Kris Nuttycombe
>> >> > <[email protected]> wrote:
>> >> >> 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
>> >> >> }
>> >> >> }
>>
>> >> > 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 [email protected].
>> > To unsubscribe from this group, send email to
>> > [email protected].
>> > 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 [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.
>
>
>
>
--
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.