How to reference a polymer component from auto-binding template? - polymer

How to reference the ts component from a binding annotation in an auto-binding template, as in {{ts.value}} shown below:
<template is="dom-bind">
<tri-state id='ts' value="open"></tri-state>
Value: {{ts.value}}
</template>

Figured out how to do this. Just imagine that the auto-binding template has a property called x (for example) and bind both things to x like this:
<template is="dom-bind">
<tri-state value="{{x}}"></tri-state>
Value: {{x}}
</template>

Related

Using a pair of Polymer Component twice in the same page doesnt work

Im new to Polymer. Im using two different Polymer components that communicates with each other. I have to do it twice (2 x 2 components).
The following code uses just one pair of different components and it works:
<dom-bind id="dombind">
<template is="dom-bind">
<polymer-componentA id="polymercomponentA_1"
attribute="[[x]]"
attribute="[[x]]"
attribute="{{x}}">
</polymer-componentA>
<polymer-componentB id="polymer-componentB_1"
attribute="{{x}}">
</polymer-componentB>
</template>
</dom-bind>
But when I add other pair of components, it starts working bad. I think they use the same component (instead of being independent):
<dom-bind id="dombind">
<template is="dom-bind">
<polymer-componentA id="polymercomponentA_1"
attribute="[[x]]"
attribute="[[x]]"
attribute="{{x}}">
</polymer-componentA>
<polymer-componentB id="polymer-componentB_1"
attribute="{{x}}">
</polymer-componentB>
</template>
</dom-bind>
<dom-bind id="dombind">
<template is="dom-bind">
<polymer-componentA id="polymercomponentA_2"
attribute="[[x]]"
attribute="[[x]]"
attribute="{{x}}">
</polymer-componentA>
<polymer-componentB id="polymer-componentB_2"
attribute="{{x}}">
</polymer-componentB>
</template>
</dom-bind>
I know this is not done well, but I dont find good examples about this.
Whats the right way to use two polmyer components?
Thanks in advance!
If you provide a function, Polymer calls the function once per element
instance.
When initializing a property to an object or array value, use a
function to ensure that each element gets its own copy of the value,
rather than having an object or array shared across all instances of
the element.
Source: https://www.polymer-project.org/2.0/docs/devguide/properties#configure-values
Example
static get properties() {
return {
data: {
type: Object,
value: function() { return {}; }
}
}
}

Polymer 1.0 dom-repeat does not trigger filter

Have a simple paper-card with an iron-ajax which is being iterated ok but the filter I have made never triggers. The JSON being fetched via the iron-ajax has an integer value for the day of the week and I only want to have the ones with value of 0.
Tried the filter field with following values:
filter="{{isMonday}}"
filter="{{isMonday(item)}}"
filter="isMonday"
filter="isMonday(item)"
All of these with and without the observe
Component code:
<dom-module id="se-ligor">
<template>
<template is="dom-bind">
<iron-ajax auto
url="http://localhost:5000/leagues/1"
handle-as="json"
last-response="{{ajaxResponse}}">
</iron-ajax>
<template name="my-paper" is="dom-repeat" items="[[ajaxResponse]]" filter="{{isMonday}}" observe="dayofweek">
<paper-card heading="[[item.name]]">
<div class="card-content">
[[item.description]]
[[item.dayofweek]]
</div>
<div class="card-actions">
<paper-button>Some action</paper-button>
</div>
</paper-card>
</template>
</template>
</template>
<script>
Polymer({
is: "se-ligor",
isMonday: function (item) {
console.log(item.dayofweek);
if (item.dayofweek == 0)
return True;
}
});
</script>
</dom-module>
The dom-bind template is intended for binding only in index.html, not in dom-module, so that template should be removed.
The filter property takes the name of a method without delimiters (i.e., no brackets) on your Polymer constructor object.
<!-- in <dom-module> -->
<template is="dom-repeat" items="[[x]]" filter="isMonday" observe="dayofweek">...</template>
<script>
Polymer({
isMonday: function(item) {...}
});
</script>
isMonday contains a typo in return True. In JavaScript, the keyword is lowercase: true.
plunker demo

Conditional template on Polymer 1.0

I'm having trouble applying the new conditional template, in particular with the condition itself, I think.
I've got something like this:
<template is="dom-repeat" items="{{menuitems}}" as="poscol">
<template is="dom-if" if="{{index != 4}}">
<div class="positioncolum horizontal layout center wrap flex">
<span>{{index}}</span>
<template is="dom-repeat" items="{{poscol}}" as="mitem" >
<main-menu-item mitem="{{mitem}}"
order="{{mitem.TotalOrder}}"
onclick="clickMainMenuMod(index)">
</main-menu-item>
</template>
</div>
</template>
</template>
Now, if I comment the <template is="dom-if" if="{{index != 4}}"> bit it works fine, the index shows as it should.
On the fourth array are stored modules that the user has selected as non-visible, so they shouldn't appear on the main menu.
I guess there's something wrong with the if condition, but I can't guess what.
Thanks!
Try to modify your conditional template like this:
<template is="dom-if" if="{{show(index)}}">
And add this function to Polymer script:
show: function (index) {
return index != 4;
}

