Marc,
Sorry... dunno what to tell you. :-(

David

On Thu, Jan 8, 2009 at 3:47 PM, Marc Boschma
<marc+lift...@boschma.cx<marc%2blift...@boschma.cx>
> wrote:

> Very cool indeed, except... I now get:
> [WARNING]
> /Users/marc/src/todo/src/main/scala/com/liftworkshop/snippet/TD.scala:99:
> error: value attr is not a member of object net.liftweb.util.BindHelpers
> [WARNING] val singular = BindHelpers.attr("singular", {s: String =>
> s.toLowerCase match {
> [WARNING]                                            ^
> [WARNING] one error found
>
> I've cleaned out my .m2/repository and I always mvn -U clean install... No
> proxies in place. Usually works a charm.
> Frustrating as hell - I feel for those that actually make a living in the
> Java/Maven world (must make a mental note to not quibble so much on what
> those who do want to get paid :)
>
> Thoughts?
>
> Marc
>
> The full context of the code for those interested (David's todo app
> modified thus):
>
> (The top of the file has import net.liftweb._  and  import util._)
>
>         private def doList(reDraw: () => JsCmd)(html: NodeSeq): NodeSeq = {
>                 val singular = BindHelpers.attr("singular", {s: String =>
> s.toLowerCase match {
>                         case "" => true
>                         case "true" => true
>                         case "t" => true
>                         case "yes" => true
>                         case "y" => true
>                         case _ => false}}, false)
>                 val l = toShow
>
>                 if (singular)
>                         l.flatMap(td =>
>                                 bind("todo", html,
>                                         "check" -> ajaxCheckbox(td.done,
>                                                 v => {td.done(v).save;
> reDraw()}),
>                                         "priority" ->
> ajaxSelect(ToDo.priorityList, Full(td.priority.toString),
>                                                 v =>
> {td.priority(v.toInt).save; reDraw()}),
>                                         "desc" -> desc(td, reDraw)
>                                 ))
>                 else {
>                         val xhtmls = template(html, l.length)
>
>                         l.zip(xhtmls).flatMap(n => { val (td , xhtml) = n
>                                 bind("todo", xhtml,
>                                         "check" -> ajaxCheckbox(td.done,
>                                                 v => {td.done(v).save;
> reDraw()}),
>                                         "priority" ->
> ajaxSelect(ToDo.priorityList, Full(td.priority.toString),
>                                                 v =>
> {td.priority(v.toInt).save; reDraw()}),
>                                         "desc" -> desc(td, reDraw)
>                                 )})
>                 }
>         }
>
>         private def template(html: NodeSeq, i: Int): List[NodeSeq] =
> expand(nodeSeq2List(html), i)
>
>         private def nodeSeq2List(html: NodeSeq): List[NodeSeq] = {
>                 val es = html.elements.toList.filter(_ match {
>                         case Text(s) if (s.trim.length == 0) => false //
> remove whitespace text
>                         case _ => true
>                         })
>                 es match {
>                         // it was just white space, return it
>                         case Nil => List(html)
>
>                         // are all the nodes the same (prefix == lift)?
>                         // this allows the use of different snippets as the
> different templates...
>                         case x :: xs if (x.prefix == "lift" &&
>                                 xs.foldLeft(true)( (t, n) => (t && n.prefix
> == x.prefix) )) => es
>
>                         // are all the nodes the same (prefix, label)?
>                         case x :: xs => {
>                                 if (xs.foldLeft(true)( (t, n) => (t &&
> n.prefix == x.prefix && n.label == x.label) ))
>                                         es
>                                 else List(html) // nope, return origional
> sequence...
>                         }
>                 }
>         }
>
>         // duplicate a list until it is at least as long as *i*
>         private def expand(xhtmls: List[NodeSeq], i: Int): List[NodeSeq] =
>                 if (i > 0)
>                         expand(xhtmls ::: xhtmls, i - xhtmls.length)
>                 else
>                         xhtmls
>
>
> On 09/01/2009, at 5:08 AM, David Pollak wrote:
>
>
>
> On Thu, Jan 8, 2009 at 9:54 AM, Marius <marius.dan...@gmail.com> wrote:
>
>>
>> Ok, I just committed the updates. Now both BindHelpers.attr and S.attr
>> implement AttrHelpers trait where we have a bunch of overloaded apply,
>>
>> I would have liked to use Option[NodeSeq] for S.attr as well but this
>> would be a breaking change and breaking changes are frozen now. So
>> S.attr("someparam") still returns a Box[String]. However I added 2
>> helper function ~ that would return Option[NodeSeq], so you can call
>> S.attr ~("someparam") and get back an Option[NodeSeq].
>>
>> I know we could have used implicits to convert from Box[String] to
>> Option[NodeSeq] but I feel that this would be an abuse of implicits as
>> the use of implicits IMHO should be motivated byt strong design
>> rationales and I think this is the case.
>>
>> Thoughts?
>
>
> Very cool!
>
>
>>
>>
>> Br's,
>> Marius
>>
>> On Jan 7, 7:40 pm, Marius <marius.dan...@gmail.com> wrote:
>> > I'll look into it.
>> >
>> > On Jan 7, 7:38 pm, "David Pollak" <feeder.of.the.be...@gmail.com>
>> > wrote:
>> >
>> > > Marc,
>> >
>> > > Good suggestion.  Marius -- do you want to do this... maybe even turn
>> the
>> > > pattern into a trait that we can apply over and over?
>> >
>> > > Thanks,
>> >
>> > > David
>> >
>> > > On Tue, Jan 6, 2009 at 9:57 PM, Marc Boschma
>> > > <marc+lift...@boschma.cx <marc%2blift...@boschma.cx><
>> marc%2blift...@boschma.cx <marc%252blift...@boschma.cx>>
>> >
>> > > > wrote:
>> > > > Cool code! Works nicely...
>> > > > Would it make sense to also add something similar to this from
>> S.attr ?
>> >
>> > > >   def apply[T](what: String, f: String => T, default: => T): T
>> > > > = apply(what).map(f) openOr default
>> >
>> > > > ie maybe:
>> >
>> > > >   def apply[T](prefix: String, key: String, f: String => T):
>> Option[T]
>> > > > = apply(prefix, key).map(f)
>> > > >   def apply[T](key: String, f: String => T): Option[T] =
>> apply(key).map(f)
>> >
>> > > > to BindHelpers.attr ?
>> >
>> > > > Thinking about it should the applys of the two attr objects be
>> aligned
>> > > > (Option verses Box, etc) ? It would make the crafting of snippets
>> and bind
>> > > > functions in terms of access to attributes the same, dropping a
>> potential
>> > > > barrier to learning lift...
>> >
>> > > > ie Maybe BindHelpers.attr should have applys with the following
>> > > > signatures...
>> >
>> > > >     def apply(key: String): Box[String]
>> > > >     def apply(prefix: String,  key: String): Box[String]
>> >
>> > > >     def apply(key: String, default: => String): String
>> > > >     def apply(prefix: String, key: String, default: => String):
>> String
>> >
>> > > >     def apply[T](key: String, f: String => T, default: => T): T
>> > > >     def apply[T](prefix: String, key: String, f: String => T,
>> default: =>
>> > > > T): T
>> >
>> > > > Lastly, and maybe I am missing something here, but I take it for a
>> snippet
>> > > > a prefixed attribute isn't accessible via S.attr ???
>> >
>> > > > Regards,
>> >
>> > > > Marc
>> >
>> > > > On 07/01/2009, at 6:54 AM, David Pollak wrote:
>> >
>> > > > On Tue, Jan 6, 2009 at 11:16 AM, Marius <marius.dan...@gmail.com>
>> wrote:
>> >
>> > > >> Ok ... i just committed some changes:
>> >
>> > > >> 1. Renamed curAttr to attr
>> > > >> 2. The BindHelpers vals are now private but we expose two functions
>> > > >> currentNode and bindNodes
>> >
>> > > > Cool beans!
>> >
>> > > >> Br's,
>> > > >> Marius
>> >
>> > > >> On Jan 6, 8:37 pm, "David Pollak" <feeder.of.the.be...@gmail.com>
>> > > >> wrote:
>> > > >> > On Tue, Jan 6, 2009 at 10:28 AM, Marius <marius.dan...@gmail.com
>> >
>> > > >> wrote:
>> >
>> > > >> > > On Jan 6, 7:15 pm, "David Pollak" <
>> feeder.of.the.be...@gmail.com>
>> > > >> > > wrote:
>> > > >> > > > I also added
>> > > >> > > > BindHelpers.attr("tag"): Option[NodeSeq]
>> > > >> > > > so you can do something like:
>> >
>> > > >> > > > <span class={BindHelpers.attr("class")>...</span>
>> >
>> > > >> > > > and:
>> > > >> > > > BindHelpers.attr("prefix", "tag")
>> >
>> > > >> > > I think it is committed to curAttr which personally I'm not a
>> fan ...
>> > > >> > > Doyou mind if I change it to attr or nodeAttr ?
>> >
>> > > >> > Go for it.
>> >
>> > > >> > > > Thanks,
>> >
>> > > >> > > > David
>> >
>> > > >> > > > On Tue, Jan 6, 2009 at 9:13 AM, Marius <
>> marius.dan...@gmail.com>
>> > > >> wrote:
>> >
>> > > >> > > > > Very cool Dave !
>> >
>> > > >> > > > > thx,
>> > > >> > > > > Marius
>> >
>> > > >> > > > > On Jan 6, 4:36 pm, "David Pollak" <
>> feeder.of.the.be...@gmail.com>
>> > > >> > > > > wrote:
>> > > >> > > > > > Folks,
>> >
>> > > >> > > > > > I'm about to commit up a non-breaking solution.
>> >
>> > > >> > > > > > In bind, you can call:
>> > > >> > > > > > BindHelpers.bindNodes.value: List[NodeSeq]
>> > > >> > > > > > BindHelpers.currentNode.value: Elem
>> >
>> > > >> > > > > > bindNodes is a list of the nodes that were passed into
>> bind with
>> > > >> the
>> > > >> > > more
>> > > >> > > > > > current node at the head of the list.  If you're doing
>> > > >> hierarchical
>> > > >> > > > > binding,
>> > > >> > > > > > you can see all the nodes that were passed into bind this
>> was.
>> >
>> > > >> > > > > > currentNode is available to the BindParam and it contains
>> the
>> > > >> parent
>> > > >> > > Elem
>> > > >> > > > > to
>> > > >> > > > > > the NodeSeq that was passed into your BindParam.  You can
>> > > >> inspect
>> > > >> > > > > attributes
>> > > >> > > > > > to your heart's content.
>> >
>> > > >> > > > > > Give it an hour or two for these changes to make their
>> way
>> > > >> through
>> > > >> > > > > Hudson.
>> >
>> > > >> > > > > > Thanks,
>> >
>> > > >> > > > > > David
>> >
>> > > >> > > > > > On Tue, Jan 6, 2009 at 4:50 AM, Marc Boschma
>> > > >> > > > > > <marc+lift...@boschma.cx <marc%2blift...@boschma.cx> <
>> marc%2blift...@boschma.cx <marc%252blift...@boschma.cx>> <
>> > > >> marc%2blift...@boschma.cx <marc%252blift...@boschma.cx> <
>> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx>>> <
>> > > >> > > marc%2blift...@boschma.cx <marc%252blift...@boschma.cx> <
>> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx>> <
>> > > >> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx> <
>> marc%25252blift...@boschma.cx <marc%2525252blift...@boschma.cx>>>><
>> > > >> > > > > marc%2blift...@boschma.cx <marc%252blift...@boschma.cx> <
>> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx>> <
>> > > >> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx> <
>> marc%25252blift...@boschma.cx <marc%2525252blift...@boschma.cx>>> <
>> > > >> > > marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx> <
>> marc%25252blift...@boschma.cx <marc%2525252blift...@boschma.cx>> <
>> > > >> marc%25252blift...@boschma.cx <marc%2525252blift...@boschma.cx> <
>> marc%2525252blift...@boschma.cx <marc%252525252blift...@boschma.cx>>>>>
>> >
>> > > >> > > > > > > wrote:
>> >
>> > > >> > > > > > > I've just had a thought as to how to make it not a
>> breaking
>> > > >> change.
>> >
>> > > >> > > > > > > Leave your change "calcValue(s.child) I just call
>> > > >> calcValue(s)"
>> >
>> > > >> > > > > > > change:
>> > > >> > > > > > >   case class FuncBindParam(name: String, value: NodeSeq
>> =>
>> > > >> NodeSeq)
>> > > >> > > > > > > extends Tuple2(name, value) with BindParam {
>> > > >> > > > > > >     def calcValue(in: NodeSeq): NodeSeq = value(in)
>> > > >> > > > > > >   }
>> >
>> > > >> > > > > > > to:
>> > > >> > > > > > >   case class FuncBindParam(name: String, value: NodeSeq
>> =>
>> > > >> NodeSeq)
>> > > >> > > > > > > extends Tuple2(name, value) with BindParam {
>> > > >> > > > > > >     def calcValue(in: NodeSeq): NodeSeq =
>> value(in.child)
>> > > >> > > > > > >   }
>> >
>> > > >> > > > > > > That should prevent old code breaking... which would be
>> a good
>> > > >> > > > > > > thing(tm) given the amount of code that uses bind(...)
>> >
>> > > >> > > > > > > then create something like:
>> >
>> > > >> > > > > > >   case class FuncMetaDataBindParam(name: String, value:
>> > > >> (MetaData,
>> > > >> > > > > > > NodeSeq) => NodeSeq) extends Tuple2(name, value) with
>> > > >> BindParam {
>> > > >> > > > > > >     def calcValue(in: NodeSeq): NodeSeq =
>> value(in.attributes,
>> > > >> > > > > > > in.child)
>> > > >> > > > > > >   }
>> >
>> > > >> > > > > > > along with adding to class SuperArrowAssoc...
>> > > >> > > > > > >   def ->(in: (MetaData, NodeSeq) => NodeSeq) =
>> > > >> > > > > > > FuncMetaDataBindParam(name, in)
>> >
>> > > >> > > > > > > That would be fairly clean...
>> >
>> > > >> > > > > > > -----
>> >
>> > > >> > > > > > > Maybe for those that actually want the full node add:
>> >
>> > > >> > > > > > >   case class FuncBoxBindParam(name: String, value:
>> > > >> Box(NodeSeq) =>
>> > > >> > > > > > > NodeSeq) extends Tuple2(name, value) with BindParam {
>> > > >> > > > > > >     def calcValue(in: NodeSeq): NodeSeq =
>> value(Full(in))
>> > > >> > > > > > >   }
>> >
>> > > >> > > > > > > and you could go nuts and:
>> >
>> > > >> > > > > > >   case class FuncPrefixAndLabelBindParam(name: String,
>> value:
>> > > >> > > > > > > (String, String, NodeSeq) => NodeSeq) extends
>> Tuple2(name,
>> > > >> value)
>> > > >> > > with
>> > > >> > > > > > > BindParam {
>> > > >> > > > > > >     def calcValue(in: NodeSeq): NodeSeq =
>> value(in.prefix,
>> > > >> > > in.label,
>> > > >> > > > > > > in.child)
>> > > >> > > > > > >   }
>> >
>> > > >> > > > > > > etc...
>> >
>> > > >> > > > > > > On 06/01/2009, at 10:51 PM, Marc Boschma wrote:
>> >
>> > > >> > > > > > > > (you can tel I'm sleeping well :/ - too hot)
>> >
>> > > >> > > > > > > > The toList function is one of David's (todo example
>> app). I
>> > > >> do
>> > > >> > > love
>> > > >> > > > > > > > the ability to curry :)
>> >
>> > > >> > > > > > > > Marc
>> > > >> > > > > > > > On 06/01/2009, at 9:51 PM, Marius wrote:
>> >
>> > > >> > > > > > > >> On Jan 6, 12:47 pm, Marc Boschma <
>> marc+lift...@boschma.cx <marc%2blift...@boschma.cx><
>> marc%2blift...@boschma.cx <marc%252blift...@boschma.cx>>
>> > > >> <marc%2blift...@boschma.cx <marc%252blift...@boschma.cx> <
>> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx>>>
>> > > >> > > <marc%2blift...@boschma.cx <marc%252blift...@boschma.cx> <
>> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx>> <
>> > > >> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx> <
>> marc%25252blift...@boschma.cx <marc%2525252blift...@boschma.cx>>>>
>> > > >> > > > > <marc%2blift...@boschma.cx <marc%252blift...@boschma.cx> <
>> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx>> <
>> > > >> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx> <
>> marc%25252blift...@boschma.cx <marc%2525252blift...@boschma.cx>>> <
>> > > >> > > marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx> <
>> marc%25252blift...@boschma.cx <marc%2525252blift...@boschma.cx>> <
>> > > >> marc%25252blift...@boschma.cx <marc%2525252blift...@boschma.cx> <
>> marc%2525252blift...@boschma.cx <marc%252525252blift...@boschma.cx>>>>>>
>> > > >> > > > > > > wrote:
>> > > >> > > > > > > >>> A quick just before going to bed reaction is that
>> your
>> > > >> change
>> > > >> > > would
>> > > >> > > > > > > >>> solve the issue.
>> >
>> > > >> > > > > > > >> Yeah it would ... (I mean it worked fine in my
>> tests)
>> >
>> > > >> > > > > > > >>> It is interesting you focused on the "exclude" and
>> not the
>> > > >> > > > > > > >>> "list" (which is what I have been playing with). I
>> > > >> actually
>> > > >> > > missed
>> > > >> > > > > > > >>> it
>> > > >> > > > > > > >>> was a similar case...
>> >
>> > > >> > > > > > > >> I just picked it randomly :) ... I've seen that
>> you're
>> > > >> using a
>> > > >> > > > > > > >> partially applied function doList ... (which I
>> assume it is
>> > > >> a
>> > > >> > > > > curried
>> > > >> > > > > > > >> function):)
>> >
>> > > >> > > > > > > >>> Regards,
>> >
>> > > >> > > > > > > >>> Marc
>> >
>> > > >> > > > > > > >>> On 06/01/2009, at 9:24 PM, Marius wrote:
>> >
>> > > >> > > > > > > >>>> I just did a minor modification to the lift code
>> so the
>> > > >> actual
>> > > >> > > > > > > >>>> node it
>> > > >> > > > > > > >>>> is passed to the BindParam and not its child. Now
>> having:
>> >
>> > > >> > > > > > > >>>> bind("todo", html,
>> > > >> > > > > > > >>>>                    "exclude" ->  {node:NodeSeq
>> > > >> =>ajaxCheckbox
>> > > >> > > > > > > >>>> (QueryNotDone, v => {QueryNotDone(v); reDraw})}
>> > > >> > > > > > > >>>> ... )
>> >
>> > > >> > > > > > > >>>> and the markup <todo:exclude param="Dumb"/>
>> >
>> > > >> > > > > > > >>>> The node parameter to the anonymous function will
>> be the
>> > > >> > > > > > > >>>> <todo:exclude> node and not its children. So now
>> you can
>> > > >> > > access
>> > > >> > > > > the
>> > > >> > > > > > > >>>> "param" attribute from node. The change was in
>> in_bind
>> > > >> > > function so
>> > > >> > > > > > > >>>> instead of calling calcValue(s.child) I just call
>> > > >> calcValue(s)
>> >
>> > > >> > > > > > > >>>> Looking at the existent BindParams this change
>> does not
>> >
>> > ...
>> >
>> > read more ยป
>>
>>
>
>
> --
> Lift, the simply functional web framework http://liftweb.net
> Collaborative Task Management http://much4.us
> Follow me: http://twitter.com/dpp
> Git some: http://github.com/dpp
>
>
>
>
>
> >
>


-- 
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to