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
Related
I am using Uppy as a js library for the client-side uploading system
Everything works well except that I can't seem to get the value of an input field using jQuery or Javavascript as a meta.
Ie : title:'hey', works but not description:$('#description').val(),
but it just sends a null value.And My server is not supposed to accept null values.
In the below code, the only metaFields that are sent with a not-null value are the 'titleandimagefields not thedesciptiontags and body` fields.Pls help
This is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="shortcut icon" type="image/x-icon" href="https://static.codepen.io/assets/favicon/favicon-aec34940fbc1a6e787974dcd360f2c6b63348d4b1f4e06c77743096d55480f33.ico" />
<link rel="mask-icon" type="" href="https://static.codepen.io/assets/favicon/logo-pin-8f3771b1072e3c38bd662872f6b673a722f4b3ca2421637d5596661b4e2132cc.svg" color="#111" />
<title>CodePen - Simple Dashboard</title>
<link rel='stylesheet' href='https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.css'>
<!--del later-->
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"/>
<!--del-->
<script>
window.console = window.console || function(t) {};
</script>
<script>
if (document.location.search.match(/type=embed/gi)) {
window.parent.postMessage("resize", "*");
}
</script>
<style>
#extraData{
margin-left:5%;
}
</STYLE>
</head>
<body translate="no">
<div id="drag-drop-area">#csrf <!-- {{ csrf_field() }} -->
</div>
<div class="form-group d-none w-50 m-20" id='extraData' >
<form id ='ExtraForm'>
<label for="title">Title:</label>
<input type="text" class="form-control" id="title"><br>
<label for="description">Description:</label>
<textarea class="form-control" rows="5" id="description"></textarea><br>
<label for="tags">Tags:</label>
<input type="text" class="form-control" id="tags"><br>
</form>
</div>
<script src="https://static.codepen.io/assets/common/stopExecutionOnTimeout-de7e2ef6bfefd24b79a3f68b414b87b8db5b08439cac3f1012092b2290c719cd.js"></script>
<script src='https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.js'></script>
<script id="rendered-js">
const uppy = Uppy.Core({ autoProceed: false });
const XHRUpload = Uppy.XHRUpload;
uppy.use(Uppy.Dashboard, { target: '#drag-drop-area', inline: true, height: 450 });
uppy.use(XHRUpload, {
endpoint: '/upload',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
// metaFields: [meta]
})
uppy.on('file-added', (file) => {
var v = document.getElementById('title').value;
$('#extraData').removeClass('d-none');
uppy.setFileMeta(file.id, {
size: file.size,
title:'hey',
description:$('#description').val(),
tags:$('#tags').val(),
body: v,
type:"image"
},
)
})
//# sourceURL=pen.js
</script>
You should use meta in Uppy.Core to send form data values.
Eg:
$description = $('#description').val()
Uppy.Core({
meta: {
description: $description,
title : 'hey'
},
I am using Polymer 1 for web-development and I am encountering a small lack of understanding. Imagine the following:
<div class="value">
<content></content>
</div>
I can easily style the content with the .value selector. Now I only want to style the First content element. :first-child etc. doesn't seem to work.
How can I select different elements of my <content></content> in Polymer?
Thanks!
Note that <content> has been deprecated for <slot>.
To target the first child of the <slot>/<content>, use ::slotted(:first-child):
HTMLImports.whenReady(() => {
Polymer({
is: 'x-foo',
properties: {
foo: {
type: String,
value: 'Hello world!'
}
}
});
});
<head>
<base href="https://cdn.rawgit.com/download/polymer-cdn/1.8.0/lib/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<x-foo>
<div>first</div>
<div>second</div>
<div>third</div>
</x-foo>
<dom-module id="x-foo">
<template>
<style>
::slotted(:first-child) {
color: red;
}
</style>
<slot></slot>
</template>
</dom-module>
</body>
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 ?
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
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>