PassingData using app route in polymer - polymer

I would like to pass the id of the selected grid using app-router. Somehow I seem to be missing a link. I want to be able to pass the id of the selected row from the grid and use that value in the iron-ajax url http://192.168.178.31:8080/demo/questions?assessmentId=TEST in place if assessmentId.
my-data.html
<dom-module id="my-data">
<template>
<style include="shared-styles">
:host {
display: block;
padding: 10px;
}
.title {
margin-left: 40%;
}
.card {
height: 100%;
}
</style>
<div class="card">
<div class="title">ASSESSMENTS</div>
<!-- Fetch an array of users to be shown in the grid -->
<vaadin-grid id="material" items="{{assessments}}" selected-items={{selectedItems}} active-item="{{selectedItem}}">
<vaadin-grid-selection-column auto-select frozen>
</vaadin-grid-selection-column>
<vaadin-grid-column>
<template class="header">Assessment Id</template>
<template>[[item.assessmentId]]</template>
</vaadin-grid-column>
<vaadin-grid-column>
<template class="header">Assessment Topic</template>
<template>[[item.assessmentTopic]]</template>
</vaadin-grid-column>
<vaadin-grid-column>
<template class="header">Assessment Subtopic</template>
<template>[[item.assessmentSubtopic]]</template>
</vaadin-grid-column>
<vaadin-grid-column>
<template class="header">Created By</template>
<template>[[item.createdBy]]</template>
</vaadin-grid-column>
<vaadin-grid-column>
<template class="header">Rating</template>
<template>[[item.rating]]</template>
</vaadin-grid-column>
</vaadin-grid>
<app-location route="{{route}}" url-space-regex="^[[rootPath]]">
</app-location>
<app-route route="{{route}}"
pattern="[[rootPath]]:page"
data="{{routeData}}"
tail="{{subroute}}">
</app-route>
<iron-selector selected="[[page]]" attr-for-selected="name" class="drawer-list" role="navigation">
<a name="assessment" href="[[rootPath]]assessment">Quiz Page</a>
</iron-selector>
</div>
</template>
<script>
class MyData extends Polymer.Element {
static get is() { return 'my-data'; }
static get properties() {
return {
index: {
type: Number,
value: 0
},
assessments: {
type: Array,
observer: 'isAssessmentLoaded'
},
selectedItem: {
type: Array,
},
selectedItems: {
type: Array,
},
page: {
type: String,
reflectToAttribute: true,
observer: '_pageChanged',
},
routeData: Object,
subroute: String,
// This shouldn't be neccessary, but the Analyzer isn't picking up
// Polymer.Element#rootPath
rootPath: String,
};
}
constructor() {
super();
}
_selectedItemsChanged(selectedItem, selectedItems) {
console.log(selectedItems);
this.selectedItem = selectedItem;
}
isAssessmentLoaded(q) {
if (q) {
console.log('loaded questions', q); // questions are loaded.
}
}
redirect() {
page('/')
}
static get observers() {
return [
//'_routePageChanged(routeData.page)',
'_selectedItemsChanged(selectedItem, selectedItems)'
];
}
// _routePageChanged(page) {
// // If no page was found in the route data, page will be an empty string.
// // Default to 'assessments' in that case.
// this.page = page | 'assessment';
// // Close a non-persistent drawer when the page & route are changed.
// // if (!this.$.drawer.persistent) {
// // this.$.drawer.close();
// // }
// }
// _pageChanged(page) {
// // Load page import on demand. Show 404 page if fails
// var resolvedPageUrl = this.resolveUrl('my-' + page + '.html');
// Polymer.importHref(
// resolvedPageUrl,
// null,
// this._showPage404.bind(this),
// true);
// }
_showPage404() {
this.page = 'view404';
}
}
window.customElements.define(MyData.is, MyData);
</script>
</dom-module>
my-assessment.html
<dom-module id="my-assessment">
<template>
<style include="shared-styles">
:host {
display: block;
padding: 10px;
}
</style>
<!--Check the url is correct ! And last responce property should be {{}} instead [[]] (as up way data binding) -->
<iron-ajax
id="requestRepos"
url="http://192.168.178.31:8080/demo/questions?assessmentId=TEST"
handle-as="json"
last-response="{{repos}}">
</iron-ajax>
<template is="dom-if" if="{{repos}}">
<my-quiz repos= "{{repos}}"></my-quiz>
</template>
</template>
<script>
class Assessment extends Polymer.Element {
static get is() { return 'my-assessment'; }
constructor() {
super();
}
ready() {
super.ready();
this.$.requestRepos.generateRequest();
}
}
window.customElements.define(Assessment.is, Assessment);
</script>
</dom-module>

