Binding Paper-Tabs to Core-Pages with Polymer - javascript

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

Related

Angular ng-container equivalent in vue.js

In Angular there is a tag called ng-container used like so
<ng-container *ngIf="false">this wont be shown</ng-container>
now as per the angular docs
The Angular is a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM.
Now this is really handy in angular since there are often times I would like to group a set of html elements without using a <div></div>
For example
<div class="flex-div">
<ng-container *ngIf="true">
<img src="cool-img" alt="awesome">
<h1>Cool Title</h1>
<p>Cool Text</p>
</ng-container>
<ng-container *ngIf="false">
<img src="not-so-cool-img" alt="awesome">
<h1>Not So Cool Title</h1>
<p>Not So Cool Text</p>
</ng-container>
</div>
here I have a div that has a position of flex on it and also rules about what the elements inside do..
Now If I wrapped the elements in a normal div it will break my flex styles but with the ng-container it contains my elements but is not rendered to them DOM
Is there an equivalent in Vue??
You could use conditional grouping on a template as mentioned in the docs here. The template will serve as an invisible wrapper.
<div class="flex-div">
<template v-if="true">
<img src="cool-img" alt="awesome">
<h1>Cool Title</h1>
<p>Cool Text</p>
</template>
<template v-if="false">
<img src="not-so-cool-img" alt="awesome">
<h1>Not So Cool Title</h1>
<p>Not So Cool Text</p>
</template>
</div>

app-header doesn't hide Polymer 2.0

I've got a problem since I migrate to Polymer 2.0, my app-header doesn't want to hide but for exemple app-drawer does with the same attribute value. Here is my code:
<app-header slot="header" fixed shadow effects="waterfall" hidden$=[[!storedUser.loggedin]]>
<app-toolbar>
<div class="header--menu header--menu__size">
<paper-button drawer-toggle>
<iron-icon icon="menu" drawer-toggle></iron-icon>
</paper-button>
</div>
<div class="header--title" main-title>Test</div>
<div class="header--setting header--setting__size">
<paper-button on-tap="_logout">
<custom-icon iconset="ci-login" icon="normal"></custom-icon>
<span>[ [[localize('logout')]] ]</span>
</paper-button>
</div>
</app-toolbar>
</app-header>
If you want more info / code don't hesitate.
Thanks
Remove the property fixed from app-header.
Check the documentation for all available properties app-header

Modify sidebar component based on content section component in Vue

Here is my template section:
<template>
<!-- START Home.vue section -->
<div class="container-fluid" v-if="user.authenticated">
<!-- START Sidebar.vue section -->
<sidebar-component></sidebar-component>
<!-- END Sidebar.vue section -->
<div class="main-container">
<!-- START Nav.vue section -->
<nav-component></nav-component>
<!-- END Nav.vue section -->
<!-- START Content Section -->
<router-view></router-view>
<!-- END Content Section -->
</div>
</div>
<!-- END Home.vue section -->
</template>
Clearly it has 3 components: NavComponent,SidebarComponent, Main component area that will be replaced by the routed component.
I have another component ApplicationList component that when will replace the router-view section of above template, is supposed to cause the sidebar component to behave differently(say for example sidebar becomes hidden or its background becomes red).
So how do I do it?
Install https://github.com/vuejs/vuex-router-sync . It will give you your current route state in your Vuex.
In your <sidebar-component> just refer to this.$store.state.route.name (or path, or whatever you need) and use it in your v-if or some watch .
This is the easiest and most scalable solution to handle changes in components based on current route in application.
Hope it helps.

Polymer content selection dom-repeat

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.

AJAX only dynamic paper-tabs

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>

Categories

Resources