Polymer neon-animation: Element is remains visible after animating - polymer-1.0

I downloaded the Polymer Starter Kit and am trying to animate an paper-element like so
<section data-route="contact">
<button on-click="_onButtonClick">Toggle</button>
<my-dialog>
<paper-material elevation="1">
<h2 class="page-title">Contact</h2>
<p>This is the contact section</p>
</paper-material>
</my-dialog>
</section>
my-dialog.html as follows:
<dom-module id="my-dialog">
<template>
<content></content>
</template>
</dom-module>
<script>
Polymer({
is: 'my-dialog',
behaviors: [
Polymer.NeonAnimationRunnerBehavior
],
properties: {
opened: {
type: Boolean
},
animationConfig: {
type: Object,
value: function() {
return {
'entry': [{
name: 'slide-left-animation',
node: this
}],
'exit': [{
name: 'fade-out-animation',
node: this
}]
}
}
}
},
listeners: {
'neon-animation-finish': '_onAnimationFinish'
},
_onAnimationFinish: function() {
if (!this.opened) {
this.style.display = '';
}
},
show: function() {
this.opened = true;
this.style.display = 'inline-block';
this.playAnimation('entry');
},
hide: function() {
this.opened = false;
this.playAnimation('exit');
}
});
</script>
The problem I'm facing is that after toggling the animation, my paper-element is squished and remains visible on screen. How do I make it not visible after animation? I've tried hardcoding <paper-material hidden?=true> but that also does not hide the element.

As commented, you simply need to change this.style.display = 'none';

Related

Angular JS Bootstrap UI Modal for Dynamic Images

I tried following this example How to zoom image with angularJS This is getting images from a JSON website and has two different picture links for each {}. I'm trying to enlarge thumbnail images that are obtained from my model by clicking the picture and opening a modal. How do I tie the modal to my click on the image and pass in the image and the caption? Incidentally now when the modal opens, it's empty and it's a tiny width. It would need to be at least 600X600.
"use strict";
var app = angular.module('myApp', ['ngResource','ui.bootstrap']);
app.run(function($templateCache){
$templateCache.put('modal.html', '<div><a ng-click="$close(true)" class="pull-right">&times close</a><img ng-src="{{vm.options.imageList.images}}"/></div>');
});
app.controller("MainController", ['$scope','$uibModal','$resource', function($scope,$uibModal,$resource) {
var vm = this;
$scope.showModal = function(imageName) {
$scope.ImageName = "vm.imageList.image" +imageName;
var uibModalInstance = $uibModal.open({
animation: true,
scope:$scope,
templateUrl: 'modal.html'
});
};
vm.selectCategory=selectCategory;
vm.options = {
imageList:[
{
images: 'images/IMG_0321.JPG',
caption: 'cuddly',
category: 'lake'
},
{
images: 'images/IMG_0050.JPG',
caption: 'sleepy',
category: 'lake'
},
{
images: 'images/IMG_0055.JPG',
caption: 'sleepy',
category: 'lake',
},
{
images: 'images/IMG_0056.JPG',
caption: 'cuddly',
category: 'lake'
},
{
images: 'images/IMG_0059.JPG',
caption: 'cuddly',
category: 'lake'
}
],
};
function selectCategory(pos) {
vm.selectedCategory = pos;
};
}]);
HTML
<div class = "row">
<div class = "col-md-12">
<div ng-repeat = "image in vm.options.imageList | filter: {category: vm.selectedCategory}">
<img class = "thumbnail" ng-src="{{image.images}}" hspace ="15" vspace ="10" ng-click="showModal()">
You are not passing the image in your showModal function.
This would be the workaround.
<div class = "row">
<div class = "col-md-12">
<div ng-repeat = "image in vm.options.imageList | filter: {category: vm.selectedCategory}">
<img class="thumbnail" ng-src="{{image.images}}" hspace ="15" vspace ="10" ng-click="showModal(image.images)">
</div>
</div>
</div>
In your modal.html:
$templateCache.put('modal.html', '<div><a ng-click="$close(true)" class="pull-right">&times close</a><img style="max-width:100%; min-height: 600px;" ng-src="{{imageName}}"/></div>');
And the controller:
$scope.showModal = function(imageName) {
var uibModalInstance = $uibModal.open({
animation: true,
templateUrl: 'modal.html',
controller: function($scope){
$scope.imageName = imageName;
},
size: 'lg'
});
};

