I would like to discuss between custom elements without events in a parent custom element.
How could I do this, if it's possible ?
This is my-custom-parent-element.htlm :
<link rel="import" href="../my-custom-elment-1.html">
<link rel="import" href="../my-custom-elment-2.html">
<polymer-element name="my-custom-parent-element" noscript>
<template>
<my-custom-elment-1></my-custom-elment-1>
<my-custom-elment-2></my-custom-elment-2>
</template>
</polymer-element>
this is my-custom-element-1 :
<link rel="import" href="../polymer-gestures/polymer-gestures.html">
<polymer-element name="my-custom-element-1">
<template>
<div><canvas width="300px" height="200px"></canvas></div>
</template>
<script>
Polymer({
ready: function() {
<!-- Here, I need notify my-custom-element-2 that canvas received an event without re-send an event-->
}
});
</script>
</polymer-element>
this is my-custom-element-2 :
<polymer-element name="my-custom-element-2">
<template>
<div></div>
</template>
<script>
Polymer({
ready: function() {
<!-- Here, I need to change value by my-custom-element-1 notifications -->
}
});
</script>
</polymer-element>
Not sure either how you want to do this.
But you can also give reference to elem1 from the parent :
<polymer-element name="my-custom-parent-element" noscript>
<template>
<my-custom-elment-1 id="elem1"></my-custom-elment-1>
<my-custom-elment-2 id="elem2"></my-custom-elment-2>
</template>
<script>
Polymer({
domReady: function() {
this.$.elem1.target = this.$.elem2
}
});
</script>
</polymer-element>
And in elem1 :
<polymer-element name="my-custom-element-1" attributes="target">
<template>
<div><canvas width="300px" height="200px"></canvas></div>
</template>
<script>
Polymer({
ready: function() {
<!-- Here, I need notify my-custom-element-2 that canvas received an event without re-send an event-->
target.xxx();
}
});
</script>
</polymer-element>
But usually, the event way is better
Related
I am using a custom element that contains a <paper-dialog>, so that I can reuse the dialog style in my application.
The structure is the following:
Polymer({
is: 'dialog-confirm',
properties: {
title: {
type: String,
value: 'Dialog Title',
reflectsToAttribute: true
},
message: {
type: String,
value: 'Dialog message',
reflectsToAttribute: true
}
},
/**
* Triggered when the document is loaded
*/
ready: function () {
var me = this;
},
/**
* Open the dialog
*/
open: function () {
this.$.dialog.open();
}
});
Then, I declare my component as follows in order to have a "prepped" dialog ready to go:
(I removed the <link import="..."> for brevity)
<dom-module id="dialog-confirm">
<template>
<style>
</style>
<paper-dialog id="confirmation"
modal with-backdrop
entry-animation="slide-from-top-animation"
exit-animation="fade-out-animation"
on-iron-overlay-closed="_onSignoutConfirm">
<h2>{{title}}</h2>
<paper-dialog-scrollable>
<p>{{message}}</p>
</paper-dialog-scrollable>
<div class="buttons">
<paper-button class="normal" dialog-dismiss>NO</paper-button>
<paper-button class="positive" dialog-confirm>YES</paper-button>
</div>
</paper-dialog>
</template>
<script type="text/javascript" src="dialog-confirm.js"></script>
</dom-module>
The problem is that this is a component, and I would like to expose the iron-overlay-closed event outside the component. Otherwise, when I re-use my component, I can't data-bind this to a new method, as in:
<dialog-confirm id="myDialog" on-iron-overlay-closed="_myCustomMethod"></dialog-confirm>
Is this possible?
The iron-overlay-closed event already bubbles up from the child component, as seen in the following demo. If it doesn't bubble up for you, the problem might be caused by something else not shown in your question.
<head>
<base href="https://polygit.org/polymer+1.7.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-dialog/paper-dialog.html">
<link rel="import" href="paper-button/paper-button.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<x-dialog on-iron-overlay-closed="_myCustomMethod"></x-dialog>
</template>
<script>
HTMLImports.whenReady(() => {
Polymer({
is: 'x-foo',
_myCustomMethod: function() {
console.log('_myCustomMethod: overlay closed');
}
});
});
</script>
</dom-module>
<dom-module id="x-dialog">
<template>
<paper-dialog opened on-iron-overlay-closed="_onIronOverlayClosed">
<div class="buttons">
<paper-button dialog-dismiss>Ok</paper-button>
</div>
</paper-dialog>
</template>
<script>
HTMLImports.whenReady(() => {
Polymer({
is: 'x-dialog',
_onIronOverlayClosed: function() {
console.log('_onIronOverlayClosed: overlay closed');
}
});
});
</script>
</dom-module>
</body>
codepen
foo.html:
<link rel="import" href="bar.html">
<dom-module id="p-foo">
<template>
<p-bar>
<content select=".myContent"></content>
</p-bar>
</template>
<script>
Polymer( {
is: 'p-foo',
} )
</script>
</dom-module>
bar.html:
<dom-module id="p-bar">
<template>
bar open
<content select=".myContent"></content>
bar closed
</template>
<script>
Polymer( {
is: 'p-bar',
} )
</script>
</dom-module>
demo.html:
<!DOCTYPE html>
<html>
<head>
...
<link rel="import" href="foo.html">
</head>
<body>
<p-foo><div class="myContent"><strong>hello</strong></div></p-foo>
</body>
</html>
The expected output:
bar open
hello
bar closed
What I sometimes get:
bar open
bar closed
hello
The error I am getting is not 100% reproducible. It only happens a percentage of the time I refresh the page. It also appears that the more complicated the content is the higher chance of the error occurring.
It seems that polymer tries to select .myContent before the bar component is has completely rendered.
You need to register your new custom elements with a call to Polymer().
Also, as already stated in comments, your custom elements need to contain an hypen. For example: <p-foo>and <p-bar>.
foo.html:
<link rel="import" href="bar.html">
<dom-module id="p-foo">
<template>
<p-bar>
<content select=".myContent"></content>
</p-bar>
</template>
<script>
Polymer( {
is: 'p-foo',
} )
</script>
</dom-module>
bar.html:
<dom-module id="p-bar">
<template>
bar open
<content select=".myContent"></content>
bar closed
</template>
<script>
Polymer( {
is: 'p-bar',
} )
</script>
</dom-module>
demo.html:
<head>
...
<link rel="import" href="foo.html">
</head>
<body>
<p-foo><div class="myContent"><strong>hello</strong></div></p-foo>
</body>
</html>
<dom-module id="element-1">
<template>
<input type="text" value={{title}}>
</template>
<script>
Polymer({
properties: {
title: {type: String}
}
})
</script>
</dom-module>
<dom-module id="element-2">
<template>
<element-1></element-1> // Added dynamically using javascript.
</template>
<script>
Polymer({
properties: {
property_1: {type:String}
},
// Here, I can access property_1 by this.property_1
// How to get the property of element-1(title) here?
})
</script>
</dom-module>
So, basically, I have a component (element-2). Inside that component I dynamically add another element (element-1). Now, how the I read the properties of element-1 from element-2?
Any help will be much appreciated.
Polymer has an instance method to query its local DOM:
$$(selector). Returns the first node in this element's local DOM that matches selector.
With this method, you could use this.$$('element-1').title from <element-2>.
<head>
<base href="https://polygit.org/polymer+1.5.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<element-2></element-2>
<dom-module id="element-1">
<template>
<span>{{title}}</span>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'element-1',
properties : {
title: {
type: String,
value: "Hello world!"
}
}
});
});
</script>
</dom-module>
<dom-module id="element-2">
<template>
<div id="container"></div>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'element-2',
addElement1: function() {
var e1 = document.createElement('element-1');
this.$.container.appendChild(e1);
},
ready: function() {
this.addElement1();
var e1ref = this.$$('element-1');
console.log("this.$$('element-1').title:", e1ref.title);
}
});
});
</script>
</dom-module>
</body>
codepen
I've got button:
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-input/core-input.html">
<polymer-element name="count-button" extends="button" on-click="increment">
<template>
<content>Increment: </content>
</template>
<script>
Polymer({
counter: 0,
increment: function(e, detail, sender) {
this.counter++;
alert(this.counter);
}
})
</script>
</polymer-element>
I successfully use it in html by:
<button is="count-button"></button>
How to add such button in js? My incorrect version is (ready function):
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name='my-input'>
<template>
my input
<style>
</style>
</template>
<script>
Polymer('my-input', {
publish: {
},
ready: function() {
var node = document.createElement("button");
node.setAttribute('is', 'count-button');
this.shadowRoot.appendChild(node);
}
});
</script>
</polymer-element>
I've found the solution by my self and it's as easy as these 2 lines:
var node = document.createElement("button", 'count-button');
this.shadowRoot.appendChild(node);
So the complete answer is here:
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name='my-input'>
<template>
my input
<style>
</style>
</template>
<script>
Polymer('my-input', {
publish: {
},
ready: function() {
# only these 2 lines
var node = document.createElement("button", 'count-button');
this.shadowRoot.appendChild(node);
}
});
</script>
</polymer-element>
I would like to add listener event on a Polymer custom element with Polymer-gestures.
This is my sample code :
- my-custom-element.html
<link rel="import" href="../polymer/polymer.html">
<polymer-element name="my-custom-element" attributes="width height color">
<template>
<canvas id="canvas" width="{{width}}" height="{{height}}" style="background-color: {{color}}" touch-action="none"></canvas>
</template>
<script>
Polymer({
width: '',
height: '',
color: ''
});
</script>
</polymer-element>
- my-custom-parent-element.html
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../polymer-gestures/polymer-gestures.html">
<polymer-element name="my-custom-parent-element">
<template>
<my-custom-element width="300px" height="200px" color="yellow"></my-custom-element>
</template>
<script>
Polymer({
ready: function() {
this.myCustomElement = this.shadowRoot.querySelector('my-custom-element');
var events = [
// base events
'down',
'up',
'trackstart',
'track',
'trackend',
'tap',
'hold',
'holdpulse',
'release'
];
events.forEach(function(en) {
PolymerGestures.addEventListener(this.myCustomElement, en, function (inEvent) {
...
});
}
});
</script>
</polymer-element>
I have an error like this
Uncaught TypeError: Cannot read property '_pgListeners' of undefined
In debug mode when I add the event listener in my-custom-parent-element.html, I checked the value of the myCustomElement variable, and it's null.
How could I add the event listener on the myCustomElement variable ???
The querySelector in the following line is misspelled:
this.myCustomElement = this.shadowRoot.querrySelector('my-custom-element');
Try with this.shadowRoot.querySelector('my-custom-element');.