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.
Related
In polymer, let's say I have a container element <x-container>, and two child elements <a-child>, <b-child>. In an element, I want to be able to specify that it contains either <a-child> or <b-child> (it will never have both).
For example, it could look like:
1. <x-container><a-child></a-child></x-container>
or,
2. <x-container><b-child></b-child></x-container>.
Since <x-container> has a lot of code, I don't want to duplicate it, but want to be able to use an <x-container> like this:
<x-container type = 'a-child'></x-container> which would then have the same behavior as the first item mentioned. How could I achieve this functionality?
Just instanciate it when you have the information which one its going to be!
//in your x-container component
observers: ['_typeChanged(type)'],
_typeChanged: function(type) {
var child = this.create(type);
Polymer.dom(this.root).appendChild(child);
}
Or you use a slot then you could do smth like this
parent component
<x-container>
<template is="dom-if" if="[[_isA()]]"><a-child></a-child></template>
<template is="dom-if" if="[[_isB()]]"><b-child></b-child></template>
</x-container>
and in your x-container´s template just simply put a slot the child will be rendered within the slot
<slot></slot>
<div ng-repeat="item in items | limitTo:$parent.limit=($parent.limit||5)">
...
<a ng-if="$last" ng-bind="$parent.limit===Infinity ? 'Read Less':'Read More'" ng-click="$parent.limit=$parent.limit===Infinity?5:Infinity"></a>
</div>
So the initial limit is only 5 items, and clicking the link changes the text between Read more/Read less. But ngRepeat doesn't pick up on the change and add/remove items. I want ngRepeat to update when I change $parent.limit variable. I'd like to avoid using the controller, if possible.
The ng-repeat directive I believe creates another scope under it for it's child items. So then you would not be talking to the same parent that's referred to in the <div> element. So in your <a> tag you may need to talk to the parent's parent scope.
So try $parent.$parent instead of just $parent within your anchor tag inside of your ng-repeat.
Of course doing this will make the AngularJS gods shed a tear, so I recommend creating a controller or calling a method in your ng-click that will propagate up to the current controller for his template. Then you can move all of that logic outside of your template.
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.
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
I have been trying create a polymer-element that generates a ul list based on an ajax request and then renders the "li" elements based on templates that can somehow be passsed in.
It's basically an attempt to make a polymer rebuild of the 'select2' library for autocompletion.
So, the base template I have so far looks like this:
<polymer-element name="auto-complete" attributes="url_base item_template">
<aj-ax id="xhr" url="{{url_base}}" params="{}" handle_as="json" on-ajax-response="{{handle_res}}" on-ajax-error="{{handle_err}}"></aj-ax>
<input id="eingabe" type="text" on-keyup="{{process_request}}" on-blur="{{hide_dropdown}}"/>
<div id="dropdown" hidden?="{{hide}}">
<ul>
<template repeat="{{i in items}}">
<li> i.text
<!--
the process_request handler makes the ajax request and sets
the "items" and un-hides the dropdown.
the above works, but I want to make it more generic so that
you can pass in a template that reads the item model such as
<template ref="{{item_template}}" bind></template>
where item_template is the ID of a template in some outside
scope
-->
</li>
</template>
</ul>
</polymer-element >
</div>
I've also tried to make a base auto-complete.html polymer-element and then extend it based on the auto-complete type...but to no avail.
Any thoughts, ideas?
I want to stick to declarative methods if possible and avoid having to build the DOM elements myself with document.createElement
Is that even possible?
thanks!
I've come up with a cool approach to do this actually!
http://jsbin.com/hesejipeha/2/edit
The main idea is that you conditionally render the your template once you've injected any child templates into the shadow DOM (and thus made it possible to call them by ref in scope!)