Polymer 1.0 Problems with dom-repeat

I hope someone could help me. I'm really frustrated. :-( I can't figure out how to use the new dom-repeat template with polymer 1.0.
I want to show same items from firebase in a custom-element-list, but if I load the items from firebase, my custom-element-list doesn't fill with the items.
Please see the Code. BIG THANKS in the meantime.
Custom Element: my-uebersicht
<dom-module id="my-uebersicht">
<style>
:host {
display: block;
}
#fabTest {
position: absolute !important;
right: 10px;
top: 10px;
}
</style>
<template>
<h1 class="paper-font-display1"><span>Übersicht</span></h1>
<my-zeiteintrag-list zeiteintraege="{{zeiteintraege}}"></my-zeiteintrag-list>
<paper-fab id="fabTest" mini icon="polymer" on-click="loadUebersicht"></paper-fab>
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'my-uebersicht',
routeTo: function(route) {
document.querySelector('#app').route = route;
},
loadUebersicht: function() {
var id = document.querySelector('#app').getUserId();
var uname = document.querySelector('#app').getUsername();
if ((typeof id === 'undefined') || (typeof uname === 'undefined')) {
this.routeTo('login');
}
var that = this;
var rootRef = new Firebase("https://<FIREBASE.com>/" + id);
rootRef.on("value", function(snapshot) {
snapshot.forEach(function(child) {
var zeintrag = child.val();
that.zeiteintraege.push(zeintrag);
});
});
},
ready: function() {
this.zeiteintraege = [];
}
})
})();
</script>
Custom Element: my-zeiteintrag-list
<dom-module id="my-zeiteintrag-list">
<style>
:host {
display: block;
}
</style>
<template>
<template is="dom-repeat" items="{{zeiteintraege}}">
<my-zeiteintrag-item zeiteintrag="{{item}}"></my-zeiteintrag-item>
</template>
</template>
</dom-module>
<script>
(function () {
Polymer({
is: 'my-zeiteintrag-list',
properties: {
zeiteintraege: {
type: Array,
value: [],
notify: true,
reflectToAttribute: true
}
},
ready: function() {
this.zeiteintraege = this.zeiteintraege || [];
}
});
})();
</script>
Custom Element: my-zeiteintrag-item
<dom-module id="my-zeiteintrag-item">
<style>
:host {
display: block;
}
</style>
<template>
<paper-material elevation="1">
<ul>
<li>Projekt: <span class="paper-font-body1">{{zeiteintrag.projekt}}</span></li>
<li>Vorgang: <span class="paper-font-body1">{{zeiteintrag.vorgang}}</span></li>
<li>Artikel: <span class="paper-font-body1">{{zeiteintrag.artikel}}</span></li>
<li>Datum: <span class="paper-font-body1">{{zeiteintrag.datum}}</span></li>
<li>Dauer: <span class="paper-font-body1">{{zeiteintrag.dauer}}</span></li>
<li>Bemerkung: <span class="paper-font-body1">{{zeiteintrag.bemerkung}}</span></li>
</ul>
</paper-material>
</template>
</dom-module>
<script>
(function () {
Polymer({
is: 'my-zeiteintrag-item',
properties: {
zeiteintrag: {
type: Object,
value: {},
notify: true,
reflectToAttribute: true
}
},
ready: function() {
this.zeiteintrag = this.zeiteintrag || {};
}
});
})();
</script>
[EDIT] - found a solution
After pointing to a Polymer Github Issue about dom-repeat at the Polymer Slack Chat Github Issue and read the Documentation again. You must use the Polymer methods (push, pop, splice, shift, unshift) for Arrays to trigger an update.
Here is the working solution:
Custom Element: my-uebersicht
<script>
(function() {
Polymer({
is: 'my-uebersicht',
routeTo: function(route) {
document.querySelector('#app').route = route;
},
loadUebersicht: function() {
var id = document.querySelector('#app').getUserId();
var uname = document.querySelector('#app').getUsername();
if ((typeof id === 'undefined') || (typeof uname === 'undefined')) {
this.routeTo('login');
}
var that = this;
var rootRef = new Firebase('https://<FIREBASE>.com/erfassung/' + id);
rootRef.on('value', function(snapshot) {
that.zeiteintraege = [];
snapshot.forEach(function(child) {
var zeintrag = child.val();
that.push('zeiteintraege', zeintrag); //THIS IS ALL!!!
});
});
},
ready: function() {
this.zeiteintraege = [];
}
});
})();
</script>
Not sure whether you are looking for something similar:
<dom-module id="my-zeiteintrag-list">
<template>
<template is="dom-repeat" items="zeiteintraglist">
<div>
<span>{{item.name}}</span><br />
<span>{{item.country}}</span>, <span>{{item.phone}}</span>.<br />
<span><a href$="{{generateEmailLink(item.email)}}"><span>{{item.email}}</span></a></span>
</div>
</template>
</template>
</dom-module>
<!--Script section starts -->
<script>
(function () {
Polymer({
// define element prototype here
is: 'my-zeiteintrag-list',
generateEmailLink: function(value) {
//Computed property, since 1.0 does not allow string concatenation
return "mailto:" + value;
},
ready: function () {
this.zeiteintraglist = [
{ "name": "John Doe", "country": "USA", "phone": "1 202 303 4567", "email": "jhondoe#sample.com"},
{ "name": "Sara O'coner", "country": "USA", "phone": "1 202 303 4567", "email": "sara#sample.com"}
];
}
});
})();
</script>
I'm glad to see you found the solution. I'd like to touch base on the why a little bit. Polymer data binding is built on events for efficiency. When a value is mutated or replaced, Polymer sends events to components that are bound to that data, and they update. Mutating the array directly does not fire these events, because arrays aren't aware of polymer. Hence, polymer provides it's own version of push, pop, shift, unshift, and splice, because these versions fire the correct event before updating the array.
It's important to keep this in mind with data binding in polymer in general. If you have an object, and you modify properties on that object outside of polymer (so not using things like this.set), you will have to manually notify Polymer of the path that updated so that templates rendered off of that object can know to update.

