SFG
SFG

Reputation: 323

Get Polymer element that was clicked on from event

I want to create a custom Polymer element that behaves like a button and has some HTML layout. Say:

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/iron-behaviors/iron-button-state.html">
<link rel="import" href="../../bower_components/iron-behaviors/iron-control-state.html">

<dom-module id="trivial-button">

    <template>
        <style>
        :host {
            display: inline-block;
            position: relative;
            background-color: #FFFFFF;
            width: 100%;
        }
        </style>

        <content style="color: #000000;">
        </content>
        <p style="color: #000000;">some brabbling</p>
    </template>

</dom-module>

<script>

    Polymer({
        is: 'trivial-button',

        that: this,

        behaviors: [
            Polymer.IronButtonState,
            Polymer.IronControlState
        ],
    });

</script>

I want to use this component in my page several times, like so:

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel='import' href='trivial-button.html'>

<dom-module id="page-browse">

    <template>
        <style include="triggi-colors">
            :host {
                display: block;
                box-sizing: border-box;
                padding: 10px;
            }
        </style>

        <trivial-button id='myFirstBytton' on-tap="handleTapped">1stButtonText</trivial-button>
        <trivial-button id='mySecondBytton' on-tap="handleTapped">2ndButtonText</trivial-button>

    </template>

    <script>

        Polymer({
            is: 'page-browse',

            handleTapped: function(e) {
                console.log('Hit the button!');
                console.log(e.target.id);
            }
        });

    </script>

</dom-module>

Now, when one of the instances is clicked, I want to access the properties of the top-level polymer object that is the button, so that I could for example do buttonReference.id. It seems that event.target is the way to go, however in my attempts event.target turns out to point to the exact HTML element that was clicked on, not to the polymer element that the HTML element is part of. Is there any way to retrieve the polymer element itself in the handler?

Upvotes: 0

Views: 4645

Answers (3)

TreeAndLeaf
TreeAndLeaf

Reputation: 1273

And if you have nested elements inside your Polymer element you can traverse up the DOM to find your element:

item = e.srcElement; // or Polymer.dom(e).localTarget
while (item.tagName !== 'MY-ELEMENT' && item.parentElement !== null)
  item = item.parentElement;
if (item.tagName === 'MY-ELEMENT')
  ... do something with the element ...

Upvotes: 0

Dogs
Dogs

Reputation: 3167

I suspect you are currently using shady DOM. However, you are expecting the event-retargeting behavior of shadow DOM (you want the event listener to see your button element, not the HTML inside of your button element).

The easiest way to fix this is to normalize the event targeting with Polymer's API.

In other words, replacing e.target with Polymer.dom(e).localTarget will give you your custom element instead of the HTML inside of your custom element.

Read more about shadow DOM vs shady DOM event targeting here: https://www.polymer-project.org/1.0/docs/devguide/events.html#retargeting

Upvotes: 2

Jan Gunzenhauser
Jan Gunzenhauser

Reputation: 73

You could listen for the event on the child element and pass it on to the parent by firing the 'handeTapped' event.

test-button-click-target.html

<p on-tap="notifyParent" style="color: #000000;">some brabbling</p>

Listener:

notifyParent: function(e) {
   e.detail.id = this.id;
   e.detail.isChild = true;
   this.fire('handleTapped', e.detail );
}

page-browse.html

handleTapped: function(e) {
 console.log('Hit the button!');
 if (e.detail.isChild)
    console.log(e.detail.id);
 else 
    console.log(e.target.id);
}

In your page-browse element you check if the event was fired directly or by a child.

Note: This seems a bit hacky and I only tested it on chrome.

Upvotes: 0

Related Questions