Access parent dom-repeat item on clicking child dom-repeat item - javascript

I am using polymer.I have array of objects it looks
[{
name:xxx,
address:yyy,
times:[
{start:12,
End:5
},
{start:2,
End:4
}
]
},
{//same format repeats
}
]
I used nested dom-repeat,
<template is="dom-repeat" items="{{pList}}" as="list">
<paper-item>
<paper-item-body two-line>
<div>[[list.address]]</div>
<div secondary>[[list.name]]</div>
</paper-item-body>
<template is="dom-repeat" items={{list.times}} as="time">
<paper-item-body on-tap="_handleTime" two-line>
<div>[[time.start]]</div>
<div>[[time.end)]]</div>
</paper-item-body>
</template>
</paper-item>
</template>
I have on tap function in second dom-repeat,so on taping below function is called,here I can access time object.
how can I access name and address which is in first dom-repeat using with 'e' reference as bellow?
I tried parentElement but its not working!
_handleTime:function(e) {
console.log(e.model.time); //displays time obj i.e {start:12,End:5} but I'm trying to get {name,address,{start,end}}
console.log(e.parentElement);//gives error
//I'm trying to get entire object like {name:xxx,address:yyy,times:[]}
}

var item = this.$.firstRepeat.itemForElement(e.target);
where firstRepeat is the id of the first dom-repeat,
check this example

Related

How do I access the dynamic template refs that are nested in Vue 3?

