Polymer import dynamic HTML - javascript

I'm working with a Product Listing Mobile App using Polymer
So i wanted to load the product details like 3 images decription and other details when click on the thumbnail,
I'm using core-animated-pages to show the product thumbnail and Detail view
Here is the HTML
<div id="article-content" >
<template is="auto-binding" id="page-template" >
<core-ajax
id="ajaxpolo" auto
url="./json/products.json"
handleAs="json"
response="{{productList}}">
</core-ajax>
<core-animated-pages id="fpages" flex selected="{{$.polo_cards.selected}}" on-core-animated-pages-transition-end="{{transitionend}}" transitions="cross-fade-all slide-from-right">
<section vertical layout>
<div id="noscroll" fit hero-p>
<div id="container" flex horizontal wrap around-justified layout cross-fade >
<section on-tap="{{selectView}}" id="polo_cards" >
<template repeat="{{item in productList}}">
<div class="card" vertical center center-justified layout hero-id="item-{{item.id}}" hero?="{{$.polo_cards.selected === item.id || lastSelected === item.id }}" > <span cross-fade hero-transition style="">{{item.name}}</span></div>
</template>
</section>
</div>
</div>
</section>
<template repeat="{{item in productList}}">
<section vertical layout>
<div class="view" flex vertical center center-justified layout hero-id="item-{{item.id}}" hero?="{{$.polo_cards.selected === item.id || $.polo_cards.selected === 0}}" >
<core-icon-button class="go_back" icon="{{$.polo_cards.selected != 0 ? 'arrow-back' : 'menu'}}" on-tap="{{goback}}"></core-icon-button>
{{item.name}} <span cross-fade class="view-cont" style="height:1000px; overflow:scroll;"></span></div>
</section>
</template>
</core-animated-pages>
</template>
template.selectView = function(e,detail,sender){
/* set core-animated page Selected */
var i = e.target.templateInstance.model.item.id;
sender.selected = i;
});
if i Put all the details in Detail view it will take too long to load, so i wanted to load the HTML of each products when click on its thumbnail
how can i do this ?

I use app-router to lazy-load the elements or html, especially with core-animated-pages. Works well with cordova as well to plug into the app. However, be cautious that since shadow DOM is not the default in Polymer 1.0 and <core-animated-pages> moved to <neon-animated-pages> with a significant difference in the apis, it no-longer works when you try to port to 1.0, at least not until it is re-worked. But, if you plan to stick to 0.5 or port to 1.0 without using core-animated-pages, it still works well. You can check it out here.

Related

AngularJS : Adding animation when div tag is updated

