My problem is same as an already question as Polymer paper-dialog.open() is not defined
My imports include
<link rel="import" src="../bower_components/paper-date-picker/paper-date-picker.html">
<link rel="import" src="../bower_components/paper-styles/demo-pages.html">
<link rel="import" src="../bower_components/paper-dialog/paper-dialog.html">
<link rel="import" src="../bower_components/paper-date-picker/paper-date-picker-dialog-style.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
Dialog HTML Section
<paper-button class="btn" on-tap="showDialog" raised>Change Date</paper-button>
<paper-dialog id="dialog1" class="paper-date-picker-dialog" modal on-iron-overlay-closed="dismissDialog">
<paper-date-picker id="picker1" date="[[appuser.date]]"></paper-date-picker>
<div class="buttons">
<paper-button dialog-dismiss>Cancel</paper-button>
<paper-button dialog-confirm>OK</paper-button>
</div>
</paper-dialog>
Code
Polymer({
is: "cp-login",
properties: {
appuser: {
type: Object,
value: {}
}
},
saveAPPUSER: function() {
if (!this.$.formappuser.validate()) return;
this.$.submitAPPUSER.url = "http://localhost:3000/app/appuser";
this.$.submitAPPUSER.body = this.appuser;
this.$.submitAPPUSER.generateRequest();
},
submitAPPUSERSuccess: function(data) {
console.log(data)
},
submitAPPUSERError: function(err) {
console.log(err)
},
showDialog : function(){
this.$.dialog1.open();
},
ready : function(){
this.appuser.date = new Date(2017, 3, 13);
this.showDialog();
}
})
For me here none of the functionality toggles, open either works via code or directly in html as dialog1.open().
Any idea what I'm doing wrong ?
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
Is there a way to toggle the type of a paper-input programmatically?
I have a paper-input element of type password and I want to change the type to text and vice versa.
This is the element what it looks like:
This is the implementation of the element:
<paper-input id="oldPassword"
type="password"
label="Old password"
no-label-float required>
<paper-icon-button suffix on-tap="toggleVisibility"
icon$="[[setVisibility(passVisible)]]">
</paper-icon-button>
</paper-input>
This is the JavaScript part:
toggleVisibility (e) {
this.passVisible = !this.passVisible;
e.currentTarget.type = this.passVisible ? 'text' : 'password';
}
The problem is that the type is set correctly but the paper-input element didn’t redraw itself.
Thanks for help!
The answer by Tony does a great job answering your question.
I'd like to add to it by introducing some more declarative bindings into your element.
See below how I toggle the input type and icon by observing the icon button's active property and using it with computed bindings.
Polymer({
is: 'some-form',
getPasswordType: function (passVisible) {
return passVisible ? 'text' : 'password';
},
getVisibilityIcon: function(isVisible) {
return isVisible ? 'visibility' : 'visibility-off';
}
})
<base href="https://polygit.org/components/">
<link href="polymer/polymer.html" rel="import">
<link href="paper-input/paper-input.html" rel="import">
<link href="paper-icon-button/paper-icon-button.html" rel="import">
<link href="iron-icons/iron-icons.html" rel="import">
<some-form></some-form>
<dom-module id="some-form">
<template>
<paper-input id="oldPassword"
type="[[getPasswordType(passVisible)]]"
label="Old password"
value="secret"
no-label-float required>
<paper-icon-button suffix toggles
active="{{passVisible}}"
icon$="[[getVisibilityIcon(passVisible)]]">
</paper-icon-button>
</paper-input>
</template>
</dom-module>
In this case, e.currentTarget is actually <paper-icon-button>, not the <paper-input>.
You could reference the password input explicitly with this.$.oldPassword:
HTMLImports.whenReady(() => {
"use strict";
Polymer({
is: 'x-foo',
properties: {
passVisible: {
type: Boolean,
value: false
}
},
setVisibility(visible) {
return visible ? 'icons:visibility' : 'icons:visibility-off';
},
toggleVisibility(e) {
this.passVisible = !this.passVisible;
this.$.oldPassword.type = this.passVisible ? 'text' : 'password';
}
});
});
<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="iron-icons/iron-icons.html">
<link rel="import" href="paper-input/paper-input.html">
<link rel="import" href="paper-icon-button/paper-icon-button.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<paper-input id="oldPassword"
type="password"
label="Old password"
no-label-float
required>
<paper-icon-button suffix
on-tap="toggleVisibility"
icon="[[setVisibility(passVisible)]]">
</paper-icon-button>
</paper-input>
</template>
</dom-module>
</body>
codepen
...or you could find the paper-input ancestor of e.currentTarget, which might make sense if you'd like to reuse the button handler for two of these paper-inputs in the same custom element (e.g., old and new password inputs):
HTMLImports.whenReady(() => {
"use strict";
Polymer({
is: 'x-foo',
properties: {
passVisible: {
type: Boolean,
value: false
}
},
setVisibility(visible) {
return visible ? 'icons:visibility' : 'icons:visibility-off';
},
_getPaperInputAncestor(el) {
while (el && el.localName !== 'paper-input') {
el = el.parentElement;
}
return el;
},
toggleVisibility(e) {
this.passVisible = !this.passVisible;
const input = this._getPaperInputAncestor(e.currentTarget);
input.type = this.passVisible ? 'text' : 'password';
}
});
});
<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="iron-icons/iron-icons.html">
<link rel="import" href="paper-input/paper-input.html">
<link rel="import" href="paper-icon-button/paper-icon-button.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<paper-input id="oldPassword"
type="password"
label="Old password"
no-label-float
required>
<paper-icon-button suffix
on-tap="toggleVisibility"
icon="[[setVisibility(passVisible)]]">
</paper-icon-button>
</paper-input>
<paper-input id="newPassword"
type="password"
label="New password"
no-label-float
required>
<paper-icon-button suffix
on-tap="toggleVisibility"
icon="[[setVisibility(passVisible)]]">
</paper-icon-button>
</paper-input>
</template>
</dom-module>
</body>
codepen
In Polymer, I'm trying to lazy load the content in the DOM. There is an example to do that on scroll using the iron-scroll-threshold. But how to achieve the same on button click??
<head>
<base href="https://polygit.org/polymer+1.5.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="iron-list/iron-list.html">
<link rel="import" href="iron-scroll-threshold/iron-scroll-threshold.html">
<link rel="import" href="paper-progress/paper-progress.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<style>
iron-list {
height: 400px;
}
</style>
<iron-scroll-threshold id="threshold"
lower-threshold="50"
on-lower-threshold="_loadMoreData"
lower-triggered="{{nearBottom}}">
<iron-list scroll-target="threshold" items="[[items]]">
<template>
<div>[[index]]: [[item]]</div>
</template>
</iron-list>
</iron-scroll-threshold>
<button on-tap="handleTap">Load More</button>
<template is="dom-if" if="[[nearBottom]]">
<paper-progress indeterminate></paper-progress>
</template>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo',
properties: {
items: {
type: Array,
value: function() { return []; }
}
},
handleTap: function() {
_loadMoreData();
},
_loadMoreData: function() {
console.log('loading 100 more...');
// simulate network delay
this.async(function() {
for (let i = 0; i < 50; i++) {
this.push('items', Math.random());
}
this.$.threshold.clearTriggers();
}, 500);
}
});
});
</script>
</dom-module>
</body>
Here's the code that I'm trying out
You are missing the this:
handleTap: function() {
this._loadMoreData();
}
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');.