Custom element height 0px inside a template - polymer

I have created a custom element,
When I put it inside a template, its height will be 0px, while it's not if I put it outside the template ...
<link href="//www.polymer-project.org/0.5/components/polymer/polymer.html" rel="import">
<link href="//www.polymer-project.org/0.5/components/paper-input/paper-input-decorator.html" rel="import">
<polymer-element name="dalilak-date-picker" attributes="selectedDate">
<template>
<style>
:host {
display: block;
}
</style>
<paper-input-decorator
label="date picker"
floatingLabel
error="Please enter the date in the following format dd/mm/yyyy "
isInvalid="{{isInvalid}}"
>
<input is="core-input" value="{{inputValue}}" on-input="{{inputChanged}}">
</paper-input-decorator>
</template>
<script>
Polymer('dalilak-date-picker', {
// source: http://stackoverflow.com/a/15504877/2407522
datePattern: /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/gm,
inputChanged: function() {
if (this.validateDate()) {
this.selectedDate = this.inputValue;
return;
}
this.selectedDate = null;
},
validateDate: function() {
this.isInvalid = !this.inputValue.match(this.datePattern);
return !this.isInvalid;
}
});
</script>
</polymer-element>
<template is="auto-binding">
<div vertical layout>
<dalilak-date-picker flex selectedDate="{{selectedDate}}"></dalilak-date-picker>
<div>
selected date is: {{selectedDate}}
</div>
</div>
</template>

Related

Duble rows when use row details in Vaadin-grid polymer 2

I try implement row-datails in webcomponnet written in polymer 2. For this I use example : https://vaadin.com/components/vaadin-grid/html-examples/grid-row-details-demos#row-details-with-polymer-template
I try show row details in two ways: _onActiveItemChanged end expanded.
When I use it the lines have doubled.
How to show my template?
My code
<link rel="import" href="./bower_components/vaadin-button/vaadin-button.html" />
<link
rel="import"
href="./bower_components/vaadin-text-field/vaadin-text-field.html"
/>
<link
rel="import"
href="./bower_components/vaadin-checkbox/vaadin-checkbox-group.html"
/>
<link
rel="import"
href="./bower_components/vaadin-combo-box/vaadin-combo-box.html"
/>
<link
rel="import"
href="./bower_components/vaadin-checkbox/vaadin-checkbox.html"
/>
<link rel="import" href="./bower_components/vaadin-grid/vaadin-grid.html" />
<link
rel="import"
href="./bower_components/vaadin-grid/vaadin-grid-column.html"
/>
<link
rel="import"
href="./bower_components/paper-checkbox/paper-checkbox.html"
/>
<dom-module id="grid-wraper">
<template>
<style>
:host {
display: block;
}
.details {
padding: 10px;
margin: 10px;
display: flex;
justify-content: space-around;
align-items: center;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14);
font-size: 20px;
}
img {
width: 80px;
height: 80px;
}
</style>
<div class="card card-scale-anim">
<div class="card-titleBlue">
<iron-icon class="icon-user" icon="account-circle"></iron-icon>
<h2 class="title">Lista użytkowników e-usług</h2>
</div>
<div class="org-users-table">
<vaadin-grid
class="users-grid"
id="grid"
height-by-rows
data-provider="[[_gridDataProvider]]"
style="height: auto"
selected-items="{{_selectedItems}}"
active-item="{{_activeUser}}"
on-active-item-changed="_onActiveItemChanged"
>
<template class="row-details">
<div class="details">
<img src="[[item.picture.large]]" />
<p>Hi! My name is [[item.name]]!</p>
</div>
</template>
<vaadin-grid-column resizable width="100px">
<template>[[item.name]]</template>
</vaadin-grid-column>
<vaadin-grid-column width="100px">
<template class="header"></template>
<template>
<paper-checkbox
aria-label$="Show Details for [[item.name]]"
checked="{{expanded}}"
>Show Details</paper-checkbox
>
</template>
</vaadin-grid-column>
</vaadin-grid>
</div>
</div>
</template>
<script>
class GridWraper extends Polymer.Element {
static get is() {
return "grid-wraper";
}
static get properties() {
return {
dataProvider: { type: Function, notify: true },
};
}
_onActiveItemChanged(e) {
console.log("Active item", e);
this.$$("#grid").expandedItems = [e.detail.value];
}
$$(selector) {
return this.shadowRoot.querySelector(selector);
}
ready() {
super.ready();
Polymer.RenderStatus.afterNextRender(this, function () {});
}
}
window.customElements.define(GridWraper.is, GridWraper);
</script>
</dom-module>
If you want to expand the items on active change (ie. when user clicks on the row), then your _onActiveItemChanged method should use Grid's detailsOpenedItems property like so:
_onActiveItemChanged(e) {
this.$.grid.detailsOpenedItems = [e.detail.value];
}
However, if you want to open the detail with the checkbox, then you would need to bind the checked attribute to detailsOpened:
<paper-checkbox aria-label$="Show Details for [[item.firstName]]" checked="{{detailsOpened}}">Show Details</paper-checkbox>
A small note:
Polymer components bind all elements with id to a $ object, so instead of this.$$("#grid"), you can use this.$.grid (as seen on my code above).