How to parse model data in the view onto a javascript function in Angular

Assuming I have the following:
<button ng-repeat="{{item in items}}" ng-click="{{item.name}}Function()">{{item.name}}</button>
I need to be able to get the ng-click to dynamically change based on the item.name such as
firstItemFunction()
secondItemFunction()
etc.
If $scope has references to the functions:
$scope.items =
[
{ name: 'firstItemFunction' },
{ name: 'secondItemFunction' }
];
$scope.firstItemFunction = function () {
console.log('firstItemFunction');
};
$scope.secondItemFunction = function () {
console.log('secondItemFunction');
};
HTML:
<button ng-repeat="item in items" ng-click="this[item.name]()">
{{item.name}}
</button>
Demo: http://plnkr.co/edit/FSrGumlZqm4Rdku6I3X5?p=preview
Alternatively:
$scope.items = [{
name: 'firstItemFunction'
}, {
name: 'secondItemFunction'
}];
$scope.firstItemFunction = function() {
console.log('firstItemFunction');
}
$scope.secondItemFunction = function() {
console.log('secondItemFunction');
}
$scope.execute = function(action) {
$scope[action]();
};
And:
<button ng-repeat="item in items" ng-click="execute(item.name)">
{{item.name}}
</button>
Demo: http://plnkr.co/edit/6jATpgEAvFgTFXbvQ6IE?p=preview
If the functions are defined globally use HTML from above, inject $window and:
$scope.items = [{
name: 'firstItemFunction'
}, {
name: 'secondItemFunction'
}];
$scope.execute = function(action) {
$window[action]();
};
Demo: http://plnkr.co/edit/TinMbmvMTIQS4vptQMYf?p=preview
I would move the logic for determining which function to call to your javascript.
html
<button ng-repeat="{{item in items}}" ng-click="figureOutFunction(item)">{{item.name}}</button>
javascript
$scope.figureOutFunction(item){
if(item.name == "firstItem"){
firstItemFunction();
}
else if(item.name == "secondItem"){
secondItemFunction();
}
};
edit
If you want to avoid the switch, you can do it this way:
html
<button ng-repeat="{{item in items}}" ng-click="item.action()">{{item.name}}</button>
javascript
var firstItemFunction = function(){
...
};
var secondItemFunction = function(){
...
};
$scope.items = [{
name: 'firstItem',
action: firstItemFunction
}, {
name: 'secondItem',
action: secondItemFunction
}];
I would avoid creating unnecessary functions that call others.

