Link in paper-item inside paper-menu-button (Polymer-1.0) - polymer

update 1: found this issue with pull request which seems to be addressing this issue in Polymer.
update 2: Decided to restructure my layout based on the Polymer Starter Kit which uses page.js instead of app-router, and seems to work well, although they don't use paper-item in paper-menu but instead use custom anchor elements.
Search every bit of documentation but I can't find this (although there is another issue on stackoverflow with almost the same title, not same thing)
TLDR: I need to have to whole paper-item clickable to the link. Not just the text itself. See image below for clarity and here is the live code.
.
I've got something like the code below. I'm using link tags in combination with app-router routing which works great. The only problem is: I would like to have have the entire paper-menu-item to be clickable with the link tag.
When I use below code, the right page is retrieved when clicking directly on the link tekst itself, but that doesn't create a "selected" state. When I click on the button (just off the text) then the button IS selected but the page isn't retrieved because I didn't click the link...
There must be an easy way to do this right? I mean, I could force this by overriding all the CSS but it seems to me a link in a paper-item in a paper-menu would be a very common thing which should do this automatically or with an attribute or someting?
<paper-menu class="list">
<paper-item icon="home" label="Home" ><a is="pushstate-anchor" href="/">Home</a></paper-item>
<paper-item icon="polymer" label="Demo"><a is="pushstate-anchor" href="/demo">Demo</a></paper-item>
</paper-menu>
I checked documentation on paper-item, paper-menu and others but those never use an example with a link.

IMO, the most clean way is to just drop the links altogether and just add on-tap event.
(You can also use dom-repeat for your menu)
<paper-menu class="list">
<paper-item icon="home" label="Home" on-tap="menuSelected" mypath="/">Home</paper-item>
<paper-item icon="polymer" label="Demo" on-tap="menuSelected" mypath="/demo">Demo</paper-item>
</paper-menu>
I'm assuming your are using <a> tags because of app-router.
From app-router doc:
go(path, options) - You can call the router from Javascript to navigate imperatively.
Then you can simple write your own on-tab handler and use custom attribute (mypath) on each <paper-item>
Polymer({
is: 'your-menu',
menuSelected: function (e) {
var mypath = e.currentTarget.getAttribute('mypath');
document.querySelector('app-router').go(mypath);
},
})();

Add class="flex" to each of your anchor tags.

Related

How can I add a delay to a button in Polymer?

I've stated creating a Polymer-based webpage and I'd like to add a link to the paper-button I created. I've figured out how to do it, but I'd like to add a delay to let users see the ripple animation after clicking it.
To link it to a webpage I used this code:
<paper-button raised> Polymer's Website </paper-button>
However, I don't know how to add a delay. Could someone help me? And, is there a better way to link the button to a webpage?
You can create an element that extends native HTML a tag and use paper-ripple element if you want to customize the ripple effect. Another solution is to add an event to you paper-button and use a setTimeout to delay your action
goto:function(){
setTimeout(function(){
window.location.href = 'http:\\www.google.com';
},1000);
}
<paper-button raised on-click="goto"> Polymer's Website </paper-button>

Issue with two-way binding inside dom-repeat in Polymer 1.0

I have a simple template like this
<template is="dom-repeat" items="[[items]]">
<paper-button active="{{item.selected}}" toggles raised>
<span>[[item.selected]]</span>
</paper-button>
</template>
If I activate the first paper-button in the list by tapping it and then call
this.set('items.0.selected', !this.items[0].selected);
It gets deactivated.
But then if I try the exact steps above again, the button doesn't get deactivated, which makes the button state and the selected value out of sync.
Why is it doing this? The issue can be replicated over here.
Interesting question. So I tried to use a single paper-button binding to a single item instance and it turned out to be working fine, which got me thinking that it might have something to do with path binding inside an array.
So I then added a tap handler to the paper-button and every time it's tapped, do a notifyPath on the selected subproperty path with the value of itself -
this.notifyPath('items.0.selected', this.items[0].selected);
And it works.

Polymer core-item selected issue

Code can be found here: https://ele.io/MikeFielden/cw-style-demo-menu
What Im trying to achieve here is to have a left nav component that I can include on many pages with an attribute on the tag selected that I can use to key off of and select the corresponding core-item.
For the life of me I cannot get it working. I guess I'm confused about piercing the shadow DOM from within js? Not really sure what the best approach here is.
There are some issues with your code.
The whole menu template should look like (note the setting of selected attribute on paper-item):
<core-menu id="nav">
<template repeat='{{node in nodes}}'>
<paper-item id="{{node.name | lowercase}}" selected='{{selected == node.name}}'>
{{node.name}}
</paper-item>
</template>
</core-menu>
I did not get why you needed two nested templates, so I simplified things a bit. Now the only thing left to do is to set the selected attribute of your demo menu to the proper name (id is not needed at all, it’s fine comparing items by names):
<cw-style-demo-menu selected="Assets">
Full live preview: http://plnkr.co/edit/E2B94tfAhJXnPZrusjtz?p=preview

paper-radio-group buttons inside a template possible?

I'm creating a project with Polymer and have the following code:
<paper-radio-group>
<template repeat="{{answer in answers}}">
<p>
<paper-radio-button name="{{answer.choice}}" label="{{answer.choice}}"></paper-radio-button>
</p>
</template>
</paper-radio-group>
I have a list of answers that I want to use in the paper-radio-group. Displaying this works fine. Every item in the answers array is displayed as a paper-radio-button.
The problem is that they are not connected to each other. So, when selecting one paper-radio-button, another is not deselected. This is probably because the paper-radio-group tag is outside the template tag. But placing it inside would make it repeat like the paper-radio-button and that's not going to work either.
Is there a way to get this to work? Or is it not possible?
The <paper-radio-group> expects <paper-radio-button> as it's children. When you wrap them in other elements like <p> the <paper-radio-group> can't manage the state.
The <template> element is is not actually included in the DOM and doesn't get in the way when the elements are rendered.

Create Anchor Element in polymer

Is it possible to create an element that will be used as an anchor in polymer. So for example
<template repeat="{{ content in contentitems }}">
<div id="{{ content.id }}">{{content.stuff}}</div>
</template>
Would it be possible to create a hyperlink to the content#id anchor like http://example.com/#someid
Alternatively, we can query that element with querySelector like the below and then scroll it into view if necessary with JavaScript. I'd rather not have to use a JS router however for anchor hyperlinking?
scrollIntoViewFunc(document.querySelector("html /deep/ #someid"))
Here's an actual URL I want to get working: http://megawac.github.io/status-whiskey/#status-408
The Web Component gods (aka Blink engineers) have decided that anchors inside of shadow-roots will not automatically scroll into view like they do in the main document. For this reason, I believe you will have to do something like you showed to handle this in JavaScript.
After brief searching, I couldn't find a reference to this question in the spec, it really needs to be spelled out somewhere.
If you come up with general solution, elementize it and share it back to the community. =P
Let's say you have a simple-element with some child elements with ids as anchors:
<simple-element>
<div id="anchor1"></div>
<div id="anchor2"></div>
</simple-element>
Then you can make a function to scrollIntoView when the hash changes:
window.addEventListener('hashchange', function() {
let targetElement = document.querySelector('simple-element').$[location.hash.substr(1)];
if(targetElement) {
targetElement.scrollIntoView();
}
}, false);