How to access details of a swiped paper-card in iron-swipeable-container

I have a swipeable-container with a dom-repeat (firebase data)
<iron-swipeable-container id="teamchat">
<template is="dom-repeat" items="[[tcmmessages]]" as="tcmmessage">
<paper-card id="tcmcard" class="swipe item blue" data-index$="[[tcmmessage.__firebaseKey__]]">
<div class="card-content">
<b>[[tcmmessage.teamname]]</b>
<paper-icon-button style="color: red;" on-tap="_startChat" icon="communication:chat"></paper-icon-button><br>
[[tcmmessage.beitrag]]<br>
<span class="chatmetadata">von [[tcmmessage.username]]
• [[tcmmessage.update]] • [[tcmmessage.uptime]] </span>
</div>
</paper-card>
</template>
</iron-swipeable-container>
I defined a listener
listeners: {
'teamchat.iron-swipe': '_onTeamChatSwipe'
},
I try to access data-index from the swiped paper-card.
_onTeamChatSwipe: function() {
var card = this.$$('#tcmcard');
var key = card.getAttribute("data-index");
but after swipe event I can not access data-index of the swiped card.
With this.$$('#tcmcard') in the iron-swipe handler, you're querying the local DOM for the swiped element, but it's removed from the DOM before the iron-swipe event fires, so the query would not return what you'd expect.
But you don't need to query for the swiped element because <iron-swipeable-container> fires the iron-swipe event with the swiped element stored in event.detail.target.
Try this:
_onTeamChatSwipe: function(e) {
var card = e.detail.target;
var key = card.getAttribute("data-index");
// simpler syntax to get `data-index`
// key = card.dataset.index;
}
<head>
<base href="https://polygit.org/polymer+1.4.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-card/paper-card.html">
<link rel="import" href="iron-swipeable-container/iron-swipeable-container.html">
<link rel="import" href="iron-flex-layout/iron-flex-layout-classes.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<style include="iron-flex">
paper-card {
margin-bottom: 16px;
}
</style>
<template>
<iron-swipeable-container class="container" on-iron-swipe="_onSwipe">
<template is="dom-repeat" items="[[items]]">
<paper-card heading="{{item}}" data-index$="{{index}}" class="layout vertical">
<div class="card-content">
Swipe me left or right
</div>
</paper-card>
</template>
</iron-swipeable-container>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo',
properties : {
items: {
type: Array,
value: function() {
return [1,2,3];
}
}
},
_onSwipe: function(e) {
var card = e.detail.target;
console.log(card.getAttribute('data-index'));
// simpler syntax to get 'data-index'
console.log(card.dataset.index);
}
});
});
</script>
</dom-module>
</body>
codepen

Want to Display message if the array is empty in Polymerjs

