How can one bind value-less attributes?

46 views
Skip to first unread message

Alex Black

unread,
Dec 1, 2009, 5:28:21 PM12/1/09
to Lift
For example, if my html template looks like this:

<lift:surround with="default" at="content">
<h2>foobar</h2>
<lift:MySnippet.render>
<input type="checkbox"/>
</lift:MySnippet.render>
</lift:surround>

I'd like to render it conditionally as:

<h2>foobar</h2>
<input type="checkbox" checked/>

Is there syntax to add the "checked" to the checkbox? perhaps similar
to the syntax to bind attribute values?

Thanks!

- Alex

Ross Mellgren

unread,
Dec 1, 2009, 5:30:52 PM12/1/09
to lif...@googlegroups.com
Valueless attributes are prohibited by XML. The proper XHTML
formulation is to use the name of the attribute as the value, e.g.
checked="checked"

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

Alex Black

unread,
Dec 1, 2009, 5:42:48 PM12/1/09
to Lift
Thanks, I didn't know that!

Alex Black

unread,
Dec 1, 2009, 5:50:38 PM12/1/09
to Lift
Is there a good/reasonable way to conditionally output
checked="checked" or output nothing?

My code looks like this:

bind("manufacturer", xhtml,
AttrBindParam("selected", Text("selected"), "selected"))

I can add an if statement, and then output Text("notSelected")
instead, but that doesn't seem to work - the correct <option> is not
selected.

- Alex


On Dec 1, 5:30 pm, Ross Mellgren <dri...@gmail.com> wrote:

Alex Boisvert

unread,
Dec 1, 2009, 6:23:11 PM12/1/09
to lif...@googlegroups.com
You can use SHtml.checkbox() to easily generate the checkbox,

bind(...,
  "checkbox" -> SHtml.checkbox(isChecked, checked => if (checked) doSomething())
)

The first parameter is whether the checkbox should be checked by default.

The second parameter is a function to do something when form is submitted.

alex

Alex Black

unread,
Dec 1, 2009, 6:29:52 PM12/1/09
to Lift
Thanks Alex. That would work, but I'm looking for a more generic
solution.

Restating the problem: Based on some condition I want to generate an
attribute or not generate an attribute, e.g.:

<myElement myAttribute="value" />

OR

<myElement>

- Alex

On Dec 1, 6:23 pm, Alex Boisvert <alex.boisv...@gmail.com> wrote:
> You can use SHtml.checkbox() to easily generate the checkbox,
>
> bind(...,
>   "checkbox" -> SHtml.checkbox(isChecked, checked => if (checked)
> doSomething())
> )
>
> The first parameter is whether the checkbox should be checked by default.
>
> The second parameter is a function to do something when form is submitted.
>
> alex
>
> > liftweb+u...@googlegroups.com<liftweb%2Bunsu...@googlegroups.com>
> > > > .
> > > > For more options, visit this group athttp://
> > groups.google.com/group/liftweb?hl=en
> > > > .
>
> > --
>
> > 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<liftweb%2Bunsu...@googlegroups.com>

Alex Boisvert

unread,
Dec 1, 2009, 6:55:30 PM12/1/09
to lif...@googlegroups.com
Here's one way,

Helpers.bind(...,
  "myElement" -> (if (condition) <myElement/> else <myElement myAttribute="value"/>))

I don't think there's a bind helper to conditionally output the attribute.  Maybe our bind experts know.

alex

To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.

Alex Black

unread,
Dec 1, 2009, 6:59:49 PM12/1/09
to Lift
I appreciate the suggestion, I did think of that, but one of my goals
is to keep the XHTML out of my code..!

This seems a tough problem in general.. Ideally in snippets there
would be no presentation, just data I think, e.g. in this case a
boolean. The XHTML template would then form the presentation of that
data, whether it be a checkbox or whatever.

Perhaps I'm approaching this from the wrong angle?

- Alex

On Dec 1, 6:55 pm, Alex Boisvert <alex.boisv...@gmail.com> wrote:
> Here's one way,
>
> Helpers.bind(...,
>   "myElement" -> (if (condition) <myElement/> else <myElement
> myAttribute="value"/>))
>
> I don't think there's a bind helper to conditionally output the attribute.
> Maybe our bind experts know.
>
> alex
>
> > <liftweb%2Bunsu...@googlegroups.com<liftweb%252Buns...@googlegroups.com>
>
> > > > > > .
> > > > > > For more options, visit this group athttp://
> > > > groups.google.com/group/liftweb?hl=en
> > > > > > .
>
> > > > --
>
> > > > 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<liftweb%2Bunsu...@googlegroups.com>
> > <liftweb%2Bunsu...@googlegroups.com<liftweb%252Buns...@googlegroups.com>

