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>
> 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>>
> 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 seem to
> >>>> cause
> >>>> side effects since the calcValue 'in' parameter is used only for
> >>>> FuncXXXBindParam-s. The impact is that the user's function would
> >>>> now
> >>>> get the actual node (from which now he can extract attributes) and
> >>>> not
> >>>> the child nodes. But child nodes from the actual node are trivial
> >>>> to
> >>>> obtain.
> >>>
> >>>> I did not commit this change as I'd like to see other opinions to
> >>>> see
> >>>> if there is something that I missed somehow. If we get general
> >>>> consensus of this change I can commit it right away and announce
> >>>> it as
> >>>> a "breaking change".
> >>>
> >>>> Thoughts?
> >>>
> >>>> Br's,
> >>>> Marius
> >>>
> >>>> On Jan 6, 12:02 pm, Marius <marius.dan...@gmail.com> wrote:
> >>>>> A nice alternative would have been :
> >>>
> >>>>> bind("todo", html,
> >>>>>                     "exclude" ->  {node:NodeSeq =>ajaxCheckbox
> >>>>> (QueryNotDone, v => {QueryNotDone(v); reDraw})}
> >>>>>  ... )
> >>>
> >>>>> But here the node impersonates the childNodes not the original
> >>>>> node.
> >>>>> So you still can not access the param attribute below
> >>>
> >>>>> <todo:exclude param="Dumb"/>
> >>>
> >>>>> but you can do it like:
> >>>
> >>>>> <todo:exclude ><meta param="dumb"/></todo:exclude>
> >>>
> >>>>> and you have full access to the meta node as it is a child of
> >>>>> todo:exclude. Hence you can pass state.
> >>>
> >>>>> I know, it is not ideal but should be workable until snippet
> >>>>> child-
> >>>>> node attributes are exposed in one way or another.
> >>>
> >>>>> Br's,
> >>>>> Marius
> >>>
> >>>>> Marc Boschma wrote:
> >>>>>> I have been playing with the ToDo example application and having
> >>>>>> fun
> >>>>>> in manipulating XML.
> >>>
> >>>>>> With the <todo:list/> node I thought it would be good if the
> >>>>>> XHTML
> >>>>>> designer could pass in some guidance to the doList(...) method
> >>>>>> used in
> >>>>>> bind(..). ie. <todo:list singular="true">...</todo:list>
> >>>
> >>>>>> Looking over the bind code I noticed that the attributes are not
> >>>>>> accessible without ending up changing the calcValue method's
> >>>>>> signature. I did initially try to knock up a
> >>>
> >>>>>>   case class FuncWithAttrBindParam(name: String, value: (NodeSeq,
> >>>>>> MetaData) => NodeSeq) extends Tuple2(name, value) with BindParam
> >>>
> >>>>>> and a corresponding
> >>>
> >>>>>>   case Some(ns : FuncWithAttrBindParam) =>
> >>>
> >>>>>> in in_bind(...), but it all looks like a huge kludge.
> >>>
> >>>>>> It strikes me as a little deficient to be able to utilise
> >>>>>> attributes
> >>>>>> within the context of a snippet and yet not within a bind. I know
> >>>>>> bind
> >>>>>> is quite embedded in lift now, but I think that this difference
> >>>>>> might
> >>>>>> prove a little frustrating. I know one solution is to just
> >>>>>> create a
> >>>>>> bind("todo", html,
> >>>>>>                                 "exclude" ->
> >>>>>> ajaxCheckbox(QueryNotDone, v => {QueryNotDone(v); reDraw}),
> >>>>>>                                 "list" -> doList(reDraw, false)
> >>>>>> _,
> >>>>>>                           "list_singular" -> doList(reDraw, true)
> >>>>>> _)
> >>>
> >>>>>> But I think from the XHtml designer's perspective that is counter
> >>>>>> intuitive...
> >>>
> >>>>>> Thoughts?
> >>>
> >>>>>> ------
> >>>
> >>>>>> It should be noted that this is different to the case class
> >>>>>> FuncAttrBindParam(name: String, value: NodeSeq => NodeSeq,
> >>>>>> newAttr:
> >>>>>> String) extends BindParam with BindWithAttr. Which interesting
> >>>>>> enough
> >>>>>> has no corresponding SuperArrowAssoc -> method match. Maybe
> >>>
> >>>>>>   def ->(t: Tuple2[String, NodeSeq]) = AttrBindParam(name, t._2,
> >>>>>> t._1)
> >>>>>>   def ->(t: Tuple2[String, NodeSeq => NodeSeq]) =
> >>>>>> FuncAttrBindParam(name, t._2, t._1)
> >>>
> >>>>>> And maybe even...
> >>>
> >>>>>>   def ->[T](t: Tuple2[String, T]) = FuncAttrBindParam(name, (name
> >>>>>> ->
> >>>>>> t._2).calcValue _, t._1)
> >>>
> >>>>>> or
> >>>
> >>>>>>   def ->[T](t: Tuple2[String, T]) = FuncAttrBindParam(name, (t._1
> >>>>>> ->
> >>>>>> t._2).calcValue _, t._1)
> >>>
> >>>>>> I'm not sure which is better on the last two... Just a thought.
> >>>
> >>>>>> Marc
> >>>
> >
> >
> > >
>
>
> >
>


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