Can someone please help how to make this template show if the filter is not found in the array.
<template is="dom-if" if="{{itemsEmpty}}">
The array is empty!
</template>
here is my entire code. but for some reasons the if condition in the dom-if template is not working
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src='bower_components/webcomponentsjs/webcomponents-lite.min.js'></script>
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/iron-image/iron-image.html">
<!--<link rel="import" href="bower_components/iron-ajax/iron-ajax.html">-->
<link rel="import" href="bower_components/paper-item/paper-item.html">
<link rel="import" href="bower_components/paper-input/paper-input.html">
<link rel="import" href="bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="bower_components/paper-listbox/paper-listbox.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<style>
.taller{
height:120px;
}
[vertical-align="top"] ul {
margin-top: 0;
}
[vertical-align="bottom"] ul {
margin-bottom: 0;
}
button, paper-button {
border: 1px solid #ccc;
background-color: #eee;
/*padding: 1em;*/
border-radius: 3px;
cursor: pointer;
}
button:focus {
outline: none;
border-color: blue;
}
</style>
</head>
<body>
<dom-module id="employee-list">
<template>
<paper-input value="{{filterValue}}" label="Search For a Company" floatingLabel id="searchCompany"></paper-input>
<paper-dropdown-menu label="Select Project Type">
<paper-listbox class="dropdown-content" >
<template is="dom-repeat" items="{{items}}" as="test" filter="{{Filter(filterValue:input)}}">
<paper-item value="{{test.fname}}">{{test.fname}} - {{test.lname}}</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu>
<paper-listbox >
<template is="dom-repeat" items="{{items}}" filter="{{Filter(filterValue)}}">
<div class="row">
<div class="col-sm-12" style="font-size:15px;font-family:'Open Sans'">
{{item.fname}} - {{item.lname}}
</div>
<hr />
<template is="dom-if" if="{{itemsEmpty}}">
The array is empty!
</template>
</div>
</template>
</paper-listbox>
</template>
<script>
Polymer({
is: 'employee-list',
properties: {
items: {
type: Array,
observer: '_itemsChanged'
},
filterValue: {
type: String,
notify:true
},
itemsEmpty: {
type: Boolean
}
},
ready: function() {
this.items = [{'fname': 'Jack', 'lname':'Bayo'}, {'fname': 'Skellington','lname':'Dar' }];
},
_itemsChanged: function(items){
this.itemsEmpty = items.length == 0;
},
Filter: function (val) {
return function (items) {
if (!items) return false;
if (val != null || val != undefined) {
return (items.fname && ~items.fname.toLowerCase().indexOf(val.toLowerCase())) ||
(items.lname && ~items.lname.toLowerCase().indexOf(val.toLowerCase()));
}
else
return true;
};
}
});
</script>
</dom-module>
<employee-list></employee-list>
</body>
</html>
I will really appreciate any help here. Here is the plunker: http://plnkr.co/edit/Qy6LeAfe93u4CK2G43eX?p=preview
Thank you
I've found a number of problems with your sample:
The polymer.html import breaks your plunk (see all the errors from registerElement). That's because the other imports try to import Polymer from different URLs
The dom-if is inside the dom-repeat
Observing items won't work because the items property isn't changed when you use filter.
What does change is renderedItemCount property, which you can observe and use to control the dom-if. The property is updated whenever filter fires or items array changes.
To sum up:
Remove Polymer import
Move dom-if outside repeater
Add binding to dom-repeat: rendered-item-count="{{renderedCount}}"
Change the if property to use the actually rendered item count: if="{{!renderedCount}}"
Here's how the element's template can look:
<paper-input value="{{filterValue}}" label="Search For a Company" floatingLabel id="searchCompany"></paper-input>
<paper-listbox >
<template is="dom-repeat" items="{{items}}" filter="{{Filter(filterValue)}}" rendered-item-count="{{renderedCount}}">
<div class="row">
<div class="col-sm-12" style="font-size:15px;font-family:'Open Sans'">
{{item.fname}} - {{item.lname}}
</div>
<hr />
</div>
</template>
<template is="dom-if" if="{{!renderedCount}}">
The array is empty!
</template>
</paper-listbox>
This is untested, but I think.
<template is="dom-if" if="{{!items}}">
should be
<template is="dom-if" if="{{itemsEmpty}}">

How can I "refresh" iron-swipeable-container after a change of data in firebase

