I've been working at this for a while, trying to get dynamic paper-tabs. Basically I have an array that's filled after an AJAX request, and I want to be able to add a new paper-tab then fill an iron-page div with some other content from the array, which might look like:
[{"Category":"Fruit", "Name":"Banana"},
{"Category":"Fruit", "Name":"Apple"},
{"Category":"Vegetable", "Name":"Potato"}]
So the section starts as...
<template is="dom-bind">
<paper-tabs id="menuTabs" selected="{{selected}}">
</paper-tabs>
<iron-pages id="menuPages" selected="{{selected}}">
</iron-pages>
</template>
And would end with something like...
<template is="dom-bind">
<paper-tabs id="menuTabs" selected="{{selected}}">
<paper-tab>Fruit</paper-tab>
<paper-tab>Vegetable</paper-tab>
</paper-tabs>
<iron-pages id="menuPages" selected="{{selected}}">
<div>Banana, Apple</div>
<div>Potato</div>
</iron-pages>
</template>
The dream is that maybe I can do this without a separate element by using a template or the Polymer DOM API, but I'm fairly new to Polymer so I could be completely missing the concept. I've tried just adding new paper-tab elements inside the paper-tabs element with JS after, but they end up in the wrong place in the DOM, and even then don't change iron-page. Any guidance is appreciated :)
Use a dom-repeat to loop through your list. Then you can populate the other elements with the array's values.
https://www.polymer-project.org/1.0/docs/devguide/templates.html#dom-bind
Custom element example:
<dom-module id="test-element">
<template is="dom-repeat" items="{{stuff}}">
<paper-tabs id="menuTabs" selected="{{selected}}">
<paper-tab>{{item.Category}}</paper-tab>
</paper-tabs>
<iron-pages id="menuPages" selected="{{selected}}">
<div>{{item.Name}}</div>
</iron-pages>
</template>
<script>
Polymer({
is: 'test-element',
properties: {
stuff:{
type: Array,
value: [{'Category':'Fruit', 'Name':'Banana'},
{'Category':'Fruit', 'Name':'Apple'},
{'Category':'Vegetable', 'Name':'Potato'}]
}
});
</script>
</dom-module>
<test-element></test-element>
dom-bind example (without custom element):
<template id="t" is="dom-bind">
<template is="dom-repeat" items="{{stuff}}">
<paper-tabs id="menuTabs" selected="{{selected}}">
<paper-tab>{{item.Category}}</paper-tab>
</paper-tabs>
<iron-pages id="menuPages" selected="{{selected}}">
<div>{{item.Name}}</div>
</iron-pages>
</template>
<script>
var t = document.querySelector('#t');
t.stuff=[{'Category':'Fruit', 'Name':'Banana'},{'Category':'Fruit', 'Name':'Apple'},{'Category':'Vegetable', 'Name':'Potato'}];
</script>
</template>
Related
I am having odd behavior with Polymer 1 Iron-selector
Below is my code.
<iron-selector selected="{{_selectedIndex}}">
<template is="dom-if" if="[[colors.length]]">
<colors-item colors="[[colors]]"></colors-item>
</template>
<template is="dom-repeat" items="{{colorways}}">
<colorway-item colorway="{{item}}"></colorway-item>
</template>
and in Properties selectedIndex looks like this
_selectedIndex: Number,
If I make changes and save, I want the selected to be none. How can i do this?
So I have a scenario:
<template is="dom-repeat" items="{{objects}}" as="o" filter="{{_filter(filter)}}">
...
<template is="dom-if" if="_isHidden" restamp>
foo
</template>
...
</template>
Now, the _filter function forces rerendering items under the dom-repeat every time my filter property changes (since it's observed by _filter. This is not the problem as it works properly, but the catch is that the _hidden function might return true or false based on another property (which could also change), and whenever the filter rerenders I need to force re-evaluation of _isHidden hence hide or show the contents of the dom-if template.
Anyone has an idea what could be my issue?
Thanks!
You have to also bind the _isHidden property:
<template is="dom-repeat" items="{{objects}}" as="o" filter="{{_filter(filter)}}">
...
<template is="dom-if" if="{{_isHidden}}" restamp>
foo
</template>
...
</template>
I have the following polymer element.
<dom-module id="my-element">
<template is="dom-repeat" items="[[items]]">
<paper-item>
<span>[[item]]</span>
</paper-item>
</template>
</dom-module>
Expected to be used as
<my-element items="[[items]]">
</my-element>
This will repeat the hardcoded span. But is it possible for the host to supply the rendering component as well. So instead of span they can provide whats going to be repeated.
<my-element items="[[items]]">
<div>
<div>[[item.name]]</div>
<div>[[item.address]]</div>
</div>
</my-element>
Tried content selection doesn't seem to repeat the selected element.
<dom-module id="my-element">
<template is="dom-repeat" items="[[items]]">
<paper-item>
<content select="element"></content>
</paper-item>
</template>
</dom-module>
<my-element items="[[items]]">
<div class="element">
<div>[[item.name]]</div>
<div>[[item.address]]</div>
</div>
</my-element>
Appreciate any help or directions on this.
If multiple <content> elements with the same select value are added all elements are projected to the first element with a matching selector. You need to find a different strategy.
I'm currently trying to map an array of strings I have to its corresponding object... but cannot find a way to do the map it.
I want to do something like this below (I know syntax is not correct, but trying to get my point across)
// user.connections ["1","2","3"]
<template is="dom-repeat" items="{{user.connections}}" as="connection"
map="isAppConnection" observe="app.id">
{{connection}} <!-- The actual object -->
</template>
Use computed bindings
<dom-module is="some-element">
<template is="dom-repeat" items="{{isAppConnection(user.connections)}}" as="connection">
{{connection}}
</template>
</dom-module>
<script>
Polymer({
is: "some-element",
properties: {user: Object},
isAppConnection: function(connections){
connections.map(e=>SomeObj[e])
},
})
</script>
I'm building a site with Polymer that uses paper-tabs and core-pages. The problem I'm running into is that I can not seem to get the click event for the tabs to affect the pages being shown and all content remains hidden unless I specifically select which page I want shown.
So I really just want the tabs to behave the way tabs are supposed to behave.
Here is my code so far:
<body unresolved>
<paper-tabs selected="0" selectedindex="0" id="paper-tabs" >
<paper-tab id="paper-tab" active>ABOUT</paper-tab>
<paper-tab id="paper-tab1">PORTFOLIO</paper-tab>
<paper-tab id="paper-tab2">CONTACT</paper-tab>
</paper-tabs>
<core-pages selected="{{$.paper-tab.selected}} " selectedindex="0" notap id="core-pages">
<about-me id="paper-tab" active>
<h2 horizontal center-justified>Worldwide Jamie</h2>
<p>Jamie is a Chicago-based freelance front end web developer.</p>
<p>Clearly this website is <b>Under Development</b></p>
<p>Come back soon to see how great your site could be</p>
</about-me>
<portfolio-list id="portfolio">
<!--Insert slider?-->
</portfolio-list>
<contact-me id="contact">
</contact-me>
</core-pages>
</body>
</html>
Thanks in advance for any time and consideration.
As of Polymer 1.0+, this is what you'll want to be using.
<link rel="import" href="components/paper-tabs/paper-tabs.html">
<link rel="import" href="components/iron-pages/iron-pages.html">
<paper-tabs selected="0">
<paper-tab>Tab One</paper-tab>
<paper-tab>Tab Two</paper-tab>
</paper-tabs>
<iron-pages selected="0">
<div>Page One</div>
<div>Page Two</div>
</iron-pages>
<script>
var pages = document.querySelector('iron-pages');
var tabs = document.querySelector('paper-tabs');
tabs.addEventListener('iron-select', function() {
pages.selected = tabs.selected;
});
</script>
Simple. use this in your script.
var tabs = document.querySelector('paper-tabs');
var pages = document.querySelector('core-pages');
tabs.addEventListener('core-select',function(){
pages.selected = tabs.selected;
});
Demo - Codepen.
<polymer-element name="my-element">
<template>
<style>
/* some css */
</style>
<section layout vertical is="auto-binding">
<paper-tabs selected="{{ selected }}" selectedindex="0" horizontal center layout>
<paper-tab inline flex center-center horizontal layout active>First</paper-tab>
<paper-tab inline flex center-center horizontal layout>Second</paper-tab>
...
</paper-tabs>
<core-animated-pages selected="{{ selected }}" selectedindex="0" notap>
<section active one flex vertical layout>
<--some html-->
</section>
<section one flex horizontal layout>
<--some html-->
</section>
...
</core-animated-pages>
</section>
</template>
<script>
Polymer({
selected: 0
});
</script>
</polymer-element>
<my-element></my-element>
The binding on <core-pages> is not being evaluated because data binding is only set up for definitions inside of a <polymer-element> template.
Polymer has a special "auto-binding" template that is meant to be put in the main page and provide data-binding for top level elements.
More info: http://www.polymer-project.org/docs/polymer/databinding-advanced.html#bindingoutside
There's a typo in your core-pages 'selected' attribute expression: paper-tab instead of paper-tabs
There's a trailing space behind this expression
You cannot use paper-tabs as a property name. Rename the paper-tabs id to paperTabs (btw. is there a way to make Polymer print an error message in case of a malformed expression?)
As #dfreedm said, you cannot use data binding outside a polymer-element. Another option is: put your whole app into a polymer-element.
<template is="auto-binding">
...
<paper-tabs selected="{{selected}}" selectedIndex="0" id="paper-tabs" >
...
<core-pages selected="{{selected}}" notap id="core-pages">
...
</template>
and, to add to some other things mentioned in other answers — i think paper-tab element shouldn't have active attribute