I have two polymer elements which have similar characteristics. I'm trying to "merge" those two to one element. What I see in the documentation is that custom elements can not be inherited in polymer 1.0.
It starts here:
<div title="{{tile.description}}" class="flex-item">
<template is='dom-if' if='{{typeIsSingle}}'>
<single-item-tile tile='{{tile}}'></single-item-tile>
</template>
<template is='dom-if' if='{{typeIsGrouped}}'>
<multiple-items-tile tile='{{tile}}'></multiple-items-tile>
</template>
...
And here are the two very similar elements:
<dom-module id="single-item-tile">
<style>
.big {
--iron-icon-width: 96px;
--iron-icon-height: 96px;
}
</style>
<template>
<paper-button on-click="navigateTo">
<iron-icon class="big" icon="{{icon}}"></iron-icon>
<h4>{{tile.label}}</h4>
</paper-button>
</template>
<script>
Polymer({
is: 'single-item-tile',
properties: {
label: String,
icon: {
type: String,
value: "check-box-outline-blank"
},
tile: Object
},
navigateTo: function () {
window.open(this.tile.url + "?id=" + this.tile.landingPageQuestionnaireItems[0].id);
}
});
</script>
</dom-module>
And:
<dom-module id="multiple-items-tile">
<style>
.big {
--iron-icon-width: 96px;
--iron-icon-height: 96px;
}
paper-dialog.size-position {
position: relative;
top: -180px;
left: 20px;
min-width: 200px;
min-height: 150px;
background: #fff;
}
.questionnaireItemToChoose:hover {
background-color: #e3e3e3;
}
</style>
<template>
<paper-button on-click="showGroupedItems">
<iron-icon class="big" icon="{{icon}}"></iron-icon>
<h4>{{tile.label}}</h4>
</paper-button>
<paper-dialog id="questionnaire-selector" class="big size-position" heading="Questionnaires" >
<iron-selector>
<template is='dom-repeat' items='{{tile.landingPageQuestionnaireItems}}'>
<div id="{{item.id}}" class="questionnaireItemToChoose" on-click="handleClick">{{item.label}}</div>
</template>
</iron-selector>
</paper-dialog>
</template>
<script>
Polymer({
is: 'multiple-items-tile',
properties: {
label: String,
icon: {
type: String,
value: "content-copy"
},
tile: Object
},
showGroupedItems: function (e) {
var dialog = document.getElementById('questionnaire-selector');
if (dialog) {
dialog.open();
}
},
handleClick: function(e) {
var dialog = document.getElementById('questionnaire-selector');
dialog.close();
window.open(this.tile.url + "?id=" + e.currentTarget.id);
}
});
</script>
</dom-module>
The current workaround for the lack of inheritance in Polymer 1.0 are shared behaviors.
You can try to extract the common behavior of both custom elements into a separate behavior which you implement in both of your custom elements:
tile-behavior.html:
<script>
TiteBehavior = {
properties: {
label: String,
icon: {
type: String,
value: "content-copy"
},
tile: Object
},
commonFunction: function() { },
....
};
</script>
<dom-module id="multiple-items-tile">
...
<script>
Polymer({
is: 'multiple-items-tile',
behaviors: [TileBehavior],
});
</script>
</dom-mdoule>
<dom-module id="single-item-tile">
...
<script>
Polymer({
is: 'single-item-tile',
behaviors: [TileBehavior],
});
</script>
</dom-mdoule>
Related
I don't want to use JQuery to do this. Currently, I've created a listview using Polymer. I'm using <template is="dom-repeat"> inside a parent div with a class of list.
The CSS is as follows. As I add new items to the list, I would like the list to scroll to the bottom automatically. Is that possible?
.list {
#apply(--layout-flex);
#apply(--layout-vertical);
position: relative;
overflow: auto;
}
You can set the div's scrollTop to scrollHeight in order to automatically scroll to the bottom:
HTMLImports.whenReady(() => {
Polymer({
is: 'x-foo',
properties: {
items: {
type: Array,
value: () => []
}
},
_addItem: function() {
this.push('items', this.items.length+1);
Polymer.RenderStatus.afterNextRender(this, () => {
this.$.list.scrollTop = this.$.list.scrollHeight;
});
}
});
});
<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">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<style>
#list {
border: solid 1px gray;
width: 100%;
height: 100px;
overflow: auto;
}
</style>
<button on-tap="_addItem">Add item</button>
<div id="list">
<template is="dom-repeat" items="[[items]]">
<div>[[item]]</div>
</template>
</div>
</template>
</dom-module>
</body>
codepen
This plunk demonstrates the behavior I am trying to achieve.
This plunk demonstrates my problem. Which is that the individual <li items do not perform their cascaded-animation behavior. All I did was to substitute a custom element I called <content-el> in the repeater and change the appropriate node definitions.
Please answer by providing a working plunk that animates the individual <content-el> nodes.
http://plnkr.co/edit/ZzG4lDvl4V32Bod36208?p=preview
<link href="content-el.html" rel="import">
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<link rel="import" href="app-layout/app-grid/app-grid-style.html">
<link rel="import" href="neon-animation/neon-animation.html">
<link rel="import" href="paper-card/paper-card.html">
<dom-module id="x-app">
<template>
<style include="app-grid-style">
:host {
display: block;
--app-grid-columns: 2;
--app-grid-gutter: 10px;
--paper-icon-button-ink-color: white;
}
.item {
height: 250px;
position: relative;
background-color: white;
background-size: cover;
background-position: center center;
}
</style>
<button on-tap="play">Play Animation</button>
<div class="centered-container">
<ul class="app-grid">
<template id="items"
is="dom-repeat"
items="[1,2,3,4,5,6]"
>
<li class="item"
style="background-image: url(http://fakeimg.pl/800x800/0079D8/fff/?text=[[item]]);"
>
</li>
</template>
</ul>
</div>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'x-app',
behaviors: [
Polymer.NeonAnimationRunnerBehavior,
],
properties: {
animationConfig: {
type: Object,
value: function() {
return {
'entry': [
{
name: 'slide-from-right-animation',
node: this,
}, {
name: 'cascaded-animation',
animation: 'scale-up-animation',
timing: {
delay: 500,
},
},
],
};
},
},
},
attached: function() {
this.async(function() {
var nodeList = Polymer.dom(this.root).querySelectorAll('li.item');
this.animationConfig['entry'][1].nodes = Array.prototype.slice.call(nodeList);
//console.log(this.animationConfig['entry'][1].nodes);
this.playAnimation('entry');
}.bind(this), 500); // https://github.com/Polymer/polymer/issues/2500
},
play: function() {
this.playAnimation('entry');
},
});
})();
</script>
</dom-module>
<dom-module id="content-el">
<template>
<style>
:host {
box-sizing: border-box;
display: block;
}
</style>
http://plnkr.co/edit/2bijfuGjC7NjIAPhMIj4?p=preview
I'm assigning a string that contains anchor tags to an element's innerHTML. I need to style these, however, I am not sure how to do so. Here's an example using Polymer.dom and updateStyles as suggested by this StackOverflow post:
Polymer({
is: 'x-foo',
properties: {
value: {
type: String,
value: 'Hello',
observer: 'setValue'
}
},
setValue: function() {
Polymer.dom(this).innerHTML = this.value;
this.updateStyles();
}
});
<base href="https://polygit.org/polymer+:1.4.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<dom-module id="x-foo">
<style>
a {
color: red;
}
</style>
<template>
<content></content>
</template>
</dom-module>
<x-foo></x-foo>
And here's a link to the jsfiddle:
https://jsfiddle.net/cbelden/xamfhe52/
You don't need to call updateStyles(). Your dom-module style should be using ::content to target the distributed nodes:
<style>
::content a {
color: red;
}
</style>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo',
properties: {
value: {
type: String,
value: 'Hello',
observer: 'setValue'
}
},
setValue: function() {
Polymer.dom(this).innerHTML = this.value;
//this.updateStyles(); // not needed
}
});
});
<base href="https://polygit.org/polymer+:1.4.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<dom-module id="x-foo">
<style>
::content a {
color: red;
}
</style>
<template>
<content></content>
</template>
</dom-module>
<x-foo></x-foo>
I've this Polymer Component:
<dom-module id="visu-conveyor">
<template>
<div id='conveyor' style="background: lightblue; height: 100%; width: 100%">
{{objectName}}
<div style="width: 80px; height: 90%; background-image: url(images/rollers_horizontal.png); background-repeat: repeat;">
<div style="width: 10px; height: 10px; background: blue;" data-bind="visible: A_B_A"></div>
</div>
</div>
</template>
<script>
Polymer({
is: "visu-conveyor",
properties: {
objectName: String
},
ready: function () {
var self = this;
var viewport = self.$.conveyor;
ko.applyBindings(visuClient_Tags, self.$.viewport);
}
});
</script>
</dom-module>
When I use this multiple times, I got this error! But I think the Element to which I apply the Binding is every time another one (A instance of the temple)? Or I'm wrong?
Was a typo error!
my code should look like this:
<script>
Polymer({
is: "visu-conveyor",
properties: {
objectName: String
},
ready: function () {
var self = this;
ko.applyBindings(visuClient_Tags, self.$.conveyor);
}
});
</script>
I want to create a custom element that takes a JSON object as input.
<activity-tracker activity='{"title": "Lord Meowser", "description": "lala"}'></activity-tracker>
The element itself looks like this
<dom-module id="activity-tracker">
<style>
:host {
display: block;
box-sizing: border-box;
}
</style>
<template>
<p>{{activity}}</p>
<p>{{activity.title}}</p>
</template>
</dom-module>
And the property binding
properties: {
activity: {
title: {
type:String,
value: '...'
},
description:{
type:String,
value: '...'
}
}
},
<p>{{activity}}</p> results in {"title": "Lord Meowser", "description": "lala"}
<p>{{activity.title}}</p> is empty
How can I map it? And how should I handle if user inserts something else, lets say activity="notanobject". Currently, defined internal object is just overwritten and the string is shown.
<dom-module id="activity-tracker">
<style>
:host {
display: block;
box-sizing: border-box;
}
</style>
<template>
<p>{{variable}}</p><!-- this shows [object Object]-->
<p>{{variable.title}}</p> <!-- this shows Lord Meowser-->
<p>{{variable.description}}</p> <!-- this shows lalala-->
</template>
<script>
Polymer({
is:"activity-tracker",
properties:{
variable:{
type:Object,
value: function(){return {};}
}
}
});
</script>
</dom-module>
<activity-tracker variable='{"title": "Lord Meowser", "description": "lala"}'></activity-tracker>
This should work.