[Lift] Re: Alternate part of view
Great. So what kind of syntax do you want to see? What do you think of my bindSwitch syntax? - georgegeo...@mattandgeorge.com 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 naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:29 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: 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 bsome text/b choose:one/choose:one choose:two/choose:two some more stuff /lift:foo Is exactly the same as: bsome 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:18 AM, Naftoli Gugenheim naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / 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 { ... }
[Lift] Re: Alternate part of view
I will have a think about it and get back to you. On Aug 11, 1:38 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Great. So what kind of syntax do you want to see? What do you think of my bindSwitch syntax? - georgegeo...@mattandgeorge.com 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 naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:29 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: 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 bsome text/b choose:one/choose:one choose:two/choose:two some more stuff /lift:foo Is exactly the same as: bsome 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:18 AM, Naftoli Gugenheim naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / 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,
[Lift] Re: Alternate part of view
On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / 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 feeder.of.the.be...@gmail.com 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 naftoli...@gmail.comwrote: 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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:yeslift:embed what=/templates/client_edit.html//client:yes client:nolift: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:
[Lift] Re: Alternate part of view
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? Thanks. - David Pollakfeeder.of.the.be...@gmail.com wrote: On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / 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 feeder.of.the.be...@gmail.com 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 naftoli...@gmail.comwrote: 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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:yeslift:embed what=/templates/client_edit.html//client:yes client:nolift:embed what=/templates/client_chooser.html/client:no /lift:MaybeClient Thanks. -- Lift, the simply functional web framework http://liftweb.net Beginning Scala
[Lift] Re: Alternate part of view
On Mon, Aug 10, 2009 at 11:18 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / 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 feeder.of.the.be...@gmail.com 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 naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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
[Lift] Re: Alternate part of view
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)? Thanks. - David Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:18 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / 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 feeder.of.the.be...@gmail.com 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 naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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
[Lift] Re: Alternate part of view
On Mon, Aug 10, 2009 at 11:29 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: 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 bsome text/b choose:one/choose:one choose:two/choose:two some more stuff /lift:foo Is exactly the same as: bsome 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:18 AM, Naftoli Gugenheim naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / 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 feeder.of.the.be...@gmail.com 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 naftoli...@gmail.com wrote: No, I meant that this pattern of parts of the view
[Lift] Re: Alternate part of view
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 = 1 - bind(client, ns, ...) }}) Also using my implicit several such invocations could easily be chained. - David Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:18 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / 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 feeder.of.the.be...@gmail.com 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 naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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
[Lift] Re: Alternate part of view
I sent my last message before I saw your last message, sorry. You made a very valid point that I didn't think of--to split the snippet into a number of snippets. However that doesn't help everywhere. For example: (breaking it into 2 messages) - David Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:29 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: 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 bsome text/b choose:one/choose:one choose:two/choose:two some more stuff /lift:foo Is exactly the same as: bsome 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:18 AM, Naftoli Gugenheim naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / 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,
[Lift] Re: Alternate part of view
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 Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:29 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: 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 bsome text/b choose:one/choose:one choose:two/choose:two some more stuff /lift:foo Is exactly the same as: bsome 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Mon, Aug 10, 2009 at 11:18 AM, Naftoli Gugenheim naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / 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:
[Lift] Re: Alternate part of view
Maybe I should write a bindSwitch method? It could take a list of strings out of which one should be bound and the others should be replaced with NodeSeq.Empty; and a function that returns a (Int, NodeSeq) indicacating which one to use and what to replace it with. Would people be interested in it? - David Pollakfeeder.of.the.be...@gmail.com 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 naftoli...@gmail.comwrote: 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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:yeslift:embed what=/templates/client_edit.html//client:yes client:nolift: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 --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@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: Alternate part of view
I think you're approaching the issue backwards... I'd figure out if you have a client first and dispatch based on that... I'll work on some code late morning tomorrow (Monday) for you. On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / client:details / /req:client hr / 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 feeder.of.the.be...@gmail.com 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 naftoli...@gmail.comwrote: 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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:yeslift:embed what=/templates/client_edit.html//client:yes client:nolift: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 --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups
[Lift] Re: Alternate part of view
What do you mean by dispatch? This is all taking place inside one screen, just parts of the screen each change between one set of xhtml and another. It would be overkill to split the view into separate files -- the html file has about 60 lines (not counting some that are commented out :) ). Another use case might be a tabbed dialog that's not so complex that it's worth it to put each page in a separate template, or a button that changes between a simpler set of configuration controls and a more advanced set. I prefer to use templates etc. for something that's used in more than one place. Thanks. - David Pollakfeeder.of.the.be...@gmail.com wrote: I think you're approaching the issue backwards... I'd figure out if you have a client first and dispatch based on that... I'll work on some code late morning tomorrow (Monday) for you. On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / client:details / /req:client hr / 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 feeder.of.the.be...@gmail.com 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 naftoli...@gmail.comwrote: 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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:yeslift:embed what=/templates/client_edit.html//client:yes client:nolift:embed what=/templates/client_chooser.html/client:no /lift:MaybeClient Thanks. -- Lift, the simply
[Lift] Re: Alternate part of view
On Sun, Aug 9, 2009 at 6:44 PM, Naftoli Gugenheim naftoli...@gmail.comwrote: What do you mean by dispatch? This is all taking place inside one screen, just parts of the screen each change between one set of xhtml and another. It would be overkill to split the view into separate files -- the html file has about 60 lines (not counting some that are commented out :) ). Another use case might be a tabbed dialog that's not so complex that it's worth it to put each page in a separate template, or a button that changes between a simpler set of configuration controls and a more advanced set. I prefer to use templates etc. for something that's used in more than one place. Within the method, dispatch to the has client and has no client handler based on the existence of the client... once again, I'll get some code to you tomorrow. Thanks. - David Pollakfeeder.of.the.be...@gmail.com wrote: I think you're approaching the issue backwards... I'd figure out if you have a client first and dispatch based on that... I'll work on some code late morning tomorrow (Monday) for you. On Thu, Aug 6, 2009 at 9:28 AM, Naftoli Gugenheim naftoli...@gmail.com wrote: Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / client:details / /req:client hr / 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 feeder.of.the.be...@gmail.com 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 naftoli...@gmail.com 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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
[Lift] Re: Alternate part of view
On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.comwrote: 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:yeslift:embed what=/templates/client_edit.html//client:yes client:nolift: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 --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@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: Alternate part of view
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. - David Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.comwrote: 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:yeslift:embed what=/templates/client_edit.html//client:yes client:nolift: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 --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@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: Alternate part of view
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 naftoli...@gmail.comwrote: 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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:yeslift:embed what=/templates/client_edit.html//client:yes client:nolift: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 --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@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: Alternate part of view
Here's some view xhtml: req:noClient label for=clientqueryClient /label client:query id=clientquery size=5/ client:set / /req:noClient req:client Client client:unset / client:editclient:name //client:editbr / client:details / /req:client hr / 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 feeder.of.the.be...@gmail.com 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 naftoli...@gmail.comwrote: 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 Pollakfeeder.of.the.be...@gmail.com wrote: On Wed, Aug 5, 2009 at 8:44 PM, Naftoli Gugenheim naftoli...@gmail.com 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:yeslift:embed what=/templates/client_edit.html//client:yes client:nolift: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 --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@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: Alternate part of view
Please see chooseTemplate from Helpers._ (It's actually defined in BindHelpers) For examples see: \sites\example\src\main\webapp\guess.html \sites\example\src\main\scala\net\liftweb\example\snippet \CountGame.scala .. see if that helps you case. Br's, Marius On Aug 6, 6:44 am, Naftoli Gugenheim naftoli...@gmail.com 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? Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@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: Alternate part of view
It doesn't, because it has to replace its contents bound, and the other view part has to be replaced with nothing, so it's less concise than FuncBindParams. - marius d.marius.dan...@gmail.com wrote: Please see chooseTemplate from Helpers._ (It's actually defined in BindHelpers) For examples see: \sites\example\src\main\webapp\guess.html \sites\example\src\main\scala\net\liftweb\example\snippet \CountGame.scala .. see if that helps you case. Br's, Marius On Aug 6, 6:44 am, Naftoli Gugenheim naftoli...@gmail.com 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? Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@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 -~--~~~~--~~--~--~---