Binding and CSS Selectors input

179 views
Skip to first unread message

Pawel R

unread,
May 17, 2011, 7:35:33 PM5/17/11
to Lift Googlegroup
Hi,

how can I get the input NodeSeq while CSS Selector Transformation?
When you use binding (def bind(xhtml: NodeSeq): NodeSeq = {...}) you can use xhtml argument. Using CSS Selector Transformation there are no arguments.

Thanks,
Etam.

Diego Medina

unread,
May 17, 2011, 8:49:58 PM5/17/11
to lif...@googlegroups.com

You can add the input field explicit.

Like here https://github.com/fmpwizard/lift-conditional-drop-down-menus/blob/master/src/main/scala/code/snippet/PlaceCometOnPage.scala

Sent from my cell
Diego Medina

> --
> You received this message because you are subscribed to the Google Groups "Lift" group.
> To post to this group, send email to lif...@googlegroups.com.
> To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
>

Etam

unread,
May 18, 2011, 1:14:12 AM5/18/11
to lif...@googlegroups.com
But there you have binding:
def render(xhtml: NodeSeq): NodeSeq = {...},
not a CssSel method like:
def render: CssSel = "*" #> "...".

Diego Medina

unread,
May 18, 2011, 1:43:23 AM5/18/11
to lif...@googlegroups.com
Ah, sorry about that, I have been staring at this one project for way too long.

I tried a few things and I could not tell how to do what you are
looking for, hopefully somebody will reply to this thread with the
correct answer.

regards

Diego

> --
> You received this message because you are subscribed to the Google Groups
> "Lift" group.
> To post to this group, send email to lif...@googlegroups.com.
> To unsubscribe from this group, send email to
> liftweb+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/liftweb?hl=en.
>

--
Diego Medina
Web Developer
http://www.fmpwizard.com

Naftoli Gugenheim

unread,
May 18, 2011, 2:26:47 AM5/18/11
to lif...@googlegroups.com
Just pass the selectors a NodeSeq=>NodeSeq function.
def render = "*" #> {ns: NodeSeq =>
  "..."
}

Unfortunately it's not as nice if you want to nest selectors:
def render = "*" #> {ns: NodeSeq =>
  val ret = "button" #> SHtml.onSubmit(...)
  ret(ns)
}

Of course you could write that in other ways, like
def render = "*" #> {ns: NodeSeq =>
  (
    "button" #> SHtml.onSubmit(...)
  ) apply ns
}

And you can use CSS selectors inside the old method signature:

def render(xhtml: NodeSeq): NodeSeq = {
  "button" #> SHtml.onSubmit(...) apply bind("pre",xhtml,"other" -> "other")
}

The bottom line is that css selectors can take a NodeSeq=>NodeSeq, and they are one themselves.
And functions can be applied with parenthesis or by calling their apply method.


On Wed, May 18, 2011 at 1:14 AM, Etam <odwr...@gmail.com> wrote:

--

Pawel R

unread,
May 18, 2011, 4:05:35 AM5/18/11
to lif...@googlegroups.com
What I am trying to do is to take width and height parameters from <img /> tag (instead of S.attr) and pass them as Image.WIDTH_PARAM and Image.HEIGHT_PARAM in my Image model:

def cssSel = {
var width = S.attr("image_width").dmap(80)(_.toInt)
var height = S.attr("image_height").dmap(60)(_.toInt)
"img [src]" #> Helpers.appendParams(
Image.prefix + ResizeMethod.Fit.toString,
(Image.ID_PARAM -> "%d".format(id.is)) ::
(Image.WIDTH_PARAM -> "%d".format(width)) ::
(Image.HEIGHT_PARAM -> "%d".format(height)) :: Nil) &
"img [width]" #> width &
"img [height]" #> height
}

What is the best solution?

Kristian Nordal

unread,
May 18, 2011, 1:58:27 AM5/18/11
to lif...@googlegroups.com

Hi.

CssSel is a function from NodeSeq to NodeSeq, and the right hand side
of the expression can also be a NodeSeq => NodeSeq. You can do
something like:
"#foo" #> ((n:NodeSeq) => ...)

--
Cheers,
Kristian

Etam

unread,
May 18, 2011, 9:37:58 AM5/18/11
to lif...@googlegroups.com
Thanks Kristian, but it does not work.

Etam

unread,
May 18, 2011, 10:59:29 AM5/18/11
to lif...@googlegroups.com
If "CssSel is a function from NodeSeq to NodeSeq", how can you convert (in: NodeSeq) => NodeSeq to CssSel?

Etam

unread,
May 18, 2011, 11:13:06 AM5/18/11
to lif...@googlegroups.com
I have found the solution (isn't it too complex?):

def cssSelBind(in: NodeSeq): NodeSeq = {
val width = (in \\ "@width" text).toInt
val height = (in \\ "@height" text).toInt
val f = "img [src]" #> Helpers.appendParams(
Image.prefix + ResizeMethod.Fit.toString,
(Image.ID_PARAM -> "%d".format(id.is)) ::
(Image.WIDTH_PARAM -> "%d".format(width)) ::
(Image.HEIGHT_PARAM -> "%d".format(height)) :: Nil) &
"img [width]" #> width &
"img [height]" #> height
f(in)
}

def cssSel: CssSel = "*" #> {in => cssSelBind(in)}

Thanks for help.

Naftoli Gugenheim

unread,
May 18, 2011, 2:36:40 PM5/18/11
to lif...@googlegroups.com
You're making the assumption that there are no other width or height attributes in the snippet template!
Also, if the img tag has height and width attributes you don't need to reassign them. In Pawel's code he assigned them because he was reading them as snippet attributes.

What about:

def cssSelBind =
  "img" #> {(_: NodeSeq) match {case e: Elem =>
    val width = e.attribute("width").map(_.text) getOrElse "100"
    val height = e.attribute("height").map(_.text) getOrElse "100"
    val src = Helpers.appendParams(
      Image.prefix + ResizeMethod.Fit.toString,
      List(Image.ID_PARAM -> "%d".format(id.is), Image.WIDTH_PARAM -> width, Image.HEIGHT_PARAM -> height)
    )
    e % ("src" -> src)  // uses an implicit in Helpers from Tuple2 to MetaData
  }}


Note that if somehow "img" would match something other than an Elem, it would throw a MatchNotFoundError, so I'm relying on an assumption (which seems pretty sane); sometimes I wish the CSS selectors would be more type safe in this regard...



--
Reply all
Reply to author
Forward
0 new messages