Ross Mellgren

unread,
Dec 1, 2009, 7:03:53 PM12/1/09
to lif...@googlegroups.com
I think you are approaching it from the wrong angle. Lift is not an MVC style framework -- the template and the snippets coordinate (conspire?) to deliver XHTML. The actual tags might be in the snippet, if there's any logic being applied to their creation / modification / etc.

-Ross
> To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.

David Pollak

unread,
Dec 1, 2009, 7:08:52 PM12/1/09
to lif...@googlegroups.com
On Tue, Dec 1, 2009 at 3:59 PM, Alex Black <al...@alexblack.ca> wrote:
I appreciate the suggestion, I did think of that, but one of my goals
is to keep the XHTML out of my code..!

This seems a tough problem in general.. Ideally in snippets there
would be no presentation, just data I think, e.g. in this case a
boolean.  The XHTML template would then form the presentation of that
data, whether it be a checkbox or whatever.

Perhaps I'm approaching this from the wrong angle?

<lift:MySnippet>
<stuff:checked><input type="checkbox"/></stuff:checked>
</lift:MySnippet>
 

class MySnippet {
  def render(in: NodeSeq): NodeSeq = bind("stuff", in, "checked" -> (myNode => myNode % (if (shouldBeChecked) ("checked" -> "checked") else Null))
}

It would be nice to do:

<lift:MySnippet>
<input type="checkbox" stuff:checked="maybe"/>
</lift:MySnippet>

class MySnippet {
  def render(in: NodeSeq): NodeSeq = bind("stuff", in, FuncAttrBindParam("checked", _ => if (shouldBeChecked) Some("checked") else None, "checked"))
}

But that's not yet possible.  Maybe it's worth a ticket.


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.





--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Surf the harmonics

Jeppe Nejsum Madsen

unread,
Dec 2, 2009, 3:32:22 AM12/2/09
to lif...@googlegroups.com
Alex Black <al...@alexblack.ca> writes:

> Is there a good/reasonable way to conditionally output
> checked="checked" or output nothing?

If you output null for the attribute value, the attribute is not
rendered:

scala> bind("stuff", <input type="checkbox" stuff:s=""/>, AttrBindParam("s",Text("checked"),"checked"))
res11: scala.xml.NodeSeq = <input type="checkbox" checked="checked"></input>

scala> bind("stuff", <input type="checkbox" stuff:s=""/>, AttrBindParam("s",null,"selected"))
res12: scala.xml.NodeSeq = <input type="checkbox" ></input>

/Jeppe

Alex Black

unread,
Dec 2, 2009, 8:15:41 AM12/2/09
to Lift
Thanks Jeppe, that works perfectly.

On Dec 2, 3:32 am, Jeppe Nejsum Madsen <je...@ingolfs.dk> wrote:

David Pollak

unread,
Dec 2, 2009, 11:24:46 AM12/2/09
to lif...@googlegroups.com
null... shudder. :-)

--

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.


Jeppe Nejsum Madsen

unread,
Dec 2, 2009, 11:55:47 AM12/2/09
to lif...@googlegroups.com
David Pollak <feeder.of...@gmail.com> writes:

> null... shudder. :-)

Yeaah, somehow it doesn't look nice anymore :-) Your idea with an Option/Box
for attribute binding seems nice & clean

/Jeppe

>
> On Wed, Dec 2, 2009 at 12:32 AM, Jeppe Nejsum Madsen <je...@ingolfs.dk>wrote:
>
>> Alex Black <al...@alexblack.ca> writes:
>>
>> > Is there a good/reasonable way to conditionally output
>> > checked="checked" or output nothing?
>>
>> If you output null for the attribute value, the attribute is not
>> rendered:
>>
>> scala> bind("stuff", <input type="checkbox" stuff:s=""/>,
>> AttrBindParam("s",Text("checked"),"checked"))
>> res11: scala.xml.NodeSeq = <input type="checkbox"
>> checked="checked"></input>
>>
>> scala> bind("stuff", <input type="checkbox" stuff:s=""/>,
>> AttrBindParam("s",null,"selected"))
>> res12: scala.xml.NodeSeq = <input type="checkbox" ></input>
>>
>> /Jeppe
>>
>> --
>>
>> 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<liftweb%2Bunsu...@googlegroups.com>
>> .

