Reputation: 323
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
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
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
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