Search code examples
polymerpolymer-1.0paper-elements

Tap listener for polymer iron-list item?


I have a custom element that utilizes iron-list to display an array of objects. Each item is generated via a template as follows:

<iron-list id="projectList" items="[[projects]]" indexAs="_id" as="projLI" class="layout flex">
    <template>
        <div>
           <paper-material id="itemShadow" animated elevation="1">
               <div class="item layout horizontal" onmouseover="hoverOver(this)" onmouseout="hoverOut(this)">

                   <!-- I use a paper-menu-button to display a list of available actions here -->

                   <!-- list item object content here such as: [[projLI.desc]] etc. -->

               </div>
           </paper-material>
        </div>
    </template>
</iron-list>

What is the best polymer-friendly approach to detect both a tap event on the iron-list item itself (ideally knowing which item was actually tapped via projLI._id), yet also be able to handle the internal paper-menu-button tap events in a different way?

I've eye-balled polymer 1.0's new event listeners (https://www.polymer-project.org/1.0/docs/devguide/events.html), as a possible approach, attempting to listen for different element tap events (as shown in example 1 on that page), but I'm not sure if that will work here. I've also considered possibly using iron-selector somehow around iron-list? Is that doable? I'm not sure that will work either, given that iron-selector would only have one child (i.e. the iron-list element and not it's templated children).

I feel like I'm missing a really easy way to accomplish this. Can someone please show me the light?


Solution

  • I do this by encoding an array index in a list element id, then pulling the id out of a list item event target. Here is an example Polymer element that does this.

    <link rel="import" href="../../bower_components/polymer/polymer.html">
    <link rel="import" href="../../bower_components/iron-list/iron-list.html">
    
    <dom-module id="list-example">
      <style>
        :host {
          display: block;
        }
    
        #list-example {
          height: 100px;
        }
      </style>
      <template>
    
        <paper-material animated elevation="1">
          <iron-list id="list-example" items="[[data]]">
            <template>
              <div id="{{index2id(item.index)}}" on-mouseover="onMouseOverItem">{{item.name}}</div>
            </template>
          </iron-list>
        </paper-material>
    
      </template>
    </dom-module>
    
    <script>
      (function () {
        Polymer({
          is: 'list-example',
    
          ready: function() {
            for(var i = 0; i < this.data.length; i++) {
              this.data[i].index = i;
            }
          },
    
          index2id: function(index) {
            return "_" + index;
          },
    
          id2index: function(id) {
            return Number(id.substr(1));
          },
    
          onMouseOverItem: function(e) {
            console.log('on-mouseover list item:', this.data[this.id2index(e.target.getAttribute('id'))]);
          },
    
          properties: {
            data: {
              type: Array,
              value: [{name: 'A'}, {name: 'B'}, {name: 'C'},
                      {name: 'D'}, {name: 'E'}, {name: 'F'},
                      {name: 'G'}, {name: 'H'}, {name: 'I'}]
            }
          }
        });
      })();
    </script>