Here is how to change the route by clicking on the link:
<app-location
route="{{route}}"
use-hash-as-path="">
</app-location>
<app-route
route="{{route}}"
pattern="/:page"
data="{{routeData}}"
tail="{{subroute}}">
</app-route>
<a name="some_name" href="#/some_route">Change route</a>

Related

Polymer2 hybrid update error: 'Uncaught TypeError: Class extends value undefined is not a constructor or null'

Problem
I have started upgrading my polymer PWA to version 2.0 of polymer. There is a suggestion in docs to upgrade the big project to polymer 1.8 version and elements to 2.0 hybrid style. I am doing the same but i got following error
Uncaught TypeError: Class extends value undefined is not a constructor or null
can someone help me solve this please,Also i don't get what's meant by hybrid style of element whether it's 2.0 or something else?
Thanks in advance.
My element (updated)
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/paper-material/paper-material.html">
<dom-module id="account-analytics">
<template>
<style >
.flex{
display: flex;
width: 100%;
align-items: center;
}
.flexChild{
flex-grow: 1;
text-align: center;
flex-basis: 40px;
}
</style>
<iron-ajax auto
id="accountAnalytics"
url="/napi/accountanalytics"
handle-as="json"
last-response="{{analytics}}"
loading="{{analyticsLoading}}"
debounce-duration="1000">
</iron-ajax>
<div style="font-size: 25px;font-weight: bold;display: none;padding-top: 2%;padding-left: 2%;padding-bottom: 2%" id="analyticsHead">eGlu Today</div>
<div class="flex">
<div class="flexChild"><b>Rules</b></div>
<div class="flexChild"><b>Scenes</b></div>
<div class="flexChild"> <i class="material-icons">linked_camera</i></div>
<div class="flexChild"><i class="material-icons">android</i></div>
<div class="flexChild"><img src="../../images/apple_logo_200px.jpeg" style="width: 30px;padding-bottom: 5px"></div>
</div>
<div class="flex">
<div class="flexChild">{{analytics.ruleCount}}</div>
<div class="flexChild">{{analytics.sceneCount}}</div>
<div class="flexChild">{{analytics.cameraCount}}</div>
<div class="flexChild">{{analytics.androidInstallations}}</div>
<div class="flexChild">{{analytics.iosInstallations}}</div>
</div>
</template>
</dom-module>
<script>
class accountAnalytics extends Polymer.Element{
static get is(){return 'account-analytics';}
static get properties(){
return{
hubId: {
type: String,
value: '7e-f2-ca-ab-40-34-34-95',
notify: true
},
analyticsLoading:{
type:Boolean,
notify:true
},
analytics:Object,
customerId:{
type:String,
value:'',
observer:'emailChanged'
},
integratorOptions:Boolean,
refreshCustomer:{
type:Boolean,
value:false,
notify:true,
observer:'_refreshCustomer'
}
};
}
constructor() {
super();
}
emailChanged() {
if(this.customerId=='')
this.$.analyticsHead.style.display='block';
this.fireAnalytics();
}
_refreshCustomer() {
this.fireAnalytics();
this.refreshCustomer=false;
}
ready(){
super.ready();
this.fireAnalytics();
}
fireAnalytics(){
if(this.customerId==undefined)
return;
var t= Date.now();
var p = this.getCookie('token');
this.$.accountAnalytics.headers={"token":p};
this.$.accountAnalytics.params={"customerId":this.customerId,"t":t};
// this.$.accountAnalytics.generateRequest();
}
getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
}
customElements.define(accountAnalytics.is, accountAnalytics);
</script>

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}}">