AngularJS binding issues

When I do the following in my code
<pre>{{uploader.queue.indexOf(item)|json}}</pre>
I get an index of the element that I am looking for but if I do something like this
removeAllFiles(uploader.queue.indexOf(item))
The result is always
-1
Try this out
Working Demo
html
<div class="container" ng-app="main" ng-controller="Controller">
<div ng-repeat="uploader in uploaders">
<button ng-click="removeAllFiles(uploader.queue.indexOf(item))">{{uploader.queue.indexOf(item)|json}}
</button>
</div>
</div>
script
angular.module('main', []);
// Main Controller
function Controller($scope) {
$scope.item = 'N';
$scope.uploaders = [{
clickable: true,
id:1,
queue: "ABC-Name"
}, {
clickable: false,
id:2,
queue: "XYZ-Name"
}, {
clickable: true,
id:3,
queue: "LMN-Name"
}];
$scope.removeAllFiles = function(item) {
console.log(item);
}
}

Magnific popup and Backbone events: the view disappears when I add the magnific popup code

I'm trying to create an event to a view which opens a light box when I click in the tag, but when I add the magnific pop-up code the view disappears.
Here is my html code:
<section class="feed">
<script id="bookTemplate" type="text/template">
<div class="book">
<a href="<%= video %>" class="video">
<span><img src="img/go.png" class="go"></span>
<img src="<%= image %>"/>
<h2 class="bookTitle"><%= title %><h2>
</a>
</div>
</script>
</section>
And now my views and some data to test them:
var app = app || {};
app.BookListView = Backbone.View.extend({
el: '.feed',
initialize: function ( initialBooks ) {
this.collection = new app.BooksList (initialBooks);
this.render();
},
render: function() {
this.collection.each(function( item ){
this.renderBook( item );
}, this);
},
renderBook: function ( item ) {
var bookview = new app.BookView ({
model: item
})
this.$el.append( bookview.render().el );
}
});
app.BookView = Backbone.View.extend ({
tagName: 'div',
className: 'book',
template: _.template( $( '#bookTemplate' ).html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
events: {
'click .video' : 'popUp'
},
popUp: {
function () {
$('.popup').magnificPopup({
disableOn: 700,
type: 'iframe',
mainClass: 'mfp-fade',
removalDelay: 160,
preloader: false,
fixedContentPos: false
});
}
}
});
$(function(){
var books = [
{title:'American Psycho', image:'http://2.bp.blogspot.com/ ytb9U3mZFaU/Ti2BcgQHuhI/AAAAAAAAAkM/NMyfgRIFgt0/s1600/american-psycho_44538679.jpg',
video:'http://www.youtube.com/watch?v=qoIvd3zzu4Y'},
{title:'The Informers',
image:'http://www.movieposterdb.com/posters/09_03/2008/865554/l_865554_d0038c1c.jpg',
video:'http://www.youtube.com/watch?v=g4Z29ugHpyk'}
];
new app.BooksListView (books);
I don't know if the problem is related with my views code or vith the magnific pop-up code.
Thanks
Looks like a syntax error
you have an extra set of braces which is not supposed to be present there.
Here popup is supposed to be a event handler and not a object hash
popUp: {
function () {
$('.popup').magnificPopup({
disableOn: 700,
type: 'iframe',
mainClass: 'mfp-fade',
removalDelay: 160,
preloader: false,
fixedContentPos: false
});
}
}
supposed to be
popUp: function (e) {
e.preventDefault();
$('.popup').magnificPopup({
disableOn: 700,
type: 'iframe',
mainClass: 'mfp-fade',
removalDelay: 160,
preloader: false,
fixedContentPos: false
});
}

Resources