How to pass value from one custom element to another element in Polymerjs 1.0 - polymer-1.0

I have a custom element element1.html in which we use iron-ajax to call the service,data received from the service is used to populate the dropdown menu
<dom-module id="element1">
<iron-ajax auto
url="../sites.json"
handle-as="json"
on-response="handleResponse"
></iron-ajax>
<paper-dropdown-menu-light label="select site" noink no-animations>
<paper-listbox class="dropdown-content sitedropdown">
<template is="dom-repeat" items="{{data}}">
<a class="sitelist" on-tap="testclick" data-cus$="{{item.keyValue}}" href$="{{baseUrl}}site/{{item.keyValue}}" tabindex="-1">
<paper-item raised>{{item.Name}}</paper-item>
</a>
</template>
</paper-listbox>
</paper-dropdown-menu-light>
<script>
Polymer({
is: 'element1',
properties: {
},
handleResponse:function(e,request){
this.data=e.detail.response;
},
testclick : function(e){
console.log(e.target.parentNode.getAttribute('data-cus'));
this.keyValue=e.target.parentNode.getAttribute('data-cus');
}
});
</script>
</dom-module>
In the above dropdown each value is a link and it has a unique key when clicked on it will route to other section(other page) where data will be displayed using the "keyValue" present in the anchor tag.In this section I use another custom element (element2.html).So how can I pass the keyValue present in element1.html to element2.html
<section data-route="site" tabindex="-1">
<element2></element2>
</section>
element2.html
<dom-module id="my-list">
<template>
<iron-ajax auto
url="serviceURL/?key={{I need to get the value from element1.html here}}"
handle-as="json"
on-response="handleResponse"
></iron-ajax>
</template>
</dom-module>

Related

Polymer equivalent to ng-show?

Is the a polymer equivalent for ng-show? Here's a snippet example of what I'm trying to convert:
<h1>Greeting</h1>
<div ng-show="authenticated">
<p>The ID is {{controller.greeting.id}}</p>
<p>The content is {{controller.greeting.content}}</p>
</div>
<div ng-show="!authenticated">
<p>Login to see your greeting</p>
</div>
dom-if is not necessary here. Simply use $= (attribute binding) to add/remove hidden attribute.
<style>
[hidden] {
display:none;
}
</style>
<h1>Greeting</h1>
<div hidden$=[[!authenticated]]>
<p>The ID is {{controller.greeting.id}}</p>
<p>The content is {{controller.greeting.content}}</p>
</div>
<div hidden$=[[authenticated]]>
<p>Login to see your greeting</p>
</div>
Use dom-if to make decisions about blocks of code that you don't want to be rendered, not just hidden.
I guess you could use dom-if to conditionally keep required HTML in DOM tree. properties should be defined there in properties of component.
<template is="dom-if" if="{{authenticated}}">
<p>The ID is {{controller.greeting.id}}</p>
<p>The content is {{controller.greeting.content}}</p>
</template>
<template is="dom-if" if="{{!authenticated}}">
<p>Login to see your greeting</p>
</template>
True and False will work once you add template with in template. I tried
<template>
<template is="dom-if" if="{{authenticated}}">
{{authenticated}}
<p>The ID is {{controller.greeting.id}}</p>
<p>The content is {{controller.greeting.content}}</p>
</template>
<template is="dom-if" if="{{!authenticated}}">
{{authenticated}}
<p>Login to see your greeting</p>
</template>
</template>
If you will not add template with in template True, false will never work. It will always show you the first template wheather you have True or False value of properties.
Hope it works.

attaching template content from within a polymer element

