It's not that it doesn't do what my code does. But in the long run it doesn't
sound shorter. Also it's not totally based on boxes anymore.
Also, my proposal would allow me to write:
bindSwitch("req", xhtml, Seq("hasClient", "noClient"),
{(ns:NodeSeq) => xxx match {
case yyy => 0 -> bind("client", ns, ...)
case zzzz => 1 -> bind("client, ns, ...)
}})
Also using my implicit several such invocations could easily be chained.
-------------------------------------
David Pollak<[email protected]> wrote:
On Mon, Aug 10, 2009 at 11:18 AM, Naftoli Gugenheim <[email protected]>wrote:
> The problem with using the template methods is that they pull the node out
> of context. So if I need to let the view html file decide how everything is
> assembled, then these calls to the template methods have to be used inside a
> bind. You can put the alternatives inside a dedicated parent xml node and
> bind on that (sometimes), but what have I saved?
I don't understand your question.
I don't understand the pattern you are trying to use.
I don't understand what kind of context a node might have other than binding
based on a condition.
What does the code that I wrote not do that your code does?
>
> Thanks.
>
> -------------------------------------
> David Pollak<[email protected]> wrote:
>
> On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim <[email protected]
> >wrote:
>
> > Here's some view xhtml:
> >>
> >> <req:noClient>
> >
> > <label for="clientquery">Client </label>
> >
> > <client:query id="clientquery" size="5"/>
> >
> > <client:set />
> >
> > </req:noClient>
> >
> > <req:client>
> >
> > Client <client:unset />
> >
> > <client:edit><client:name /></client:edit><br />
> >
> > <client:details />
> >
> > </req:client>
> >
> > <hr />
> >
> >
>
> How about:
>
> def doBinding(xhtml: NodeSeq): NodeSeq = {
> def doClientBind(c: Client): Box[NodeSeq] =
> Helpers.template(xhtml, "req", "client").map(t => bind("client", t,
> ...))
>
> def doClientFreeBind: Box[NodeSeq] =
> Helpers.template(xhtml, "req", "noClient").map(t => bind("client", t,
> ...))
>
> (client.flatMap(doClientBind) or doClientFreeBind) openOr NodeSeq.Empty
> }
>
>
>
> >
> > And here's some snippet code:
> >
> >> xhtml.bind("req",
> >
> > "noClient" -> noClient _,
> >
> > "client" -> hasClient _,
> >
> > ...
> >
> > )
> >
> > def noClient(xhtml: NodeSeq) = {
> >
> > var clientQuery: String = ""
> >
> > def queryClient {
> >
> > ...
> >
> > }
> >
> > client match {
> >
> > case None =>
> >
> > xhtml.bind("client",
> >
> > "query" -> keepAttrs(SHtml.text(clientQuery, clientQuery =
> _)),
> >
> > "set" -> SHtml.submit(?(">"), ()=>queryClient)
> >
> > )
> >
> > case Some(_) =>
> >
> > NodeSeq.Empty
> >
> > }
> >
> > }
> >
> >
> > So both alternatives are always bound to a NodeSeq=>NodeSeq function, and
> > both functions have to check if client is None or a Some, and always one
> > function returns NodeSeq.Empty and the other one something useful.
> > So my question is not, "how can I do xxx," but, "is there a 'DRY'er or
> more
> > concise way to do it."
> > In another place I used a slightly different technique:
> >
> >> val emptyFn = (ns: NodeSeq) => NodeSeq.Empty
> >
> > def noLocationKind = (ns: NodeSeq) => ...
> >
> > def hasLocationKind(kind: LocKind#Value) = (ns:NodeSeq) => ...
> >
> > ns.bind("nlt",
> >
> > // "name" -> {(ns:NodeSeq)=>Text("foo")},
> >
> > "locKind" -> lkOpt.map(hasLocationKind).getOrElse(emptyFn),
> >
> > "noLocKind" -> (if(lkOpt==None) noLocationKind else emptyFn)
> >
> > ).bind("nlt","name"->nlt.name.is)
> >
> > Where lkOpt is the value that can be None or a Some. Instead of letting
> the
> > functions check None/Some, I check outside the function. But it still
> seems
> > that in theory it could be simplified.
> > chooseTemplate doesn't solve the problem that the alternative NodeSeq has
> > to be transformed to NodeSeq.Empty.
> > P.S. Notice that I'm using my implicit to call bind on the NodeSeq :)
> > P.P.S If you look closely, there's another problem that I had. For some
> > reason the first "name" -> ... was getting ignored, and it only worked in
> > the second bind.
> > Thanks!
> >
> >
> >
> >
> >
> > On Thu, Aug 6, 2009 at 10:49 AM, David Pollak <
> > [email protected]> wrote:
> >
> >> I really need to see the resulting view code that you'd like to see
> >> depending on the conditions.
> >>
> >> On Thu, Aug 6, 2009 at 7:47 AM, Naftoli Gugenheim <[email protected]
> >wrote:
> >>
> >>>
> >>> No, I meant that this pattern of parts of the view being alternatives
> to
> >>> each other repeats, in other words the view has several pairs of
> >>> alternatives.
> >>
> >>
> >> I don't understand why the example doesn't allow for alternatives that
> >> repeat.
> >>
> >>
> >>>
> >>>
> >>> -------------------------------------
> >>> David Pollak<[email protected]> wrote:
> >>>
> >>> On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim <
> [email protected]
> >>> >wrote:
> >>>
> >>> >
> >>> > What's the smartest / most concise way to achieve the following in
> the
> >>> > corresponding view xhtml and snippet code:
> >>> > Parts of the view have to change, depending on whether something is
> >>> set.
> >>> > For example, in the area where you select the client, if the client
> is
> >>> None,
> >>> > then it displays an interface to select a client. If it's set to a
> Some
> >>> then
> >>> > it displays the client's details with a button to unset it. This
> >>> pattern is
> >>> > repeated.
> >>> > My current strategy is to have two elements, req:noClient and
> >>> req:client,
> >>> > which have different xhtml contents. Then in the snippet I bind them
> to
> >>> two
> >>> > NodeSeq functions, one that binds useful contents when the client is
> >>> None
> >>> > and returns NodeSeq.Empty otherwise; and another function that binds
> >>> when
> >>> > it's a Some and returns Empty otherwise. However, it seems to be
> >>> somewhat
> >>> > redundant in theory.
> >>> > So does anyone have a better way of switching view parts?
> >>>
> >>>
> >>> If it's repeated, then <lift:embed /> the part that you need.
> >>>
> >>> <lift:MaybeClient>
> >>> <client:yes><lift:embed
> >>> what="/templates/client_edit.html"/></client:yes>
> >>> <client:no><lift:embed
> >>> what="/templates/client_chooser.html"/><client:no>
> >>> </lift:MaybeClient>
> >>>
> >>>
> >>>
> >>> >
> >>> > Thanks.
> >>> >
> >>> >
> >>> >
> >>> > >
> >>> >
> >>>
> >>>
> >>> --
> >>> Lift, the simply functional web framework http://liftweb.net
> >>> Beginning Scala http://www.apress.com/book/view/1430219890
> >>> Follow me: http://twitter.com/dpp
> >>> Git some: http://github.com/dpp
> >>>
> >>>
> >>>
> >>>
> >>>
> >>
> >>
> >> --
> >> Lift, the simply functional web framework http://liftweb.net
> >> Beginning Scala http://www.apress.com/book/view/1430219890
> >> Follow me: http://twitter.com/dpp
> >> Git some: http://github.com/dpp
> >>
> >>
> >>
> >
> > >
> >
>
>
> --
> Lift, the simply functional web framework http://liftweb.net
> Beginning Scala http://www.apress.com/book/view/1430219890
> Follow me: http://twitter.com/dpp
> Git some: http://github.com/dpp
>
> >
>
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---