My code with swipable-container and dom-repeat of firebase-data
<iron-swipeable-container id="teamchat">
<paper-card class="swipe item blue">
<template is="dom-repeat" items="[[tcmmessages]]" as="tcmmessage">
<div class="card-content">
<b>[[tcmmessage.teamname]]</b><br>
[[tcmmessage.beitrag]]<br>
<span class="chatmetadata">von [[tcmmessage.username]]
• [[tcmmessage.update]] • [[tcmmessage.uptime]] </span>
</div>
</template>
</paper-card>
</iron-swipeable-container>
I have defined a listener
listeners: {
'teamchat.iron-swipe': '_onTeamChatSwipe'
},
and remove the firebase-data with '_onTeamChatSwipe'.
That work fine!
But when there is new firebase-data, how can I bring the iron-swipeable-container back again without refreshing the entire page? I don't find a solution.
It looks like you've created just one paper-card that contains multiple messages. When the card is swiped away, your code has no template to refill the container.
Did you actually mean to create a card for each message? That would require moving paper-card inside the template repeater like this:
<iron-swipeable-container id="teamchat">
<template is="dom-repeat" items="[[tcmmessages]]" as="tcmmessage">
<paper-card class="swipe item blue">
<div class="card-content">
<b>[[tcmmessage.teamname]]</b><br>
[[tcmmessage.beitrag]]<br>
<span class="chatmetadata">von [[tcmmessage.username]]
• [[tcmmessage.update]] • [[tcmmessage.uptime]] </span>
</div>
</paper-card>
</template>
</iron-swipeable-container>
When tcmmessages refills (via Firebase), the iron-swipeable-container automatically repopulates with a paper-card per message.
Here's a demo of similar code that shows that behavior:
<head>
<base href="https://polygit.org/polymer+1.4.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-card/paper-card.html">
<link rel="import" href="iron-swipeable-container/iron-swipeable-container.html">
<link rel="import" href="iron-flex-layout/iron-flex-layout-classes.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<style include="iron-flex">
paper-card {
margin-bottom: 16px;
}
</style>
<template>
<iron-swipeable-container class="container">
<template is="dom-repeat" items="[[items]]">
<paper-card heading="{{item}}" class="layout vertical">
<div class="card-content">
Swipe me left or right
</div>
</paper-card>
</template>
</iron-swipeable-container>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo',
properties : {
items: {
type: Array,
value: function() {
return [1,2,3];
}
}
},
_clearListAfterDelay: function(delay) {
this.async(function() {
this.set('items', []);
}, delay);
},
_refillListAfterDelay: function(delay) {
this.async(function() {
this.push('items', 4);
this.push('items', 5);
}, delay);
},
ready: function() {
this._clearListAfterDelay(1000);
this._refillListAfterDelay(2000);
}
});
});
</script>
</dom-module>
</body>
codepen

access polymer elements attribute, inside of a polymer attribute

I am trying to access the attribute of an polymer element inside of an other polymer element
So, when the flatter-navbar-toggle is clicked I want the flatter-navbar to know so I can change some styling based on the attribute.
<link rel="import" href="../../bower_components/polymer/polymer.html">
<polymer-element name="flatter-navbar-toggle" on-click="{{ toggle }}" attributes="toggled">
<template>
<link rel="stylesheet" href="flatter-navbar-toggle.css"/>
<div>
<span></span>
<span></span>
<span></span>
</div>
</template>
<script>
Polymer('flatter-navbar-toggle', {
toggled: false,
toggle: function () {
this.toggled = this.toggled === true ? false : true;
}
})
</script>
</polymer-element>
<polymer-element name="flatter-navbar">
<template>
<flatter-navbar-toggle id="flatterNavbarToggle">
</flatter-navbar-toggle>
<div id="flatterNavbarBody">
<content>
</content>
</div>
</template>
<script>
Polymer('flatter-navbar', {
toggledChanged: function () {
if (this.$.flatterNavbarToggle.toggled) {
this.$.flatterNavbarBody.style.display = 'block';
} else {
this.$.flatterNavbarBody.style.display = 'none';
}
}
})
</script>
</polymer-element>
You can bind to the flatter-navbar to the flatter-navbar-toggle toggle attribute like this.
<polymer-element name="flatter-navbar" noscript>
<template>
<flatter-navbar-toggle toggled="{{toggled}}"></flatter-navbar-toggle>
<template if="{{toggled}}">
<div><content></content></div>
</template>
</template>
</polymer-element>
jsbin example here http://jsbin.com/pusoj/1