I am trying to have certain content of a polymer element procedurally added, at a time later than its creation. I am trying to avoid a <template is="dom-if"> element.
Instead I am trying to have a nested <template> element inside the polymer element's template and have its content attached on the execution of a method, like so:
<dom-module id="simple-element">
<template>
<content id="content"></content>
<div id="display">display</div>
<template id="t">
template content
<script>console.log("template added!")</script>
</template>
</template>
<script>
var simpleElement = {
is: "simple-element",
attached : function(){
this.init();
},
init : function(){
var t = document.importNode(this.$.t.content,true);
this.$.display.appendChild(t);
},
}
Polymer(simpleElement);
</script>
</dom-module>
See it also in this jsbin http://jsbin.com/zudituvuli/edit?html,js,console,output
Is there a way to accomplish this?

Can't change drawerWidth on paper-drawer-panel Polymer 1.0

It's pretty basic but i don't know if it's a bug or i'm wrong with something.
I cant change the width of the drawer in the paper-drawer-panel. In the documentation page specify to add the property drawerWith.
Here is some code:
<dom-module id="my-app">
<template>
<style>
:host {
display: block;
}
</style>
<paper-drawer-panel drawerWidth="300px">
<!-- Nav Bar -->
<section drawer>
<!-- Logo -->
<div id="logoContainer">
<img id="logo" src="../img/logo.png">
</div>
</section>
<!-- Content -->
<paper-header-panel main>
<paper-toolbar>
<paper-icon-button icon="menu" paper-drawer-toggle></paper-icon-button>
<div class="flex">My App</div>
</paper-toolbar>
</paper-header-panel>
</paper-drawer-panel>
</template>
<script>
// element registration
Polymer({
is: "my-app",
});
</script>
</dom-module>
This should work:
<paper-drawer-panel drawer-width="300px">
Here you can find the documentation that talks about it.
Attribute names with dashes are converted to camelCase property names by capitalizing the character following each dash, then removing the dashes. For example, the attribute first-name maps to firstName.
So, in documentation says drawerWidth when you use it in your elements must be: drawer-width

AngularJS Expression Not Working Correctly in ng-src with JSF

