Open bendavis78 opened 9 years ago
Just hit this -- surprised to find this disparity between 0.5 and 1.0 -- the iron-selectable
docs make no mention of this limitation:
* This is a CSS selector sting. If this is set, only items that matches the CSS selector
* are selectable.
Seems to have gotten worse. I've been using the below pattern a lot.
<iron-selector selected="{{selectedmyitem}}">
<template is="dom-repeat" items="{{myitems}}">
<div>{{item}}</div>
</template>
</iron-selector>
<h2>{{selectedmyitem}}</h2>
myitems: {
type: Array,
value: function () {
return ["robert", "john", "sue"];
}
},
until recently this worked fine (in fact at the last demo before the customer). Now it is broken while the below works like a champ. Similar issue? dom-repeat templates don't work with iron-selector? Deadlines will force me to jerry-rig around this issue.
<iron-selector selected="{{selectedmyitem2}}">
<div>Allison</div>
<div>Cindy</div>
<div>Kathy</div>
</iron-selector>
<h2>{{selectedmyitem2}}</h2>
As a workaround I have been using IronSelectableBehavior directly and overriding its get items() method. I use jQuery, but it might also be doable with Polymer's dom helpers.
behaviors: [ Polymer.IronSelectableBehavior ], get items() { var nodes = $(this.selectable, this).get(); return Array.prototype.filter.call(nodes, this._bindFilterItem); }
First, I would like to apologize on behalf of the team for the un-announced regression of functionality from core-selector
0.5 -> iron-selector
1.0. We should have done a better job of communicating the change in behavior.
Second, we are interested in supporting this use case again. Since there are performance costs associated with the old behavior, we are probably going to add it back in as a boolean attribute that you can apply to any iron-selectable
implementing element.
Please leave any further feedback on this in this issue!
The current implementation uses queryDistributedElements
to select items; this means that items can come from any 'lighter' layer of light DOM, as long as those elements would be distributed to a content
element that is a child of the iron-selector
. With that in mind, does the request to find items by selecting from descendants extend through any number of light DOM layers as well?
In this example, only example-1
and example-3
are selectable in the current implementation. It sounds like the request is to at least make example-2
selectable also, but what about 4-6?
<!-- template for <nested-selector> -->
<iron-selector selectable=".item">
<example-1 class="item" />
<div>
<example-2 class="item" />
</div>
<content select=".content-1"></content>
<div>
<content select=".content-2"></content>
</div>
<content select=".content-3"></content>
<div>
<content select=".content-4"></content>
</div>
</iron-selector>
<!-- somewhere else -->
<nested-selector>
<example-3 class="content-1 item" />
<example-4 class="content-2 item" />
<div class="content-3">
<example-5 class="item" />
</div>
<div class="content-4">
<example-6 class="item" />
</div>
</nested-selector>
Not sure about the above scenario as my use cases are mostly straightforward with items being rendered by a dom-repeat template and need to be selectable.
I do have a question about queryDistributedElements and a "content element" - what if there's is none? In an element with a dom-repeat template and Polymer.IronSelectableBehavior like the one below queryDistributedElements returns and empty array and paper-items are not selectable:
<dom-module id="selectable-test">
<template>
<paper-material>
<template is="dom-repeat" items="[[itemData]]">
<paper-item>[[item]]</paper-item>
</template>
</paper-material>
</template>
<script>
Polymer({
is: "selectable-test",
properties: {
itemData: {
type: Array,
value: ["Item 1", "Item 2", "Item 3"]
}
},
behaviors: [
Polymer.IronSelectableBehavior
],
selectable: "paper-item",
listeners: {
'iron-activate': '_onIronActivate'
},
_onIronActivate: function (event) {
debugger;
}
});
</script>
</dom-module>
If wrapped in <iron-selector selectable="paper-item"></iron-selector>
it seems to be working now.
in version 1.0.8 iron-selector still does not handle the scenario first described by @bendavis78
I'm facing a similar issue with the following structure, iron-selector holding a dom-repeat, Inside another dom-repeat that holds the actual selectable items...
<iron-selector attr-for-selected="target-id" selectable="[selectable]:not(.target-disabled)">
<template is="dom-repeat" items="{{users}}" as="user" index-as="user_index">
<div id$="{{user.id}}">
<template is="dom-repeat" items="{{user.statistics}}" as="stats" index-as="stat_index">
<user-stats class$="[[stats.properties.class]]" target-id$="[[stats.target.id]]"
target="{{stats.target}}"
sizing="cover"
compact
selectable$="[[stats.isEditable]]">
Modifying, https://github.com/PolymerElements/iron-selector/blob/master/iron-selectable.html#L220-L224
_updateItems: function() {
var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
nodes = Array.prototype.filter.call(nodes, this._bindFilterItem);
this._setItems(nodes);
},
Into
_updateItems: function() {
var nodes = this.selectable
? Polymer.dom(this).querySelectorAll(this.selectable)
: Polymer.dom(this).queryDistributedElements('*');
nodes = Array.prototype.filter.call(nodes, this._bindFilterItem);
this._setItems(nodes);
},
Solved it, please note that extending the behavior did not worked for me, had to directly edit the element, which is not ideal, since when its updated, changes are replaced... it would be great to implement the solution into the component though, thanks
Extending actually works fine (v1.0.8). Also voting for implementing it in the component.
var MySelectableBehaviorImpl = {
_updateItems: function() {
var nodes = this.selectable
? Polymer.dom(this).querySelectorAll(this.selectable)
: Polymer.dom(this).queryDistributedElements('*');
nodes = Array.prototype.filter.call(nodes, this._bindFilterItem);
this._setItems(nodes);
}
};
var MySelectableBehavior = [
Polymer.IronSelectableBehavior,
MySelectableBehaviorImpl
];
(function() {
'use strict';
Polymer({
is: 'my-selector',
behaviors: [
MySelectableBehavior
]
});
It is still not decided if iron-selector
should support this style of nested items.
In the Shadow DOM spec, there's a section about HTMLSlotElement.prototype.getAssignedNodes
which mentions that you can optionally pass an object {flatten: true}
and get the distributed nodes. However, there's currently no formally documented mechanism for learning about changes to the distributed content of a slot. w3c/webcomponents#288 is tracking this issue and the result of that discussion will probably play a role here since the options they've mentioned have different timing and might require listening in multiple ways to be sure all DOM changes are caught. :/
Any news on this?
I would like to use iron selector like:
<iron-selector selectable="foo > item">
<slot name="foo"></slot>
</iron-selector>
Any updates to this? I need it for divs paper-radio-group
I have nested loops that generate the items for my selector, so my markup looks like this (simplified for brevity):
This type of setup worked fine with
core-selector
in 0.5, but doesn't work in 1.0.