javascripthtmlcsspolymerdom-repeat

In Polymer can I make a dynamically created paper-button change color when I click it?


I am trying to change the color of a paper-button that is created dynamically through the <template is="dom-repeat"> element. Let's say I have this piece of code:

<template is="dom-repeat" items="{{items}}" as="item">
  Itemnumber: [[item.number]] is [[item.height]].
  <paper-button on-click="setHigh">High</paper-button>
  <paper-button on-click="setLow">Low</paper-button>
</template>

Now when I click the button "High" for example, I want the background-color of that button to change and I want to background-color of the "Low" button to change as well. The Array items is stored locally and I have been able to do something similar to this using this code:

<template is="dom-repeat" items="{{items}}" as="item">
  Itemnumber [[item.number]] is [[item.height]].
  <template is="dom-if" if="[[isHigh(item)]]">
    <paper-button on-click="setHigh" class="active">High</paper-button>
    <paper-button on-click="setLow">Low</paper-button>
  </template>
  <template is="dom-if" if="[[!isHigh(item)]]">
    <paper-button on-click="setHigh">High</paper-button>
    <paper-button on-click="setLow" class="active">Low</paper-button>
  </template>
</template>

Now every Item that returns isHigh(item) as true will be part of class active (which I use to style the background-color), and false will not be part of that class. This works when I first load the page, however when I press the buttons and the Items array changes, I have to first reload the page for the styles to take effect. The attribute item.height DOES update immediately.


Solution

  • I would suggest adding a container around the two buttons on which you add a class which colors the buttons. Doing this with css is a lot lighter for your application, since it doesn't need to call getHigh when the buttons are pressed.

    <template is="dom-repeat" items="{{items}}" as="item">
      <div class="button-container">
      Itemnumber [[item.number]] is [[item.height]].
        <paper-button on-click="setHigh" class="high">High</paper-button>
        <paper-button on-click="setLow" class="low">Low</paper-button>
    </div>
    </template>
    

    Then make the functions add and remove a class on the div around them

    setHigh(e) {
      e.currentTarget.classList.add("high")
    }
    
    setLow(e) {
      e.currentTarget.classList.remove("high")
    }
    

    And in your css:

    .button-container .high {
      background-color: green;
    }
    
    .button-container .low {
      background-color: red;
    }
    
    /* When high is pressed */
    .button-container.high .high {
      background-color: red;
    }
    
    .button-container.high .low {
      background-color: green;
    }