Scroll to bottom automatically using vanilla Javascript/CSS - Polymer - polymer

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

Related

How to set the responsive width of Polymer component inside `<iron-list grid>`

Consider the following code, where <my-item> always has a fixed width of 200px inside <iron-list grid>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Polymer Element Test Case</title>
<!-- Load webcomponents-loader.js to check and load any polyfills your browser needs -->
<script src="bower_components/webcomponentsjs/webcomponents-loader.js"></script>
<link rel="import" href="bower_components/polymer/polymer-element.html">
<link rel="import" href="bower_components/iron-list/iron-list.html">
</head>
<body>
<h1>iron-list-grid-calc-issue</h1>
<!-- Test case HTML goes here -->
<test-case>
</test-case>
<dom-module id="test-case">
<template>
<iron-list items="[[items]]" grid>
<template>
<div>
<!-- value: [[item.n]] -->
<my-item data="[[item]]"></my-item>
</div>
</template>
</iron-list>
</template>
</dom-module>
<dom-module id="my-item">
<template>
<style>
.content {
width: calc(50% - 32px); /* Not working */
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
border: 1px solid grey;
box-sizing: border-box;
}
</style>
<div class="container">
<div class="content">
data: [[data.n]]
</div>
</div>
</template>
</dom-module>
<script>
window.addEventListener('WebComponentsReady', function() {
class TestCase extends Polymer.Element {
static get is() {
return 'test-case';
}
static get properties() {
return {
items: {
type: Array,
value: function() {
let items = [];
for (let i=0; i < 10; i++) {
items.push({
n: i,
});
}
return items;
}
},
};
}
}
class MyItem extends Polymer.Element {
static get is() {
return 'my-item';
}
static get properties() {
return {
data: Object,
};
}
}
window.customElements.define(TestCase.is, TestCase);
window.customElements.define(MyItem.is, MyItem);
});
</script>
</body>
</html>
I intend to make <my-item> responsive by always showing 2 <my-item>s per row (which can be stretched) by setting the width of <my-item> with width: calc(50% - 32px). I noticed CSS calc() doesn't seem to work as expected.
How do I set the responsive width of a Polymer component inside <iron-list grid>?
Set the size of the item template's root container element (<div> in this case).
<iron-list items="[[items]]" grid>
<template>
<div style="width: calc(50% - 32px); height: 200px"> <!-- root container element -->
<my-item data="[[item]]"></my-item>
</div>
</template>
</iron-list>
<head>
<base href="https://polygit.org/polymer+v2.3.1/components/">
<script src="webcomponentsjs/webcomponents-loader.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="iron-list/iron-list.html">
</head>
<body>
<h1>iron-list-grid-calc-issue</h1>
<test-case></test-case>
<dom-module id="test-case">
<template>
<style>
.item {
width: calc(50% - 32px);
height: 200px;
}
</style>
<iron-list items="[[items]]" grid>
<template>
<!-- Set the size of the item template's root container,
which is this `div` element. -->
<div class="item">
<my-item data="[[item]]"></my-item>
</div>
</template>
</iron-list>
</template>
</dom-module>
<dom-module id="my-item">
<template>
<style>
.content {
/* NOTE: The item size is set in the item template
in `iron-list` */
/*width: calc(50% - 32px);*/
/*width: 200px;*/
/*height: 200px;*/
line-height: 200px;
text-align: center;
border: 1px solid grey;
box-sizing: border-box;
}
</style>
<div class="container">
<div class="content">
data: [[data.n]]
</div>
</div>
</template>
</dom-module>
<script>
window.addEventListener('WebComponentsReady', function() {
class TestCase extends Polymer.Element {
static get is() {
return 'test-case';
}
static get properties() {
return {
items: {
type: Array,
value: function() {
let items = [];
for (let i=0; i < 10; i++) {
items.push({
n: i,
});
}
return items;
}
},
};
}
}
class MyItem extends Polymer.Element {
static get is() {
return 'my-item';
}
static get properties() {
return {
data: Object,
};
}
}
window.customElements.define(TestCase.is, TestCase);
window.customElements.define(MyItem.is, MyItem);
});
</script>
</body>
codepen

How to use CSS variable in same rule that declares it