I am stuck in this problem where I have a div tag which updates and shows a list of images. I want to add animation when the value in the div tag is updated in the transition from one set of images to another.
Here as you can see in the bottom there are a set of images for girl's hair. And when the user goes to other tab, a different set of images comes. I want animation in that transition.
The AngularJS part for the transition is as follows :
<div ng-swipe-left="avDesignController.onSwipeLeftAction()" ng-swipe-right="avDesignController.onSwipeRightAction()">
<!-- CUSTOMIZABLE TAB BAR -->
<div class="tab-bar-container" >
<div class="scrollmenutab">
<!-- CUSTOMIZABLE MENU -->
<div ng-repeat="customizable in customizables"
ng-click="avDesignController.onCustomizableClicked($event)"
style="display: inline;">
<a ng-if="customizable.allowed == 1">
<div ng-class="{selected: $index==currentIndex}">
<div ng-if="customizable.name == 'Hair'">
<img class="scrollmenutab-icon"
id="{{customizable.name}}-{{$index}}"
src="/app/app_resources/icons/{{genderImage}}Hair.png">
</div>
<div ng-if="customizable.name != 'Hair'">
<img class="scrollmenutab-icon"
id="{{customizable.name}}-{{$index}}"
src="/app/app_resources/icons/{{customizable.name}}.png">
</div>
</div>
</a>
</div> <!-- MENU : END -->
</div>
</div>
<!-- CUSTOMIZABLES -->
<div class="avdesign-item-container" id="avdesign-item-container">
<div id="four-columns" class="grid-container" >
<!-- LOAD CUSTOMIZABLES IF NOT LAST ITEM IN TAB -->
<ul ng-if="currentIndex < (customizables.length - 1)"
class="rig columns-4">
<li ng-repeat="customizableItem in currentCustomizable.customizable_item">
<img class="tab-icon"
src="/app/app_resources/resources/av/{{avatarInfo.name}}/as/{{customizableItem.as}}"
id="customizable-{{$index}}"
ng-click="avDesignController.onCustomizedItemClicked($event)"
ng-class="{highlight: customizableItem.id==currentID}">
</li>
</ul>
<!-- LOAD OUTFITS (FROM avatarOutfit) IF LAST ITEM IN TAB -->
<ul ng-if="currentIndex == (customizables.length - 1)"
class="rig columns-outfit">
<div ng-repeat="brand in outfitBrand" ng-style="{'margin-bottom':'1vh'}">
<div class="brand-icon" >
<img src="/app/app_resources/icons/{{brand.bg_image}}">
</div>
<li ng-repeat="outfit in brand.outfitList">
<img class="outfit-icon"
src="/app/app_resources/resources/av/{{avatarInfo.name}}/as/{{outfit.as}}"
id="outfit-{{$index}}"
ng-click="avDesignController.onOutfitItemClicked($event,$parent.$index)"
ng-class="{highlightOutfit: $index==avatar.outfit_index && $parent.$index==indexParent}">
</li>
</div>
</ul>
</div>
</div>
</div>
Where the functions being called in the JS part is updating accordingly the images.
So Question being how to add transition animation for the same element when it is updated because we are never leaving or entering that element tag
Your question is answered here
Html
<div ng-controller="c">
<div id={{my_id}} width={{widthOfOutsideWrapper}} height={{heightOfOutsideWrapper}}>
<img ng-src="{{src}}" imageonload />
</div>
</div>
and in controller
var app = angular.module('app', []);
app.directive('imageonload', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('load', function() {
alert('image is loaded');
scope.widthOfOutsideWrapper= this.width;
scope.heightOfOutsideWrapper= this.height;
scope.my_id = "testing";
});
}
};
});
app.controller('c', function($scope) {
$scope.src ="https://www.google.com.ua/images/srpr/logo4w.png";
});
and http://jsfiddle.net/2CsfZ/855/ working example is available here
The above answer is very helpful and might be of a great help for many.
But the answer to my question is you simply can't. ngAnimate's ngEnter and ngLeave will not able to recognize a change unless the element is changed and not what is inside the element.
So either some hack needs to be applied like using ngRepeat with different id's for different updation that happens to the element or something else needs to be done.

How to place div items into jQuery Slider showing a minimum of 5 elements with Left-Right slider to view more elements?

I have div elements on a page with col-sm-3 classes. So far, I have 6 of these elements and so, 4 elements are on 1 row and 2 are on the next row which fill half this row. I am using Bootstrap.
I want to make all these elements be contained on 1 row in a slider using JQuery with a minimum of 5 elements showing and be able to click on left-right arrow buttons to view all elements.
I found this example JQuery called lightSlider: http://sachinchoolur.github.io/lightslider/ There are 2 examples on this website and I would like to make mine similar to the second red example.
I have tried to use the lightSlider class on my elements, but no change is seen.
Here is my HTML:
<div class="row whiteBG" id="lightSlider">
#foreach (var item in Model)
{
<div class="col-sm-3 align-centre">
<img src="#item.OutputImage" alt="#item.Image" />
<a href="#Url.Action("Products", "Home", new { id = item.Id, categoryName = item.Name })">
<div class="blend-box-top category-head" style="background: #0197BA url(#item.OutputImage) no-repeat 50% 0%;">
<div class="item-container">
<div class="desc-plus">
<p>#item.Name</p>
<p>+</p>
</div>
</div>
</div>
</a>
</div>
}
</div>
I have a row which added multiple amounts of col-sm-3 div elements.
I also placed this below my HTML before the ending body tag:
<script type="text/javascript">
$(document).ready(function() {
$("#lightSlider").lightSlider();
});
</script>
I am using Visual Studio and JQuery is loaded in by default at the bottom of the _Layout.cshtml file:
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
</body>
</html>
<div class="col-sm-2 align-centre">
Change your class from 3 > 2 so that 5 will fit.
It was the first time using JQuery for me and the problem was that I was including all the classes in my HTML that I saw in the Chrome Developer Tool HTML for the second example slider here: http://sachinchoolur.github.io/lightslider/index.html This was not necessary and caused errors since I was only meant to use 1 class which then automatically added new classes to my HTML.
Firstly, I used the lightslider.js, lightslider.css and controls.png files into my project available here: https://github.com/sachinchoolur/lightslider/tree/master/src
I then placed the folling script into my HTML page before the ending body tag:
$(document).ready(function () {
window.prettyPrint && prettyPrint()
$('#content-slider').lightSlider({
keyPress: false,
item: 5,
loop: true,
onSliderLoad: function () {
$('#content-slider').removeClass('cS-hidden');
}
});
});
</script>
This is available on the GitHub repository link above - I changed it a bit to make the item attribute display 5 elements initally.
It is crucial that you place this script after the script that calls the JQuery. It took me a day to find out this was the problem.
In lightslider.css you need to change the filePath to include the image used for the left-right arrows correctly. the class is .lSAction > a. I just placed mine in the Images folder and this is the attribute that I changed: background-image: url('Images/controls.png');
This is my HTML:
What you need to know is that I only include 1 class in my HTML list: ul<id="content-slider"> which will add the other necessary lightSlider to create the second example slider displayed here: http://sachinchoolur.github.io/lightslider/index.html
<div class="row whiteBG">
<ul id="content-slider" >
#foreach (var item in Model)
{
<li class="col-sm-4 align-centre">
<a href="#Url.Action("Products", "Home", new { id = item.Id, categoryName = item.Name })">
<img src="#item.OutputImage" alt="#item.Image" />
<div class="blend-box-top category-head" style="background: #0197BA url(#item.OutputImage) no-repeat 50% 0%;">
<div class="item-container">
<div class="desc-plus">
<p>#item.Name</p>
<p>+</p>
</div>
</div>
</div>
</a>
</li>
}
</ul>
</div>
I hope this can help someone else going through a similar problem. :)