Polymer: Bind custom-element's data to main document

I have create a custom element to show chat list as follows:
<dom-module id="contact-element">
<style>
--paper-card: {
width: 100%;
}
.edit{
display: block;
}
.last{
color: #A7A7A7;
font-size: 14px;
margin-top: 4px;
}
</style>
<template>
<template is="dom-repeat" items="{{contacts}}">
<div>
<paper-card class="contactcard" on-click="setUser">
<div class="card-content">
<div>{{ item.name }}</div>
<div class="last">{{ item.last }}</div>
</div>
</paper-card>
</div>
</template>
</template>
<script>
HTMLImports.whenReady(function () {
Polymer({
is: 'contact-element',
properties: {
user: {
type: Object,
},
username: {
type: String,
reflectToAttribute: true,
}
},
ready: function(){
this.contacts = [
{name: "Rajat",last: "How are you!", unread: 1},
{name: "Neeraj",last: "Okay", unread: 0},
{name: "Vaibhav"},
{name: "Rohit"},
{name: "Hitesh"},
];
},
setUser: function(e){
var model = e.model;
this.user = model.get('item');
this.username = this.user.name;
console.log("user set: "+model.get('item.name'));
}
});
});
</script>
</dom-module>
And I want that when a user clicks on any of the object, the toolbar should get the name. For that I'm using:
<paper-toolbar>
<paper-icon-button icon="menu" paper-drawer-toggle paper-drawer-left></paper-icon-button>
<span class="flex"></span>
<!-- Title -->
<div class="app-name flex">[[ pagetitle ]]</div>
<paper-icon-button icon="add-alert"></paper-icon-button>
<paper-icon-button icon="question-answer" paper-drawer-toggle paper-drawer-right></paper-icon-button>
</paper-toolbar>
But it's not working. Any help?
I solve this by putting notify='true' into the script tag like this:
properties: {
user: {
type: Object,
notify: true
},
username: {
type: String,
reflectToAttribute: true,
}
},
Notify lets the data change event bounce up, to the element housing our custom element.

polymer 1.0 dom-repeat filter only runs once

