On Thu, Nov 19, 2009 at 2:52 PM, Chris Lewis <[email protected]> wrote:
> Classic use case: a user chooses to view/edit and object by clicking on
> a link. This causes the app to fetch an edit view (form) and render it
> asynchronously, probably rendering it as a modal dialog. To specify the
> case a bit more, consider a table of like objects that allows you to
> edit them (orders or accounts). As far as the user experience, clicking
> edit for one would yield the same edit form as any other - only the
> contents (the target of the edit) would change.
>
> Normal ajax forms in lift are simple - just wrap the bind in an ajax
> form (http://is.gd/4Z61Z) and you get an async submit with essentially
> the same template code.
>
> But what about ajax forms delivered by ajax? What's the best way to
> implement this in lift? It seems like there are two routes: client and
> server-based.
>
>
> 1) In the client-based approach, I can declare an invisible form in the
> template, as well as write some static javascript to do the heavy
> lifting (no pun intended). This JS would be responsible for receiving
> the data representing the object to edit from the server as json,
> unpacking it into the form for editing, rendering the form, handling the
> submit as ajax, and finally hiding the form.
>
> This means writing a good bit more JS by hand, but it keeps the
> (compiled) snippet code smaller. Ordinarily I'd see that as good, but
> more and more snippets seem like they are intended for such heavy view
> meddling.
>
>
> 2) The server-based approach would require very little of the main
> template: basically just a containing element (w/ dom id) to host the
> delivered form. The snippet itself would yield a form on an ajax call
> via SetHtml. It would also have to set up the handlers and populate the
> form contents with the target object.
>
> This is the part that I'm not clear on. I know I can just inline the XML
> with bind points as if it were in a form, but that just feels strange.
> Would it make more sense to use an external template, similar to a rails
> partial? Is there a template loading facility for this?
>
> Thanks for any and all input.
>
> chris

I use the second style, to great effect, in Lift - except I use
net.liftweb.http.TemplateFinder.findAnyTemplate to get the NodeSeq
representing the template instead of inlining the XML, and then use a
normal call to bind. It works a treat.

There are a couple of utility traits that I use to make this even
cleaner; I don't have time to detail how they're used at the moment
but maybe you can get a little bit of an idea by looking at the types.
One of these days I'll clean these up into something truly reusable
(these rely on the bindings stuff I detailed on my blog at
http://logji.blogspot.com/2009/09/composable-bindings-in-lift.html
with a couple of extra things, tbind and the Templated trait.

def tbind(x: Binding with Templated): NodeSeq = x.bind(x.template)

trait Templated {
    def template: List[String]
}

trait Form[T] {
    def onSubmit: Unit = process
    def process: T
}

trait FormSnippets {
    this: StatefulSnippet =>

    var actionBinding: Binding with Templated = _
    var editFormBinding: Binding with Templated = _

    lazy val dispatch: DispatchIt = {
        case "actionSelect" => actionBinding
        case "editForm" => editFormBinding
    }

    def ajaxify(b: Binding with Templated with Form[_],
clientOnSubmit: JsCmd, serverRedirect: Option[String]) = new Binding
with Templated {
        override val template = b.template
        override def apply(xhtml: NodeSeq): NodeSeq = {
            def serverOnSubmit: JsCmd = {
                b.onSubmit

                serverRedirect.map(where => RedirectTo(where)).
                getOrElse(SetHtml("action_selector",
tbind(actionBinding)) & SetHtml("edit_form", tbind(editFormBinding)))
            }

            ajaxForm(b.apply(xhtml) ++ hidden(serverOnSubmit _), clientOnSubmit)
        }
    }
}

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=.


Reply via email to