In my custom element's definition, I have the following code:
<dom-module id="dom-element">
<style>
p {
--test: brown;
color: var(--test);
}
</style>
<template>
<p>I'm a DOM element. This is my local DOM!</p>
</template>
<script>
Polymer({
is: "dom-element"
});
</script>
</dom-module>
However, the CSS custom property isn't working. Polymer just turns this:
p {
--test: brown;
color: var(--test);
}
into this:
p {
color: ;
}
But I want the output to be:
p {
color: brown;
}
The demo can be found here: http://plnkr.co/edit/ogMVPKNvc7SYISomWPWm?p=preview
If I don't use Polymer, and create the custom element in pure JavaScript, the CSS custom property works as expected.
I have searched Google, but didn't find something related. What's the problem here? How can I use the CSS custom property with Polymer?
Polymer 1's CSS shim (enabled by default) apparently doesn't handle the CSS variable declaration in the same rule that uses it, so you'd have to move the declaration to :host in this scenario.
<!-- inside dom-module's template -->
<style>
:host {
--test: brown;
}
p {
color: var(--test);
}
</style>
HTMLImports.whenReady(() => {
Polymer({
is: 'x-foo'
});
});
<head>
<base href="https://polygit.org/polymer+1.7.1/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>
:host {
--test: brown;
}
p {
color: var(--test);
}
</style>
<p>Hello world</p>
</template>
</dom-module>
</body>
However, you can enable native CSS properties in Polymer with a global setting (useNativeCSSProperties) declared before importing polymer.html, which would allow your code to work as-is:
<script>window.Polymer = {lazyRegister: true, useNativeCSSProperties: true};</script>
<!-- import polymer.html here -->
HTMLImports.whenReady(() => {
Polymer({
is: 'x-foo'
});
});
<head>
<script>window.Polymer = {dom: 'shadow', lazyRegister: 'max', useNativeCSSProperties: true};</script>
<base href="https://polygit.org/polymer+1.7.1/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>
p {
--test: brown;
color: var(--test);
}
</style>
<p>Hello world</p>
</template>
</dom-module>
</body>
codepen

Polymer 1.x: How to animate custom elements using neon-animation cascaded-animation

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

Polymer: how to handle a style dynamically

Hey i'm trying to create a simple drag and drop. Is that possible to style an element dynamically. My code will be more explicit:
<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="wireframe-view">
<template>
<div on-tap="handleTap"
style$=width:{{ width }}px; background-color:red;
>Hello, World</div>
</template>
<script>
Polymer({
is: "wireframe-view",
handleTap: function() {
this.width = 200;
}
});
</script>
This should change the width in my "style" propertie :/
If the property value contains spaces quotes are required.
style$="width:{{ width }}px; background-color:red";
Here is a method for dynamically updating the style based on the value of a bound data attribute.
<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="conditional-css-example">
<style>
#tapContainer {
width: 100px;
background-color:white;
}
#tapContainer[data-tap-status$="tapped"] {
width: 200px;
background-color:red;
}
</style>
<template>
<div id="tapContainer" data-tap-status$="[[tapStatus]]" on-tap="handleTap">Tap Me!</div>
</template>
<script>
Polymer({
is: "conditional-css-example",
properties: {
tapStatus: String;
},
handleTap: function() {
this.tapStatus='tapped';
}
});
</script>

Polymer Repeat in Template Is Not working

So I have a polymer element, which uses a nested template with repeat attribute. But it doesnt seem to recognize the JSON object being passed in.
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/core-icon/core-icon.html">
<link rel="import" href="bower_components/paper-input/paper-input.html">
<link rel="import" href="bower_components/paper-checkbox/paper-checkbox.html">
<link rel="import" href="bower_components/core-localstorage/core-localstorage.html">
<polymer-element name="to-do">
<template>
<style>
:host {
display: block;
background: white;
height:400px;
width: 300px;
padding: 20px;
}
paper-input {
width: 70%;
margin: 10px;
display: inline-block;
}
core-icon {
margin: 55px 10px 10px 10px;
display: inline-block;
}
paper-checkbox {
display: block;
width: 100%;
}
</style>
<paper-input floatingLabel label="Enter a Task"></paper-input> <core-icon icon="add-circle"></core-icon>
<div class="tasks">
<template repeat="{{item in tasklist}}">
<paper-checkbox label="{{item.itemName}}"></paper-checkbox>
</template>
</div>
<core-localstorage name="tasks" value="{{tasklist}}"></core-localstorage>
</template>
<script>
Polymer('to-do', {
tasklist: [
{
itemName : "Study",
isDone : true
},
{
itemName : "Cook Dinner",
isDone : false
}
],
ready: function() {
console.log(this.tasklist);
},
addObject: function() {
}
});
</script>
</polymer-element>
It doesnt seem to get tasklist from the script block in the nested template block, but prints it out in the ready block.
You Can see a running demo of the above code here
https://to-do-prateekjadhwani.c9.io/demo.html
Thanks
*****EDIT****
Since, it was using localstorage, it was using data in tasklist from LocalStorage rather than updating itself with the code iteration.
So, I believe that this issue is resolved. But feel free to add comment(s) if you think that my reasoning isn't correct.
Thanks in advance.
Since, it was using localstorage, it was using data in tasklist from LocalStorage rather than updating itself with the code iteration. So, I believe that this issue is resolved.