Polymer multiple similar elements and click events - polymer

I am trying to build a custom polymer element which has a div like this
<core-menu>
<paper-item on-tap={{openPage}}><core-icon icon="add"></core-icon> Add Issues</paper-item>
<paper-item on-tap={{openPage}}><core-icon icon="view-list"></core-icon> View Issues</paper-item>
<paper-item on-tap={{openPage}}><core-icon icon="lock"></core-icon>Logout</paper-item>
</core-menu>
And this openPage function needs to provide this kind of operation
openPage: function(event, details, sender) {
console.log("open page called item "+ item);
}
I am not sure how to get the item clicked. Say, if I click on the Logout item, i would like the value of item to be a number, like something that could say that nth paper-item was clicked.
I dont know how to get this value from event or details or sender.
Thanks in advance

You can do something like this:
<core-menu>
<paper-item data-action-id="1" on-tap={{openPage}}><core-icon icon="add"></core-icon> Add Issues</paper-item>
<paper-item data-action-id="2" on-tap={{openPage}}><core-icon icon="view-list"></core-icon> View Issues</paper-item>
<paper-item data-action-id="3" on-tap={{openPage}}><core-icon icon="lock"></core-icon>Logout</paper-item>
</core-menu>
And then:
openPage: function(event, details, sender) {
console.log("open page called item "+ sender.target.attributes["data-action-id"]);
}
"sender.target" is returning paper-item

Related

Refresh dom-repeat on a change of sort mode - no mutation needed to array set for sort

I have a dom-repeat template and I want to be able to sort the list real time. So, the way I went about it is the way below. However, I need a way to refresh that dom-repeat when a user selects a new selection from paper-menu.
Typically, a modification to the result set array would do it. But in this case, a change in sorting the list doesn't require adding or removing anything in that array set(therefore no array mutation).
How could I get <template is="dom-repeat" items="[[pic.results173]]" as="url" sort="_sortList"> to refresh?
<paper-menu-button>
<paper-button class="dropdown-trigger" raised>
<iron-icon icon="visibility"></iron-icon>
<span>View By</span>
</paper-button>
<paper-menu id="viewMode" class="dropdown-content" selected="0">
<paper-item>Most Recent</paper-item>
<paper-item>Least Recent</paper-item>
<paper-item>Highest Price</paper-item>
<template is="dom-repeat" items="[[pic.results173]]"
as="url" sort="_sortList">
_sortList: function(first, second) {
var el = this.$.viewMode;
var listMode;
switch(el.selected) {
case 0:
listMode = this._mostRecent(first , second);
break;
}
return listMode;
},
The developers guide has your answer. Give your template an id (say id="list") and call this.$.list.render()

advanced data binding in Polymer

i have a little problem that i can not solve on my own.
I have custom element:
<dom-module id="station">
<template>
<country-iso-alpha3 id="country" selected={{country}}></country-iso-alpha3>
</template>
this custom element station has country property with CZE default value.
if we look in country-iso-alpha3 :
<paper-dropdown-menu>
<paper-menu class="dropdown-content" attr-for-selected="type" selected="{{selected}}" >
<paper-item type="CZE">
<span>CZE</span>
</paper-item>
<paper-item type="ENG">
<span>ENG</span>
</paper-item>
</paper-menu>
</paper-dropdown-menu>
properties of country-iso-alpha3 are:
properties: {
label: {},
selected: {},
},
what i am trying to achieve is that when user tap on paper item inside paper menu, property country in station element should update. But the only thing that is updated is selected attribute in station
Is there any way how to achieve this? Maybe this is already 3 way data binding.
I know, my english is not best and this is not so easy to demonstrate so if you do not undestand i can try to explain it a little bit better
In your country-iso-alpha3 element, configure selected to propagate changes upward. This can be done by setting notify: true.
properties: {
selected: {
type: String,
notify: true
}
},
By default, changes are not propagated to the parent element (docs).

Set selected item in paper-drop-down-menu?

I have this paper-dropdown-menu with one button:
<paper-dropdown-menu id="Default" label="My items">
<paper-menu id="DefaultDropDown" attr-for-selected="value" selected="{{selection}}" class="dropdown-content">
<paper-item value="5">Item 1</paper-item>
<paper-item value="6">Item 2</paper-item>
<paper-item value="7">Item 3</paper-item>
</paper-menu>
</paper-dropdown-menu>
<button onclick="clickEvent();">Click</button>
<script>
function clickEvent() {
$('#Default').selectedItem = -1;
}
</script>
I want in the event "clickEvent" you can set selection dropdown-menu to -1: noT selected item.
Any idea how?
The code I put javascript is only to illustrate the idea
The '#' here is redundant because $(...) only supports id anyway:
$('#Default').s...
The selection is maintained by the child component (<paper-menu>) in your case not the <paper-dropdown-menu> itself.
$('DefaultDropDown').selectIndex(-1);
I couldn't figure out from the docs whether deselecting is actually supported when multi is not set.

Polymer 1.0: Clickable item in dom-repeat to e.g. iron-page which contains further info (contact list)