When I change the year using the drop-down, I want the list to re-filter and display the info for that chosen year. What am I missing? Changing the year does not re-filter the dom-repeat.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<base href="http://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<title>dropdown</title>
<link rel="import" href="http://polygit.org/components/paper-menu/paper-menu.html">
<link rel="import" href="http://polygit.org/components/paper-item/paper-item.html">
<link rel="import" href="http://polygit.org/components/paper-button/paper-button.html">
<link rel="import" href="http://polygit.org/components/paper-menu-button/paper-menu-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="x-demo">
<template>
<div class="horizontal-section flex layout horizontal taller">
<paper-menu-button>
<paper-button icon="menu" class="dropdown-trigger"><span>Year<br/></span><span>{{year}}</span></paper-button>
<paper-menu id="selectedYear" class="dropdown-content" selected="{{selectedIndex}}">
<template is="dom-repeat" items="{{allData}}">
<paper-item on-tap='yearTapped'>{{item.year}}</paper-item>
</template>
</paper-menu>
</paper-menu-button>
<paper-menu-button>
<paper-button icon="menu" class="dropdown-trigger"><span>Make<br/></span><span>{{make}}</span></paper-button>
<paper-menu id="selectedMake" class="dropdown-content" selected="{{selectedIndex}}">
<template is="dom-repeat" items="{{allData}}">
<paper-item on-tap='makeTapped'>{{item.make}}</paper-item>
</template>
</paper-menu>
</paper-menu-button>
<paper-menu-button>
<paper-button icon="menu" class="dropdown-trigger"><span>Model<br/></span><span>{{model}}</span></paper-button>
<paper-menu id="selectedModel" class="dropdown-content" selected="{{selectedIndex}}">
<template is="dom-repeat" items="{{allData}}">
<paper-item on-tap='modelTapped'>{{item.model}}</paper-item>
</template>
</paper-menu>
</paper-menu-button>
<paper-menu-button>
<paper-button icon="menu" class="dropdown-trigger"><span>Engine<br/></span><span>{{engine}}</span></paper-button>
<paper-menu id="selectedEngine" class="dropdown-content" selected="{{selectedIndex}}">
<template is="dom-repeat" items="{{allData}}">
<paper-item on-tap='engineTapped'>{{item.engine}}</paper-item>
</template>
</paper-menu>
</paper-menu-button>
</div>
<div>Vehicle list filtered by selected year: </div>
<template is="dom-repeat" id="vehicleList" items="{{allData}}" filter="yearMatch" observe="year item.year">
<div>Year <span>{{item.year}}</span></div>
<div>Make <span>{{item.make}}</span></div>
<div>Model <span>{{item.model}}</span></div>
<div>Engine <span>{{item.engine}}</span></div>
<button on-click="toggleSelection">Select</button>
</template>
<array-selector id="selector" items="{{allData}}" selected="{{selected}}" multi toggle></array-selector>
<div>Selected vehicle: </div>
<template is="dom-repeat" items="{{selected}}">
<div><span>{{item.year}}</span></div>
<div><span>{{item.make}}</span></div>
<div><span>{{item.model}}</span></div>
<div><span>{{item.engine}}</span></div>
</template>
</template>
<script>
Polymer({
is: 'x-demo',
properties:{
allData:{type:Array,
value: function() {
return [{year:'2015',make:'HONDA',model:'CB300F',engine:'300cc'},
{year:'2014',make:'HONDA',model:'CBR300R',engine:'300cc'}];
}
},
year:{type:String,value:'2014',notify:true}
},
observers: [
'yearChanged(year)'
],
yearChanged: function(item) {
console.log(item);
this.set('item.year', item);
this.$.vehicleList.render();
},
yearMatch: function(item) {
console.log('year checked');
return item.year = this.year;
},
toggleSelection: function(e) {
var item = this.$.vehicleList.itemForElement(e.target);
this.$.selector.select(item);
},
yearTapped: function(e) {
this.year=e.target.innerText;
},
makeTapped: function(e) {
this.make=e.target.innerText;
},
modelTapped: function(e) {
this.model=e.target.innerText;
},
engineTapped: function(e) {
this.engine=e.target.innerText;
}
});
</script>
</dom-module>
<x-demo></x-demo>
</body>
</html>
this works for me
<script>
HTMLImports.whenReady(function () {
Polymer({
is: 'x-demo',
properties:{
allData:{
type:Array,
value: [{
year:'2015',
make:'HONDA',
model:'CB300F',
engine:'300cc'
}, {
year:'2014',
make:'HONDA',
model:'CBR300R',
engine:'300cc'
}]
},
year:{
type:
String,
value:'2014',
observer: 'yearChanged'
}
},
yearChanged: function() {
console.log(this.year)
this.$.vehicleList.render();
},
yearMatch: function(item) {
return item.year == this.year;
},
toggleSelection: function(e) {
var item = this.$.vehicleList.itemForElement(e.target);
this.$.selector.select(item);
},
yearTapped: function(event) {
var res = event.target.innerText || event.target.textContent;
this.year = res.replace(/\s+/g, '');
},
makeTapped: function(event) {
var res = event.target.innerText || event.target.textContent;
this.make = res.replace(/\s+/g, '');
},
modelTapped: function(event) {
var res = event.target.innerText || event.target.textContent;
this.model = res.replace(/\s+/g, '');
},
engineTapped: function(event) {
var res = event.target.innerText || event.target.textContent;
this.engine = res.replace(/\s+/g, '');
}
});
});