Polymer Load Product Page data from JSON

Working with an e-commerce store application with polymer
I'm loading products array using polymer core-ajax and using core-animated pages to display product thumbnail and product detail page (full view) but I only wanted to load the product details when clicking on each product thumb, How can I do this
Find the HTML
<div id="article-content" >
<template is="auto-binding" id="page-template" >
<core-ajax
id="ajaxpolo" auto
url="./json/products.json"
handleAs="json"
on-core-response="{{handleResponse}}" response="{{headerList}}" on-core-response="{{postsLoaded}}">
</core-ajax>
<core-animated-pages id="fpages" flex selected="{{$.polo_cards.selected}}" on-core-animated-pages-transition-end="{{transitionend}}" transitions="cross-fade-all slide-from-right">
<section vertical layout>
<div id="noscroll" fit hero-p>
<div id="container" flex horizontal wrap around-justified layout cross-fade >
<section on-tap="{{selectView}}" id="polo_cards" >
<template repeat="{{item in headerList}}">
<div class="card" vertical center center-justified layout hero-id="item-{{item.id}}" hero?="{{$.polo_cards.selected === item.id || lastSelected === item.id }}" > <span cross-fade hero-transition style="">{{item.name}}</span></div>
</template>
</section>
</div>
</div>
</section>
<template repeat="{{item in headerList}}">
<section vertical layout>
<div class="view" flex vertical center center-justified layout hero-id="item-{{item.id}}" hero?="{{$.polo_cards.selected === item.id || $.polo_cards.selected === 0}}" >
<core-icon-button class="go_back" icon="{{$.polo_cards.selected != 0 ? 'arrow-back' : 'menu'}}" on-tap="{{goback}}"></core-icon-button>
{{item.name}} <span cross-fade class="view-cont" style="height:1000px; overflow:scroll;"></span></div>
</section>
</template>
</core-animated-pages>
</template>
first you would set the auto attribute of core ajax to false. auto="false" that would stop core-ajax from grabbing data by it's self. then set up a on-tap or on-click attribute on the element you want to be the click / tap handler. on-tap="{{getThem}}" then create the function.
getThem: function () {
this.$.ajaxpolo.go();
}
that should get it. hope it helps.
edit: you will want to grab a few more things with your event.
on the click / tap handler add the id of the item you wish to get to a generic attribute. (stay away from normal attributes. ie id, title and so forth) dataId I will call it.
<div on-tap="{{getThem}}" dataId="{{product_id}}"></div>
then in your function you get a few more things with the event as i said before.
getThem: function (event, detail, sender) {
var id = sender.attributes.dataId.value;
// do something with id
}
i just realized i may have misunderstood when you were talking about php. sorry.

Slow page rendering

