0
votes

We cannot get this simple use case running with [email protected]. We have a list of items. If user click on an item, an icon before the item will be shown. Also a specific is-selected class will be added to this item.

The list will be rendered with a dom-repeat. Each list item looks like:

{
  "label": "Item 1",
  "value": 0
}

If the user click in that item, we store the value in variable selectedValue. For some reason, the dom-repeat will not be rerendering. So the functions isSelected and getSelectedClass only will be called initially. But not after click-interaction. We already tried to use the this.$.listItems.render(); inside the selectItem-function. But also have to effect. How we can handle this?

Our current code:

<dom-module id="selectable-list">
  <template>
    <style is="custom-style" include="selectable-list-styles"></style>
    <ul id="selectable-list">
      <template is="dom-repeat" items="[[items]]" id="itemList">
        <li class$="{{getSelectedClass(item)}}">
          <template is="dom-if" if="{{isSelected(item)}}">
            <iron-icon icon="sanitas-icons:check"></iron-icon>
          </template>
          <button type="button" on-click="selectItem">{{item.label}}</button>
        </li>
      </template>
    </ul>
  </template>

  <script>
    var SELECTED_CLASS = 'is-selected';

    Polymer({

      is: 'selectable-list',

      properties: {
        items: {
          type: Array,
          value: []
        },
        selectedValue: {
          type: Object,
          notify: true,
          reflectToAttribute: true
        }
      },

      selectItem: function(event){
        this.selectedValue = event.model.item.value;
      },


      /**
       * check if a list item is selected
       *
       * @param {object} item
       * @returns {boolean}
       */
      isSelected: function(item){
        return item.value === this.selectedValue;
      },


      /**
       * get selected class if item is selected
       * @param {object} item
       * @returns {string}
       */
      getSelectedClass: function(item){
        return this.isSelected(item) ? SELECTED_CLASS : '';
      }

    });
  </script>
</dom-module>
1

1 Answers

2
votes

The problem is your dom-if and dom-repeat do not get re-triggered once you select some item as both of them depends on item which do not change. So the simple solution will be to add selectedValue also as variable to your functions

<li class$="{{getSelectedClass(item, selectedValue)}}">
  <template is="dom-if" if="{{isSelected(item,selectedValue)}}">

and in js

isSelected: function(item, selectedValue){
  return item.value === selectedValue;
},

getSelectedClass: function(item, selectedValue){
  return this.isSelected(item, selectedValue) ? SELECTED_CLASS : '';
}

<base href="https://polygit.org/polymer+v1.4.0/components/">

<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<dom-module id="selectable-list">
  <template>
    <style is="custom-style" include="selectable-list-styles"></style>
    <ul id="selectable-list">
      <template is="dom-repeat" items="[[items]]" id="itemList">
        <li class$="{{getSelectedClass(item, selectedValue)}}">
          <template is="dom-if" if="{{isSelected(item,selectedValue)}}">
            yes
          </template>
          <button type="button" on-click="selectItem">{{item.label}}</button>
        </li>
      </template>
    </ul>
  </template>

  <script>
    var SELECTED_CLASS = 'is-selected';

    Polymer({

      is: 'selectable-list',

      properties: {
        items: {
          type: Array,
          value: function() {
            return [{
              "label": "Item 1",
              "value": 0
            }, {
              "label": "Item 2",
              "value": 1
            }, {
              "label": "Item 3",
              "value": 2
            }]
          }
        },
        selectedValue: {
          type: Object,
          notify: true,
          reflectToAttribute: true
        }
      },

      selectItem: function(event) {
        this.selectedValue = event.model.item.value;
      },


      /**
       * check if a list item is selected
       *
       * @param {object} item
       * @returns {boolean}
       */
      isSelected: function(item, selectedValue) {
        return item.value === selectedValue;
      },


      /**
       * get selected class if item is selected
       * @param {object} item
       * @returns {string}
       */
      getSelectedClass: function(item, selectedValue) {
        return this.isSelected(item, selectedValue) ? SELECTED_CLASS : '';
      }

    });
  </script>
</dom-module>


<selectable-list></selectable-list>