I'm setting up a contact list in Polymer 1.0. When the user clicks on a name, there should be a (animated) page opened for further details. All of these data elements are pulled from an external .json file.
Two questions for this approach..:
1) where to begin? How do I wrap, for example, an iron-page or neon-animated-page around my current setup (which is searchable, which is also the -temporary- reason it's a dom-repeat instead of an iron-list):
<template id="resultlist" is="dom-repeat" items="{{data}}" filter="contactFilter">
<paper-item>
<paper-item-body two-line>
<div>{{item.name}}</div>
<div secondary>{{item.number}}</div>
</paper-item-body>
</paper-item>
</template>
2) For quick try-out with binding options I've created an paper-dialog (instead of an page behaviour) which displays further data for the chosen person... On top of that paper-dialog should the chosen name being displayed. But I only get the first name of the array in my .json file. How can I setup the code to display the {{item.name}} of the chosen item?
Ps. I'm aware of the contacts-app from Rob Dodson (https://github.com/robdodson/contacts-app), but I can't figure out how it should be done in Polymer 1.0.
Update 27.10.2015
After Hugo's answer I'm not able to get the solution to work in an dom-module structure.
Sorry for misunderstanding, but I can't figure out where I'm wrong.
Having to following:
phonebook.html, which acts like an index
...
<body unresolved>
<template is="dom-bind" id="application">
<neon-animated-pages selected="[[selected]]" entry-animation="fade-in-animation" exit-animation="fade-out-animation">
<contact-list></contact-list>
<contact-details></contact-details>
</neon-animated-pages>
</template>
<script>
var application = document.querySelector('#application');
application.selected = 0;
document.addEventListener('show-details', function() {
application.selected = 1;
});
document.addEventListener('show-list', function() {
application.selected = 0;
});
</script>
</body>
DOM-module contact-list.html, the list it self.
<dom-module id="contact-list">
<template>
<style include="phonebook-styles"></style>
<iron-ajax url="../data/data.json" handle-as="json" last-response="{{data}}" auto></iron-ajax>
<div class="container">
<h3>Contactlist:</h3>
<div class="template-container">
<template is="dom-repeat" id="templateUsers" items="{{data}}">
<paper-item on-tap="showDetails">
<paper-item-body two-line>
<div>{{item.name}}</div>
<div secondary>{{item.phonenumber}}</div>
</paper-item-body>
<div class="item-details-link">
<iron-icon icon="account-circle"></iron-icon>
</div>
</paper-item>
</template>
</div>
</div>
</template>
<script>
Polymer({
is: 'contact-list',
properties: {
selectedContact:{
type:Object,
value:function(){
return null;
}
}
},
showDetails: function(ev) {
var data = this.$.templateUsers.itemForElement(ev.target);
//alert(JSON.stringify(data)) // works with data chosen data selection...
this.selectedContact = data;
this.fire('show-details', this.selectedContact);
}
});
</script>
</dom-module>
DOM-module contact-details.html, the details-list.
<dom-module id="contact-details">
<template>
<!-- Do I need to declare the .json in my details module? -->
<iron-ajax url="../data/data.json" handle-as="json" last-response="{{data}}" auto></iron-ajax>
<paper-icon-button icon="arrow-back" on-tap="showList"></paper-icon-button>
<h3>Contact details</h3>
<template is="dom-repeat" items="{{data}}">
<div>{{selectedContact.name}}</div>
</template>
</template>
<script>
Polymer({
is: 'contact-details',
showList: function() {
this.fire('show-list');
}
});
</script>
</dom-module>
Everything, like the transitions, work. The chosen contact is also displayed in an alertbox (commented out in contact-list.html), but isn't forwarded to the contact-details.html page.
There are multiple steps to implement the solution:
Setup the neon animated pages ( one page would be the contact list, the other page would be the details )
Display the list of contacts ( you already have this one )
Add a "selectedContact" property to your element
Add a tap/click handler to the list items element and inside the handler set the selectedContact. You need to get the contact item from the DOM element clicked. ( Check an example here : http://jsbin.com/lofarabare/6/edit )
You can bind the contact details page elements to the selectedContact properties, e.g {{selectedContact.name}}
Inside the handler also Change the neon animated pages selected property to have it display the animation to the other page.
-- Extra feedback
I checked the way you handle events, feedback below:
Give the elements some id so you can add the event listener directly to them (e.g application.$.myContactList.addEventListener('show-detail',function(ev){...})
The way you fire the event from the contact-list is correct, however you are not reading the event data inside the event listener for the 'show-detail' event. The event listener receives the event as argument "ev". You can get the event data using ev.detail
With the event data (the selected contact) you can update your contact details component. Give it some id like 'details' and just update the 'selectedContact' property. **You need to declare the selectedContact in the details component, right now you don't have it there **

Access core-ajax response from within nested component?

I have a core-ajax element like so:
<core-ajax id="ds" auto url="address/to/data.json" response="{{data}}"></core-ajax>
Then a list element like so:
<my-items alarms="{{data}}"></my-items>
Which iterates through the data and displays it in another template:
<template repeat="{{item in items}}">
<my-item alarm="{{item}}"></my-item>
</template>
My question is, from within "my-item", how can I access the original {{data}}? For instance, if I wanted to get a count of the total items in a javascript function?
You need to pass that information into <my-item>.
If <my-item> also published a data property, you could pass it like this:
<template repeat="{{alarm in alarms}}">
<my-item alarm="{{alarm}}" data="{{alarms}}"></my-item>
</template>
or just the stats you need:
<my-item alarm="{{alarm}}" length="{{alarms.length}}"></my-item>
Polymer('my-item', {
dataChanged: function (e) {
console.log(this.data);
}
});
that should give you the data you need