I have a <template is="dom-if" if=... that I want to use with a logical condition.
Any binding I try appears to be truthy:
<link href="https://polygit.org/components/polymer/polymer.html" rel="import">
<dom-module id="test-thing">
<template>
<template is="dom-if" if="{{title == 'foo'}}" restamp>
Title is <b>FOO</b>
</template>
<template is="dom-if" if="{{title}} == 'bar'" restamp>
Title is <b>BAR</b>
</template>
Actual: "{{title}}"
</template>
<script>
Polymer({
is: 'test-thing',
properties: {
title: {type: String,value:''}
}
});
</script>
</dom-module>
<div>
Title: foo<br>
<test-thing title="foo"></test-thing>
</div>
<div>
Title: bar<br>
<test-thing title="bar"></test-thing>
</div>
<div>
Title: abc<br>
<test-thing title="abc"></test-thing>
</div>
What is the correct way to apply an if condition to a dom-if template?
you have to define your function.
<template is="dom-if" if="[[_isEqualTo(title, 'Foo')]]">
and then in script:
function _isEqualTo(title, string) {
return title == string;
}
whenever is property title changed, function _isEqualTo is called. so you don't have to take care of observing property or something.
function _isEqualTo is called with 2 parameters, the second one is just plain string you want to compare some value with.
The only logic you can use in a binding is not.
for instance:
<template is="dom-if" if="{{_isEqualTo(title, 'Foo')}}">
<template is="dom-if" if="{{!_isEqualTo(title, 'Foo')}}">
If your data was such that Foo was boolean or had an attribute that "Foo":true or "isFoo":true . Then you could just do:
<template is="dom-if" if="{{isFoo}}">
Foo
</template>
Related
I'm trying to use a dom-repeat inside a dom-repeat over a json array inside a json array. How can pass a value from the first array over to the second dom-repeat?
To illustrate, I have the following json array which loads fine:
"books": [
{
"title": "book1",
"slug": "b1",
"authors": ["author1","author2"],
"blurb": "Some text"
},
{
"title": "book2",
"slug": "b2",
"authors": ["author2","author3"],
"blurb": "some more text"
}]
I'm iterating over the array 'books' and retrieve title and blurb. Then underneath, I want both authors of each book listed and I also want a link to each one in the format of /slug/author (f.i. /b1/author1). But because in the second dom-repeat I redefine "items", the 'slug' is no longer available. How do I go about this?
<template>
<iron-ajax
auto
url="somelist.json"
handle-as="json"
last-response="{{someList}}"></iron-ajax>
<template is="dom-repeat" items="{{someList.books}}">
<paper-collapse-group>
<paper-collapse-item header$="{{item.title}}">
<p>{{item.blurb}}</p>
</paper-collapse-item>
<template is="dom-repeat" items="{{item.authors}}">
<a href$="/[[slug]]/[[item]]">{{item}}</a></div>
</template>
</paper-collapse-group>
</template>
</template>
I'm also very new to Polymer so thank you for helping me learn!
Use the as attribute to use a custom name for the item property.
Example:
<template>
<iron-ajax
auto
url="somelist.json"
handle-as="json"
last-response="{{someList}}"></iron-ajax>
<template is="dom-repeat" items="{{someList.books}}" as="book">
<paper-collapse-group>
<paper-collapse-item header$="{{book.title}}">
<p>{{book.blurb}}</p>
</paper-collapse-item>
<template is="dom-repeat" items="{{book.authors}}" as="author">
<a href$="/[[book.slug]]/[[author]]">{{author}}</a></div>
</template>
</paper-collapse-group>
</template>
</template>
So what you can do is to create another element, let's say that would look like:
<dom-module id="authors">
<template>
<template is="dom-repeat" items="[[authors]]">
<a href$="/[[slug]]/[[item]]">[[item]]</a>
</template>
</template>
<script>
Polymer({
is: 'authors',
properties: {
authors: Array,
slug: String
},
});
</script>
</dom-module>
and then inject it into your code like:
<template is="dom-repeat" items="[[someList.books]]">
<paper-collapse-group>
<paper-collapse-item header$="[[item.title]]">
<p>[[item.blurb]]</p>
</paper-collapse-item>
<authors slug="[[item.slug]]" authors="[[item.authors]]"></authors>
</paper-collapse-group>
</template>
I just started playing with Polymer and have been struggling to solve following issue.
In below code when the button is clicked myItem array is changed and parent template dom-repeat is rerendered, but the child template dom-repeat is not updated.
The reason might be the child dom-repeat is bound to the function _get.
<dom-module id="my-element">
<template>
<button on-click="_removeLastTwo">switch</button>
<template is="dom-repeat" items="{{myItem}}">
<ul>
<template is="dom-repeat" items="{{_get(item)}}">
<li>{{item}}</li>
</template>
</ul>
</template>
</template>
</dom-module>
<script>
Polymer({
is: 'my-element',
properties: {
data: {
type: Array,
value: [9,8]
},
myItem:{
type:Array,
value:[1,2,3,4,5]
}
},
_get:function(t){
var d = this.myItem.length;
return [d+1,d+2]
},
_removeLastTwo: function(){
this.myItem = [1,2]
}
});
</script>
How can I overcome this issue, check it at http://jsbin.com/misuvehuwe/edit?html,output . Am I missing any basic approach??
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
I need a dom-repeat to loop over one array and for each item I also need an element of a second array in the same index location.
<template is="dom-repeat" items="[[my_array1]]">
<div>[[item]]</div>
<div>[[my_array2[index]]] </div> <!-- this does not work -->
</template>
How to solve?
You'll need to use a computed binding:
<template is="dom-repeat" items="[[my_array1]]">
<div>[[item]]</div>
<div>[[getElementFromArray(index, my_array2)]]</div>
</template>
<script>
Polymer({
is: 'my-element',
getElementFromArray: function(index, arr) {
return arr[index];
}
})
</script>
I have a simple dom-module with an dom-repeat template in it:
<dom-module id="bookmark-extends">
<style>(...)</style>
<template>
<template is="dom-repeat" items="[[extends]]" as="extend">
<a href="[[extend.url]]">
<paper-button>[[extend.__firebaseKey__]]</paper-button>
</a>
</template>
</template>
</dom-module>
<script>
Polymer({
is: 'bookmark-extends',
properties: {
extends: {
type: Array,
notify: true,
value: function(){ return []; }
}
}
});
</script>
Here where I use it:
<dom-module id="bookmark-cards">
<style>(...)</style>
<template>
<firebase-collection
location="*******"
data="{{bookmarks}}"></firebase-collection>
<template is="dom-repeat" items="[[bookmarks]]" as="bookmark">
(...)
<div hidden="[[!bookmark.extendable]]" class="card-actions">
<bookmark-extends extends="[[bookmark.extends]]">
</bookmark-extends>
</div>
<div hidden="[[!bookmark.searchable]]" class="card-actions">
<input-search-on-site id="input" website-name="[[bookmark.__firebaseKey__]]" website-search-url="[[bookmark.searchUrl]]">
</input-search-on-site>
</div>
</paper-card>
</template>
</template>
</dom-module>
<script>Polymer({
is: 'bookmark-cards'
});</script>
I'm getting this error:
Uncaught TypeError: Cannot read property 'extends' of undefined
Please help me, I don't know what to do,
because in my second code the nearly same process is working...
EDIT:
Now I don't use an extra module and don't use the word "extend" anymore...
<div hidden="[[!bookmark.expandable]" class="card-actions">
<template is="dom-repeat" items="[[bookmark.links]]" as="link">
<paper-button>{{link.__firebaseKey__}}</paper-button>
</template>
</div>
The new Error is: "[dom-repeat::dom-repeat]: expected array for items, found Object"
If I try this:
properties: {
links: {
type: Array,
notify: true,
value: function(){ return []; }
}
}
The same error comes.
Couple of things. Move your script element inside the dom-module tag, as per Polymer recommendations.
https://www.polymer-project.org/1.0/docs/devguide/properties.html
Secondly don't use "extends" as an instance variable/property name. Extends is a Polymer keyword for extending existing HTML elements.
https://www.polymer-project.org/1.0/docs/devguide/registering-elements.html
This Plunker shows the key changes: http://plnkr.co/edit/BKzrfC
<dom-module id="bookmark-extends">
<template>
<template is="dom-repeat" items="[[extnds]]" as="extend">
<div>extend</div>
</template>
</template>
<script>
Polymer({
is: 'bookmark-extends',
properties: {
extnds: {
type: Array,
notify: true,
value: function(){ return ['one', 'two']; }
}
}
});
</script>
</dom-module>