Alex Black

unread,
Dec 6, 2009, 8:59:28 AM12/6/09
to Lift
> If you output null for theattributevalue, theattributeis not
> rendered:

I've just upgraded from 1.0 to 1.1-M6, and this doesn't seem to work
any more - could this be a bug in M6?

Message: scala.MatchError: null
scala.runtime.ScalaRunTime$.boxArray(ScalaRunTime.scala:136)
net.liftweb.util.BindHelpers$class.mix$1(BindHelpers.scala:612)
net.liftweb.util.BindHelpers$class.net$liftweb$util$BindHelpers$
$bindByNameMixIn(BindHelpers.scala:618)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind$1$1$
$anonfun$apply$27.apply(BindHelpers.scala:440)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind$1$1$
$anonfun$apply$27.apply(BindHelpers.scala:436)
net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:65)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind
$1$1.apply(BindHelpers.scala:436)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind
$1$1.apply(BindHelpers.scala:424)
scala.Seq$class.flatMap(Seq.scala:294)
scala.xml.NodeSeq.flatMap(NodeSeq.scala:34)
net.liftweb.util.BindHelpers$$anonfun$bind$2.in_bind$1
(BindHelpers.scala:424)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind
$1$1.apply(BindHelpers.scala:444)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind
$1$1.apply(BindHelpers.scala:424)
scala.Seq$class.flatMap(Seq.scala:294)
scala.xml.NodeSeq.flatMap(NodeSeq.scala:34)
net.liftweb.util.BindHelpers$$anonfun$bind$2.in_bind$1
(BindHelpers.scala:424)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind
$1$1.apply(BindHelpers.scala:444)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind
$1$1.apply(BindHelpers.scala:424)
scala.Seq$class.flatMap(Seq.scala:294)
scala.xml.NodeSeq.flatMap(NodeSeq.scala:34)
net.liftweb.util.BindHelpers$$anonfun$bind$2.in_bind$1
(BindHelpers.scala:424)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind
$1$1.apply(BindHelpers.scala:444)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind
$1$1.apply(BindHelpers.scala:424)
scala.Seq$class.flatMap(Seq.scala:294)
scala.xml.NodeSeq.flatMap(NodeSeq.scala:34)
net.liftweb.util.BindHelpers$$anonfun$bind$2.in_bind$1
(BindHelpers.scala:424)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind
$1$1.apply(BindHelpers.scala:444)
net.liftweb.util.BindHelpers$$anonfun$bind$2$$anonfun$in_bind
$1$1.apply(BindHelpers.scala:424)
scala.Seq$class.flatMap(Seq.scala:294)
scala.xml.NodeSeq.flatMap(NodeSeq.scala:34)
net.liftweb.util.BindHelpers$$anonfun$bind$2.in_bind$1
(BindHelpers.scala:424)
net.liftweb.util.BindHelpers$$anonfun$bind$2.apply(BindHelpers.scala:
449)
net.liftweb.util.BindHelpers$$anonfun$bind$2.apply(BindHelpers.scala:
409)
net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:65)
net.liftweb.util.BindHelpers$class.bind(BindHelpers.scala:409)
net.liftweb.util.Helpers$.bind(Helpers.scala:29)
net.liftweb.util.BindHelpers$class.bind(BindHelpers.scala:380)
net.liftweb.util.Helpers$.bind(Helpers.scala:29)

Jeppe Nejsum Madsen

unread,
Dec 6, 2009, 3:39:17 PM12/6/09
to lif...@googlegroups.com
Alex Black <al...@alexblack.ca> writes:

>> If you output null for theattributevalue, theattributeis not
>> rendered:
>
> I've just upgraded from 1.0 to 1.1-M6, and this doesn't seem to work
> any more - could this be a bug in M6?

Maybe. The code I wrote worked in 1.1-SNAPSHOT at the time.....you could
try this just to verify.

/Jeppe

[...]

Alex Boisvert

unread,
Dec 6, 2009, 10:25:52 PM12/6/09
to lif...@googlegroups.com
Using the latest and greatest (master branch), I can't reproduce the MatchError but I can reproduce the issue with the attribute being generated if the value is null.

I'll fix it tomorrow morning.

alex


David Pollak

