Great. So what kind of syntax do you want to see? What do you think of my bindSwitch syntax?
------------------------------------- george<[email protected]> wrote: I've been following this thread with interest because I have a very similar use case. I also want to show different form fields depending on what the user previously entered. My solution was to dynamically create the bind params and bind Empty to anything irrelevant. I thought this felt a bit awkward, but I couldn't see a better alternative being new to both Lift and Scala. So I am also interested in finding a better way to do this. On Aug 10, 8:05 pm, Naftoli Gugenheim <[email protected]> wrote: > For example, I have requests. Every request is of a particular nature. Every > nature specifies a set of location "types"--for example a Transportation > request has a "From" and a "To"--and each type has a set of allowed location > "kinds"--for example, transportation can be from/to a street address, > hospital, etc., while a Hospital Visitation has one location type > ("Location") which only has one location kind (hospital). > Now, when you are entering a request, once you select your nature, you are > shown a list of location types, each of which you have to choose the location > kind for. When you select the location kind of a location type, you then see > the fields for that location kind. For example a street address has text > fields while a hospital location has two dropdowns and a text field. > The point being, that each location type is a switch, depending on whether a > location kind has been selected for it. But they are inside an xml node that > is reused for each location type, which has to be inside the snippet. But > there is static formatting there. > Nested snippets isn't a great solution here because the inner xml needs > access to the location being iterated in the outer snippet, and class > variables are less preferable than direct scope access. > Thanks! > > ------------------------------------- > > David Pollak<[email protected]> wrote: > > On Mon, Aug 10, 2009 at 11:29 AM, Naftoli Gugenheim > <[email protected]>wrote: > > > > > By context I mean where it is in the xml. > > For example, br's between the "switch" and everything else. > > In other words, your code implements a "switch." But where are you putting > > it back in the view? chooseTemplate etc. extract data "out of context" as > > oppo'sed to bind which is "in place." And if indeed you are calling it from > > within bind then why is it better than a NodeSeq function (FuncBindParam)? > > Put the static content outside the snippet invocation: > > <lift:foo> <b>some text</b> > <choose:one>....</choose:one> > <choose:two>....</choose:two> > some more stuff > </lift:foo> > > Is exactly the same as: > > <b>some text</b> > <lift:foo> <choose:one>....</choose:one> > <choose:two>....</choose:two> > </lift:foo> > some more stuff > > The snippet operates on the content that must be modified and the static > text is outside the snippet invocation. > > > > > > > Thanks. > > > ------------------------------------- > > 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 frameworkhttp://liftweb.net > > > >>> Beginning Scalahttp://www.apress.com/book/view/1430219890 > > > >>> Follow me:http://twitter.com/dpp > > > >>> Git some:http://github.com/dpp > > > > >> -- > > > >> Lift, the simply functional web frameworkhttp://liftweb.net > > > >> Beginning Scalahttp://www.apress.com/book/view/1430219890 > > > >> Follow me:http://twitter.com/dpp > > > >> Git some:http://github.com/dpp > > > > -- > > > Lift, the simply functional web frameworkhttp://liftweb.net... > > read more » --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
