MDV question: conditional HTML class attributes

252 views
Skip to first unread message

Martijn Faassen

unread,
Jun 24, 2013, 10:06:34 AM6/24/13
to polymer-dev
Hi there,

A common pattern is to include a class on an element if some condition
is true. I can't find a shorter way to express this in MDV than this:

<template if="{{active}}">
<li class="active">Foo</li>
</template>
<template if="{{!active}}">
<li>Foo</li>
</template>

(not sure about "!active" as the correct spelling of not active)

Unless I'm missing something conditional attributes don't seem to
cover this case, as I wouldn't be able to express the existence of a
class, just the existence of an attribute.

So this is rather a lot of repetition, especially if you have other
things going on too.

In Obviel Template I got around this by allowing a callback into
JavaScript that set things up. In hypothetical MDV terms:

<li mdv-call="myfunc">Foo</li>

var myfunc = function(element, bound) {
if (bound.active) {
element.classList.add("active");
}
}

This is quite powerful, but might run into all sorts of issues as
myfunc can depend on arbitrary state, so MDV won't know whether things
need to be updated or not. With sufficient extra metadata something
like this could be made to work, though, I imagine.

Another pattern I explored is something like this:

<li><template if="{{active}}"><mdv-attr
name="class">active</mdv-attr></template>Foo</li>

this allows you to apply conditional logic directly to attributes. But
this has a serious limitation: it won't work for elements which don't
allow such element content, such as input, img and textarea.

Does anyone have something better in mind? Or again, perhaps I missed something.

Regards,

Martijn

Eric Bidelman

unread,
Jun 24, 2013, 10:42:09 AM6/24/13
to Martijn Faassen, polymer-dev
Hi Martijn,

We turned on a default expression syntax for Polymer in the latest release,
which adds support for this type of behavior.

Conditionally apply a class with an expression like this:

<div class="{{ active: user.selected; big: user.type == 'super' }}">
-> <div class="active big"> if user.selected is truthy and user.type is "super". 





--
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Martijn Faassen

unread,
Jun 24, 2013, 10:54:51 AM6/24/13
to Eric Bidelman, polymer-dev
Hi Eric,

Thanks, I should read that document carefully. That looks like a nice solution!

I see it also answers a question I had about accessing an outer scope
object in an inner scope. Awesome!

Regards,

Martijn

Eric Bidelman

unread,
Jun 24, 2013, 10:59:03 AM6/24/13
to Martijn Faassen, polymer-dev
No problem. There's lot-o-good stuff in there.

I've added a link from the main MDV docs to the Expression Syntax doc.
Hopefully it will be easier to find next time we publish docs.
Message has been deleted

Eric Bidelman

unread,
Dec 11, 2014, 3:44:18 PM12/11/14
to fab...@gmail.com, polymer-dev, Martijn Faassen
The syntax changed, but same general idea:

<div class="{{ {active: user.selected, big: user.type == 'super'} | tokenList}}">


On Thu, Dec 11, 2014 at 11:12 AM, <fab...@gmail.com> wrote:
Hi,

Just wondering does this solution still work in Polymer version 0.5.1? I seem to have no luck with it....

<div class="{{ active: user.selected}}">


If not, could someone tell me the correct way to approach this?

Thanks, Willem

Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.

Sam Carecho

unread,
Dec 11, 2014, 4:25:43 PM12/11/14
to Eric Bidelman, fab...@gmail.com, polymer-dev, Martijn Faassen
Eric and fellows,


It's not working for me.

I was using javascript's "classList" "add()" and "remove()" methods to change the classes of the elements within the shadow DOM.
After reading this thread I changed my code to use Polymer Expressions, but it seems that I'm doing something wrong,

Can you or someone lend a little hand?

Here is my code:

--> the custom element tag:
<my-tag someAttribute></my-tag>


--> the custom element definition:
<polymer-element name="my-tag" attributes="notitle author">
<template>
<div id="someId" class="{{ {someClass: someAttribute} | tokenList}}"></div>
</template>
<script>
Polymer({
author: this.author,
ready: function() {  }
});
</script>
</polymer-element>


Thanks,
Sam 

Eric Bidelman

unread,
Dec 11, 2014, 4:32:16 PM12/11/14
to Sam Carecho, fab...@gmail.com, polymer-dev, Martijn Faassen
That element definition doesn't match your <my-tag someAttribute></my-tag> declaration.

Sam Carecho

unread,
Dec 11, 2014, 4:38:41 PM12/11/14
to Eric Bidelman, fab...@gmail.com, polymer-dev, Martijn Faassen
Eric,

Thanks for the reply :) , but the jsbin link leads to a default jsbin, no code there, just a HTML default template.


Cheers,
Sam

Eric Bidelman

unread,
Dec 11, 2014, 4:40:57 PM12/11/14
to Sam Carecho, fab...@gmail.com, polymer-dev, Martijn Faassen

Sam Carecho

unread,
Dec 11, 2014, 5:22:15 PM12/11/14
to Eric Bidelman, fab...@gmail.com, polymer-dev, Martijn Faassen
Thank you Eric :)


But I'm still doing something wrong.
Regarding the declaration of the attribute "someAttribute", I got it wrong while typing the sample code that was based on the actual app code.

Sorry for taking all this time from you, but please, can you take a look on this extraction of the actual code to help me identify why the expression is not working?

http://jsbin.com/lifalabuhe/1/edit?html,output


Cheers,
Sam

Eric Bidelman

unread,
Dec 11, 2014, 5:28:35 PM12/11/14
to Sam Carecho, fab...@gmail.com, polymer-dev, Martijn Faassen
Object keys with "-" need to use string notation:

{{ {'video-hero': videoHero} | tokenList}}

Sam Carecho

unread,
Dec 11, 2014, 5:40:57 PM12/11/14
to Eric Bidelman, fab...@gmail.com, polymer-dev, Martijn Faassen
Thanks a lot :)


I would have spent hours and hours looking for the source of the error, if it wasn't for your help. 


Cheers,
Sam

Sam Carecho

unread,
Dec 11, 2014, 5:50:21 PM12/11/14
to Eric Bidelman, fab...@gmail.com, polymer-dev, Martijn Faassen
Eric,


Just one more thing, what would be the best approach to add and remove classes to/from the host element?
On my code, as I said before, I'm using "classList" to change the host class. Does Polymer offers a better way of doing that?


Cheers,
Sam

Eric Bidelman

unread,
Dec 11, 2014, 6:33:39 PM12/11/14
to Sam Carecho, fab...@gmail.com, polymer-dev, Martijn Faassen
Classes, no. But you can use a published property instead of a class and 
reflect it. Then define the :host([someAttr]) stylings within your element.

Sam Carecho

unread,
Dec 11, 2014, 6:39:59 PM12/11/14
to Eric Bidelman, fab...@gmail.com, polymer-dev, Martijn Faassen
Thanks :)
Reply all
Reply to author
Forward
0 new messages