Data binding between published properties of two custom elements inside an auto binding template - Polymer 1.0

Problem: I have an auto binding template in my main index.html page. Inside the template I am using two of my custom elements. One element is the producer of some data and the other one is the consumer of that data. These custom elements expose published/declared properties for each other to use and bind to. I was able to do that in Polymer 0.5 fairly easily (an example shown below). How do I do the same in Polymer 1.0?
How I used to do in Polymer 0.5?
In Polymer 0.5 I used to data bind between published properties of two custom elements using curly brace syntax and then inside it used the auto node finding concept to directly bind to other element's published property. An example shown below,
<template is="auto-binding">
<my-navigation selectedLabel="Home" id="my_navigation"></my-navigation>
<my-scaffold toolbartitle="{{ $.my_navigation.selectedLabel }}" id="my_scaffold"></my-scaffold>
</template>
I tried something similar in Polymer 1.0 as shown in the example below
<template is="dom-bind">
<my-navigation selectedLabel="Home" id="my_navigation"></my-navigation>
<my-scaffold toolbartitle="{{ $.my_navigation.selectedLabel }}" id="my_scaffold"></my-scaffold>
</template>
But it throws an error:-
Uncaught TypeError: Cannot read property '$' of undefined
You can't do $.* bindings inside the template in Polymer 1.0. Instead, either refactor or use computed functions.
In your situation, since selectedLabel and toolbartitle shares the same value, it is much better to simply bind them to the same property.
Also, attribute names that are declaratively passed in (through the element tag) need to be serialized, so selectedLabel becomes selected-label.
<body>
...
<template id="tpl" is="dom-bind">
<my-navigation selected-label="{{myLabel}}" id="my_navigation"></my-navigation>
<my-scaffold toolbartitle="{{myLabel}}" id="my_scaffold"></my-scaffold>
</template>
<script>
...
window.addEventListener("WebComponentsReady", function (e) {
document.querySelector("#tpl").myLabel = "Home";
...
});
...
</script>
</body>
There is probably a better way to do that, but you can try this:
<body>
<template id="app" is="dom-bind">
<my-navigation selectedLabel="Home" id="my_navigation"></my-navigation>
<my-scaffold toolbartitle="{{ selectedLabel }}" id="my_scaffold"></my-scaffold>
</template>
<script>
var app = document.querySelector('#app');
app.addEventListener('template-bound', function () {
console.log('Our app is ready to rock!');
});
window.addEventListener('WebComponentsReady', function () {
document.querySelector('body').removeAttribute('unresolved');
var my-navigation = document.querySelector('my-navigation');
// This will add the variable to the 'app' context (template)
app.selectedLabel = my-navigation.selectedLabel;
});
</script>
</body>

Polymer: How do you create repeating elements dynamic?

I have a Polymer element called edit-box that acts as a container for a set of unspecified elements based on incoming data.
<link rel="import" href="/assets/bower_components/polymer/polymer.html">
<link rel="import" href="/assets/elements/field-text.html">
<link rel="import" href="/assets/elements/field-hidden.html">
<polymer-element name="edit-box" attributes="dataFields">
<template>
<template repeat="{{dataField in dataFields}}">
<field-{{dataField.Type}}></field-{{dataField.Type}}>
</template>
<input type="button" value="Save" />
</template>
<script>
Polymer('edit-box', {
...
}
</script>
</polymer-element>
dataField.Type might be "text" or "hidden", etc.
I have created other polymer elements called field-text and field-hidden, etc.
This is just the basic idea, I know it's not polished. How can I go about looping through my dataFields and render different elements within this edit-box container element based on what exists inside of that data set?
It would be super cool to bind to an element name like this, but it's not possible. Polymer's internal Node.bind() library needs a property, TextNode, etc. to bind to. In the case of <field-{{dataField.type}}>, the {{}} is meaningless, as there's nothing to latch on to.
One way you can achieve what you want is to use conditional templates:
<template repeat="{{dataField in dataFields}}">
<template if="{{dataField.type == 'text'}}">
<field-text></field-text>
</template>
<template if="{{dataField.type == 'chart'}}">
<field-chart></field-chart>
</template>
</template>
http://jsbin.com/yuqinoxa/1/edit
Even better would be to create a generic element, and give it a type attribute to bind to:
<template repeat="{{dataField in dataFields}}">
<field-element type="{{dataField.type}}"></field-element>
</template>
http://jsbin.com/tirokuso/1/edit