I have an issue with a partial that is rendered almost instantly for the first time navigating to that page, however if navigate away from that page and sometime later i come back it is rendered noticeably slow. It contains an ng-repeat on a list of about 140 items.
e.g: home (initialize) --> spells (instant) --> home --> spells (slow)
GitHub Repository
Why does this happen and how do i fix it?
Steps i've already taken to try and improve:
Add bind-once in the repeater
Use etags in my API so i don't get back a full list of the items i already have each time i load a partial.
Added track by to ng-repeat.
Code
<div ng-repeat="color in ::colors">
<div>
<span data-target="#{{$index + 'col'}}">
<header>
<label>{{color.name}}</label>
</header>
</span>
</div>
<ul id="{{$index + 'col'}}">
<li ng-repeat="spell in ::spells track by spell.name"
ng-if="spell.color.name === color.name"
ng-dblclick="addToCharacter(spell, 'spell')"
on-long-press="addToCharacter(spell, 'spell')">
<div>
<label ng-hide="isSpell(spell)">Ability</label>
<label ng-show="isSpell(spell)">{{spell.cost}} mana</label>
</div>
<div data-target="#{{$index + 'sp'}}">
<a>{{spell.name}}</a>
</div>
<div id="{{$index + 'sp'}}">
{{spell.description}}
</div>
</li>
</ul>
</div>
IsSpell()
$rootScope.isSpell = function (spell) {
return spell.type != null && spell.cost != null;
};
I have implement a little mechanism to only load the items when they are needed, so the page loads instantaneous and when the user clicks on a category (which is animated) it loads the items it needs. This all works very smoothly and i am quite happy with it.
See the first div (colors) and the ng-if on the li
<div ng-repeat="color in ::colors" ng-init="loadItems = false" ng-click="loadItems = true">
<div>
<span data-target="#{{$index + 'col'}}">
<header>
<label>{{color.name}}</label>
</header>
</span>
</div>
<ul id="{{$index + 'col'}}">
<li ng-repeat="spell in ::spells track by spell.name"
ng-if="(spell.color.name === color.name) && (loadItems = true)"
ng-dblclick="addToCharacter(spell, 'spell')"
on-long-press="addToCharacter(spell, 'spell')">
<div>
<label ng-hide="isSpell(spell)">Ability</label>
<label ng-show="isSpell(spell)">{{spell.cost}} mana</label>
</div>
<div data-target="#{{$index + 'sp'}}">
<a>{{spell.name}}</a>
</div>
<div id="{{$index + 'sp'}}">
{{spell.description}}
</div>
</li>
</ul>
</div>

Get node inside template if statement

On my polymer-based website I created a custom element in that I am loading data via ajax. Depending on the current state of data-loading i created some <template if="{{}}"> elements to display the right content. It looks something this way:
<polymer-element name="modules-item" attributes="moduleID categories">
<template >
<service-get-module module="{{module}}" moduleID="{{moduleID}}"></service-get-module>
<paper-shadow z="1">
<core-toolbar>
<span flex hero-id="title" hero itemprop="name">{{module.title}}</span>
</core-toolbar>
</paper-shadow>
<paper-progress id="moduleLoadingProgress"></paper-progress>
<template if="{{moduleID == null}}">
<p>Modul not available</p>
</template>
<template if="{{moduleID != null && module == null}}">
<p>Module is loading...</p>
</template>
<template if="{{moduleID != null && module != null}}">
<div id="moduleContainer">
<!-- Content //-->
</div>
<template>
</template>
<script>
Polymer({
module: null,
moduleID: null,
ready: function(){
console.log(this.$.moduleContainer);
}
</script>
</polymer-element>
That works great, but if I try to access the <div id="moduleContainer"> I don't get it... I just read so many posts but did not get any solution. May anybode help me? :)
Here is the link to the live website: http://www.test.gruppenstunde.eu/
UPDATE
After working a little longer with polymer I found out, that it's easier to use the hidden?-Attribute, to casual hide content. Example:
<div hidden?="{{moduleID != null}}">Module not available</div>
You can't access elements within <template if="{{..}}"> or <template repeat="{{..}}"> (dynamically created) using the $ accessor. You need to use querySelector(...) and you can the field only when the if expression evaluates to true (the element is actually created/shown)
to get access to that element you can put that template in a div and give the div a id.
<div id="mod">
<template if="{{moduleID != null && module != null}}">
<div id="moduleContainer">
<!-- Content //-->
</div>
<template>
</div>
then you can
var el = this.$.mod.querySelector("#moduleContainer");

Categories