unread,
Dec 6, 2009, 11:28:53 PM12/6/09
to lif...@googlegroups.com
On Sun, Dec 6, 2009 at 7:25 PM, Alex Boisvert <alex.b...@gmail.com> wrote:
Using the latest and greatest (master branch), I can't reproduce the MatchError but I can reproduce the issue with the attribute being generated if the value is null.

How about adding a Box alternative rather than perpetuating a paradigm based on null?
 

Alex Boisvert

unread,
Dec 7, 2009, 12:22:32 PM12/7/09
to lif...@googlegroups.com
On Sun, Dec 6, 2009 at 8:28 PM, David Pollak <feeder.of...@gmail.com> wrote:

On Sun, Dec 6, 2009 at 7:25 PM, Alex Boisvert <alex.b...@gmail.com> wrote:
Using the latest and greatest (master branch), I can't reproduce the MatchError but I can reproduce the issue with the attribute being generated if the value is null.

How about adding a Box alternative rather than perpetuating a paradigm based on null?

Yes, that's better.  I'll do that.

[Side diatribe:  Can't wait for a working scala.NotNull so we can implicitly convert (non-null) literal values to Some() or Full() instance and reduce verbosity]

alex

David Pollak

unread,
Dec 7, 2009, 12:24:32 PM12/7/09
to lif...@googlegroups.com


Mmmm.... sweet tasty NotNull.

 

alex

--

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.

Ross Mellgren

unread,
Dec 7, 2009, 12:29:59 PM12/7/09
to lif...@googlegroups.com
I looked at adding a Box variant, but it wasn't a strictly speaking trivial change since calcValue on BindParam is of type NodeSeq. I guess it could become Box[NodeSeq] and then when binding at element positions convert that to NodeSeq.Empty, but I also have had the need (which I've worked around) to be able to replace a single bound attribute with multiple result attributes, so I was thinking that it would be best to allow AttrBindParams to generate MetaData, not just a value.

I had written some code to play with this idea, but I didn't get too far because I was busy and needed feedback from other committers. I can return it to working tonight if there's interest.

-Ross

David Pollak

unread,
Dec 7, 2009, 12:43:40 PM12/7/09
to lif...@googlegroups.com
Is there a ticket for this?  I'm in ticket-closing mode today ;-)

Ross Mellgren

unread,
Dec 7, 2009, 12:57:17 PM12/7/09
to lif...@googlegroups.com

Alex Black

unread,
Dec 7, 2009, 5:58:53 PM12/7/09
to Lift
Thanks for the help on this guys, looks promising.

On Dec 7, 12:57 pm, Ross Mellgren <dri...@gmail.com> wrote:
> Sha-bam
>
> http://github.com/dpp/liftweb/issues/#issue/229
>
> -Ross
>
> On Dec 7, 2009, at 12:43 PM, David Pollak wrote:
>
> > Is there a ticket for this?  I'm in ticket-closing mode today ;-)
>
> > On Mon, Dec 7, 2009 at 9:29 AM, Ross Mellgren <dri...@gmail.com>  
> > wrote:
> > I looked at adding a Box variant, but it wasn't a strictly speaking  
> > trivial change since calcValue on BindParam is of type NodeSeq. I  
> > guess it could become Box[NodeSeq] and then when binding at element  
> > positions convert that to NodeSeq.Empty, but I also have had the  
> > need (which I've worked around) to be able to replace a single bound  
> > attribute with multiple result attributes, so I was thinking that it  
> > would be best to allow AttrBindParams to generate MetaData, not just  
> > a value.
>
> > I had written some code to play with this idea, but I didn't get too  
> > far because I was busy and needed feedback from other committers. I  
> > can return it to working tonight if there's interest.
>
> > -Ross
>
> > On Dec 7, 2009, at 12:22 PM, Alex Boisvert wrote:
>
> >> On Sun, Dec 6, 2009 at 8:28 PM, David Pollak <feeder.of.the.be...@gmail.com
> >> > wrote:
>
> >> On Sun, Dec 6, 2009 at 7:25 PM, Alex Boisvert <alex.boisv...@gmail.com
> > For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en
> > .
>
> > --
> > Lift, the simply functional web frameworkhttp://liftweb.net
> > Beginning Scalahttp://www.apress.com/book/view/1430219890
> > Follow me:http://twitter.com/dpp
> > Surf the harmonics
>
> > --
>
> > 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
> > .
Reply all
Reply to author
Forward
0 new messages