The angularjs module. the products array contains 2 product objects that will be added as a property of the controller.
(function () {
var app = angular.module('myApp', []);
var products = [
{
title: "Dummy Title 1",
description: "Dummy Description 1",
image: "dummy_image_1.jpg"
},
{
title: "Dummy Title 2",
description: "Dummy Description 2",
image: "dummy_image_2.jpg"
}
];
app.controller('myController', function () {
this.products = products;
});
})();
The JSF Page, if I remove images/{{product.image}} with the actual image file name such as images/dummy_image_1.jpg, the images are displayed, but if I use angularjs expression instead, then nothing is shown. Please note that other expressions in the loop work besides {{product.image}}. If I add {{product.image}} somewhere else, then it displays the filename correctly, but used in ng-srs, it prints nothing if I view the html. I don't know why it is.
<h:form>
<div class="container" ng-controller="myController as controller">
<div class="row">
<div class="col-sm-offset-10">
Hello <b><h:outputText value="#{user.userName}"/></b><br/>
<h:commandLink action="cart" value="Cart"/>
</div>
</div>
<hr/>
<div ng-repeat="product in controller.products">
<div class="row">
<div class="media">
<div class="media-left">
<img class="media-object" ng-src="images/{{product.image}}"/> <!--If I replace that expression with a the image file name, it shows the image -->
</div>
<div class="media-body">
<h4 class="media-heading">{{product.title}}</h4>
<span class="caption">{{product.description}}</span><br/>
<h:commandLink action="cart" value="Add to cart"/>
</div>
</div>
</div>
</div>
</div>
</h:form>
Sometimes using interpolation {{}} won't evaluate & update value of attribute (most often this happens in IE). The way to do this is using ng-src directive with interpolation {{}} this will add src to the img tag after evaluation interpolation directive.
Markup
<div class="media-left">
<img class="media-object" ng-src="{{'images/'+product.image}}"/>
<!--If I replace that expression with a the image file name, it shows the image -->
</div>
Alternative
The other way would be using ng-attr directive which add attribute with evaluated value. This will ensure you everytime that the interpolated value has been assigned to the attribute mentioned it in ng-attr (the part after ng-attr is considered as attribute to be added, suppose we have ng-attr-value="{{someVar}}" then angular will evaluate someVar and then assign that value to value attribute on that element.
Markup
<div class="media-left">
<img class="media-object" ng-attr-src="{{'images/'+product.image}}"/>
<!--If I replace that expression with a the image file name, it shows the image -->
</div>

How can I write shadow dom that selects particular elements *after* most of the children?

I'm writing a custom <figure>-like element for which I'd like to put a <figcaption> under the main content. The <figcaption> needs to include some content (text with potential formatting) from the child nodes of the custom element, for which I'm using <content select="span.caption"></content>. However, per the Shadow DOM spec, the <span> has already been distributed to the earlier <content></content> element that laid out the body of the custom element.
I've tried using <content select=":not(span.caption)"></content> to avoid distributing the caption, but that appears not to be a compound selector and matches nothing.
What's the recommended way to get the elements to render in the order I want?
Here's the code with the problem, which is also at http://jsbin.com/vizoqusu/3/edit:
<!DOCTYPE html>
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.1.4/platform.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.1.4/polymer.js"></script>
<meta charset="utf-8">
</head>
<body>
<polymer-element name="my-figure" noscript>
<template>
<figure>
<content></content>
<figcaption>Figure 7: <content select="span.caption"></content></figcaption>
</figure>
</template>
</polymer-element>
<my-figure>
Hello World!
<span class="caption">The caption</span>
</my-figure>
</body>
</html>
This actually does work today under ShadowDOM polyfill, with two caveats:
:not only takes simple selectors as arguments, so you need to do something like *:not(.caption)
If you use a selector at all, plain text nodes are ignored, so you have to wrap your other content in some kind of element.
Here is an example:
http://jsbin.com/vizoqusu/5/edit
<polymer-element name="my-figure" noscript>
<template>
<figure>
<content select="*:not(.caption)"></content>
<figcaption>Figure 7: <content select="span.caption"></content></figcaption>
</figure>
</template>
</polymer-element>
<my-figure>
<span>Hello World!</span>
<span class="caption">The caption</span>
</my-figure>
As for the native system, I used your use case to argue for inclusion of :not() into the specification, you can see it here:
https://www.w3.org/Bugs/Public/show_bug.cgi?id=24867
I see a few options here:
You could use getDistributedNodes to first get the content of the element and then inject the text (Hello World) and caption at the right points as follows:
<polymer-element name="my-figure">
<template>
<figure id="figureHolder">
<content id="content"></content>
<figcaption>Figure 7: <content id="caption" select="span.caption"></content></figcaption>
</figure>
</template>
<script>
Polymer('my-figure', {
caption: '',
ready: function() {
var nodes = this.$.content.getDistributedNodes();
this.$.caption.innerHTML = nodes[1].innerHTML;
this.$.content.getDistributedNodes()[0].data = nodes[0].data;
this.$.content.getDistributedNodes()[1].innerHTML = '';
}
});
</script>
</polymer-element>
<my-figure>
Hello World!
<span class="caption">The caption</span>
</my-figure>
You could move your caption into an attribute and this allows you to maintain a clean separation between the content of your figure and the caption itself:
<polymer-element name="my-figure" attributes="caption" noscript>
<template>
<figure>
<content></content>
<figcaption>Figure 7: {{caption}} </figcaption>
</figure>
</template>
</polymer-element>
<my-figure caption="The caption">
Hello World!
</my-figure>
You could move your main content (e.g Hello World) into it's own span and add a class to allow targeting it from inside your template directly, so:
<polymer-element name="my-figure" noscript>
<template>
<figure>
<content select="span.hello"></content>
<figcaption>Figure 7:
<content select="span.caption"></content></figcaption>
</figure>
</template>
</polymer-element>
<my-figure>
<span class="hello">Hello World!</span>
<span class="caption">The caption</span>
</my-figure>

Resources