Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymer 1.0 - Binding css classes

I'm trying to include classes based on parameters of a json, so if I have the property color, the $= makes the trick to pass it as a class attribute (based on the polymer documentation)

<div class$="{{color}}"></div>

The problem is when I'm trying to add that class along an existing set of classes, for instance:

<div class$="avatar {{color}}"></div>

In that case $= doesn't do the trick. Is any way to accomplish this or each time that I add a class conditionally I have to include the rest of the styles through css selectors instead classes? I know in this example maybe the color could just simple go in the style attribute, it is purely an example to illustrate the problem.

Please, note that this is an issue only in Polymer 1.0.

like image 969
fray88 Avatar asked Jun 02 '15 22:06

fray88


2 Answers

As of Polymer 1.0, string interpolation is not yet supported (it will be soon as mentioned in the roadmap). However, you can also do this with computed bindings. Example

<dom-module>
  <template>
    <div class$="{{classColor(color)}}"></div>
  </template>
</dom-module>
<script>
  Polymer({
    ...
    classColor: function(color) {
      return 'avatar '+color;
    }
  });
<script>

Edit:

As of Polymer 1.2, you can use compound binding. So

<div class$="avatar {{color}}"></div>

now works.

like image 124
Neil John Ramal Avatar answered Nov 17 '22 02:11

Neil John Ramal


Update

As of Polymer 1.2.0, you can now use Compound Bindings to

combine string literals and bindings in a single property binding or text content binding

like so:

<img src$="https://www.example.com/profiles/{{userId}}.jpg">

<span>Name: {{lastname}}, {{firstname}}</span>

and your example

<div class$="avatar {{color}}"></div>

so this is no longer an issue.

The below answer is now only relevant to versions of polymer prior to 1.2

If you are doing this a lot, until this feature becomes available which is hopefully soon you could just define the function in one place as a property of Polymer.Base which has all of it's properties inherited by all polymer elements

//TODO remove this later then polymer has better template and binding features.
// make sure to find all instances of {{join( in polymer templates to fix them
Polymer.Base.join = function() { return [].join.call(arguments, '');}

and then call it like so:

<div class$="{{join('avatar', ' ', color)}}"></div>

then when it is introduced by polymer properly, just remove that one line, and replace

{{join('avatar', color)}}

with

avatar {{color}}

I use this a lot at the moment, not just for combining classes into one, but also things like path names, joining with a '/', and just general text content, so instead I use the first argument as the glue.

Polymer.Base.join = function() {
    var glue = arguments[0];
    var strings = [].slice.call(arguments, 1);
    return [].join.call(strings, glue);
}

or if you can use es6 features like rest arguments

Polymer.base.join = (glue, ...strings) => strings.join(glue);

for doing stuff like

<div class$="{{join(' ', 'avatar', color)}}"></div>
<img src="{{join('/', path, to, image.jpg)}}">
<span>{{join(' ', 'hi', name)}}</span>

of just the basic

Polymer.Base.join = (...args) => args.join('');
<div class$="{{join('avatar', ' ', color)}}"></div>
like image 26
Ryan White Avatar answered Nov 17 '22 01:11

Ryan White