I have a custom list component gcl-list that uses a v-for to render a passed template for each item in an array. Ive nested one of these components in another and am trying to access refs on the children gcl-list-items to then edit the innerHTML but when I access that ref it gives me a string representation of the element which I cant edit the inner HTML. How would I access that childs span and change its innerHTML?
Output to console when logging childItemRefs.value:
Proxy
handler: {get: function, set: function, deleteProperty: function, has: function, ownKeys: function}
target: Array (2)
0 <span data-v-2b58c258>Three.One</span>
1 <span data-v-2b58c258>Three.Two</span>
Code:
<gcl-list :listArray="filteredDropdownItems">
<template v-slot="itemData">
<gcl-list-item
selectable
:indeterminate="itemData.item.indeterminate"
:checked="itemData.item.selected"
:iconStart="itemData.item.iconStart"
:iconEnd="itemData.item.iconEnd"
#click.stop
#click="onItemClick(itemData.item)"
>
<span :ref="el => itemRefs[filteredDropdownItems.indexOf(itemData.item)] = el">
{{ itemData.item.displayValue }}
</span>
</gcl-list-item>
<gcl-list v-if="itemData.item.childItems" :listArray="filteredChildren(itemData.item.childItems)">
<template v-slot="childItemData">
<gcl-list-item
selectable
nested
:checked="childItemData.item.selected"
:iconStart="childItemData.item.iconStart"
:iconEnd="childItemData.item.iconEnd"
#click.stop
#click="onChildItemClick(childItemData.item, itemData.item)"
>
<span :ref="el => childItemRefs[filteredChildren(itemData.item.childItems).indexOf(childItemData.item)] = el">
{{ childItemData.item.displayValue }}
</span>
</gcl-list-item>
</template>
</gcl-list>
</template>
</gcl-list>
```
[1]: https://i.stack.imgur.com/1dFTx.png

Unable to fetch multi selected values in paper listbox polymer3

I am trying get multiselected values in paper-list box polymer
<paper-dropdown-menu label="{{_getLabel('Activity Type')}}" id="fromMenu" on-paper-dropdown-close="fromAccountChanged" searchable="true">
<paper-listbox selected="{{value}}" id="ddtype" on-iron-select="SelectedType" attr-for-selected="value" selected="{{typeList}}" class="dropdown-content" slot="dropdown-content" multi>
<template is="dom-repeat" items="{{typeList}}">
<paper-item value="{{item}}">{{item}}</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu>
SelectedType(e){
var selectedItem = e.target.selectedItem;
console.log(selectedItem.value)
var product_value = selectedItem.value;
this.searchTypeString = selectedItem.value;
}
This is function that i am using to fetching values but only getting single value
You can use the selectedItems property to get the selected paper-item elements, or the selectedValues property to get the values of the selected paper-items. See the documentation for further information.

display data in specific order in polymer

In my polymer dom, each data object todo has multiple items and it also has a todo.idx. I would like to order the items according to its todo.idx, instead of their (random) ordering in the data. How can I do it with polymer?
In the polymer document, it mentions a sort function, but I couldn't find examples there. My current code is as follows.
<ol>
<template is="dom-repeat" items="{{todos}}" as="todo">
<li><span> {{todo.item}} </span> </li>
</template>
</ol>
You can sort items in polymer using the sort attribute, and in your case you would want to use nested templates so you can sort on the dom-repeat for a given todo's items:
<template is="dom-repeat" items="{{todos}}" as="todo">
<template is="dom-repeat" items="{{todo.items}}" as="item" sort="_sortItems">
<li><span>{{item}}</span></li>
</template>
</template>
You can then define your _sortItems function in same fashion as you would for a compare function in Array.prototype.sort():
_sortItems: function(a, b) {
if (a.idx < b.idx) { return -1; }
if (a.idx > b.idx) { return 1; }
return 0;
}

re-sort Polymer dom-repeat after change of value in child

I have a Polymer dom-repeat list where the children get sorted o.k. on the initial value.
When I change the a value inside of the child, the depending sort order of the list is not updated. How can I best achieve that?
<body>
<list-records></list-records>
<dom-module id="list-records">
<template>
<template is="dom-repeat"
items="{{records}}"
sort="sortByValue">
<single-record record="{{item}}"
base="{{base}}">
</single-record>
</template>
</template>
<script>
Polymer({
is: 'list-records',
properties: {
records: {
type: Array,
value: [
{number:1, value:4},
{number:2, value:2},
{number:3, value:3}]
}
},
sortByValue: function(a, b) {
if (a.value < b.value) return -1;
if (a.value > b.value) return 1;
return 0;
}
});
</script>
</dom-module>
<dom-module id="single-record">
<template>
<div>
Number: <span>{{record.number}}</span>
Value: <span>{{record.value}}</span>
<button on-tap="_add">+</button>
</div>
</template>
<script>
Polymer({
is: 'single-record',
properties: {
record: Object,
},
_add: function() {
this.set('record.value', this.record.value + 1);
}
});
</script>
</dom-module>
</body>
Background: In the real location based application I have a center location (lat, lng) and get a list of keys for locations around the center. I create a child for each key. The child uses the key to get lat,lng information from a database (async). Using the lat lng information from center and from the location, I can calculate the distance inside the child. The list should be ordered by the calculated distance.
In your single-record component, your record property does not allow two-way data binding, hence it won't change that record back to the list-records element. To enable two-way data binding, you must declare record property with notify:true.
properties: {
record: {
type: Object,
notify: true
}
}
Source: https://www.polymer-project.org/1.0/docs/devguide/properties
I had to add the notify parameter as pointed out by Neil and also 'observe' to the template (source: How to re run dom-repeat with sort when bool property changed in Polymer element).
<template id="list"
is="dom-repeat"
items="{{records}}"
sort="sortByValue"
observe="value">
Then it works as expected in the sample code above as well as in the real geo-location application :)

Polymer 1.0 dom-repeat display index starting at 1

I am using Polymer 1.0 to create a shopping/checkout cart. I have customers who may want to ship their order to multiple addresses. In the receipt, I need to list all the addresses with an index:
Address 1
John Doe
1234 Main St
...
Address 2
Jane Smith
999 Broadway
...
How do I get the index to start at 1 instead of 0?
<template is="dom-repeat" items="{{shipping_details}}" as="address">
<div>Address <span>{{index}}</span></div>
<div>{{address.name}}</div>
<div>{{address.line1}}</div>
</template>
This is a simplification of my actual code, but the principle is the same. I have tried to make a js function that takes the index as a parameter and sets the innerHTML to index++, but I don't know what event it should fire on or how to get it to call the function.
<div>Address <span on-some-event="displayIndex(index)"></span></div>
I am new to all of this, so you can't go in to too much detail about how to make this work. Thank you for your help in advance!
You can use a computed binding for this.
Instead of this:
<span on-some-event="displayIndex(index)"></span>
Do this:
<span>{{displayIndex(index)}}</span>
When displayIndex is this:
function (index) {
return index + 1;
}
Note:
displayIndex can be
a method on the element prototype
<dom-module id="cart-addresses">
<template is="dom-repeat" items="{{shipping_details}}" as="address">
<div>Address <span>{{displayIndex(index)}}</span></div>
<div>{{address.name}}</div>
<div>{{address.line1}}</div>
</template>
<script>
Polymer({
is: 'cart-addresses',
...
displayIndex: function(index) {
return index + 1;
}
...
});
</script>
</dom-module>
a method attached to an auto-binding template
<template is="dom-bind">
...
<template is="dom-repeat" items="{{shipping_details}}" as="address">
<div>Address <span>{{displayIndex(index)}}</span></div>
<div>{{address.name}}</div>
<div>{{address.line1}}</div>
</template>
</template>
<script>
var template = document.querySelector('template[is="dom-bind"]');
...
template.displayIndex = function (index) {
return index + 1;
};
</script>

Categories

Resources