Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"selectable" property only works for immediate children #42

Open
bendavis78 opened this issue Jun 23, 2015 · 12 comments
Open

"selectable" property only works for immediate children #42

bendavis78 opened this issue Jun 23, 2015 · 12 comments

Comments

@bendavis78
Copy link

I have nested loops that generate the items for my selector, so my markup looks like this (simplified for brevity):

  <iron-selector id="calendarSelector" selectable=".day-item">
    <template is="dom-repeat" items="{{months}}" as="month">
          <template is="dom-repeat" items="{{month.weeks}}" as="week">
            <div class="week">
              <template is="dom-repeat" items="{{week}}" as="day">
                <div label$="{{item.date}}" class="day-item">{{item.day}}</div>
              </template>
            </div>
          </template>
        </div>
    </template>
  </iron-selector>

This type of setup worked fine with core-selector in 0.5, but doesn't work in 1.0.

@klebba
Copy link

klebba commented Jul 27, 2015

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.

@dwagner4
Copy link

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>

@govis
Copy link

govis commented Aug 27, 2015

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);
}

@cdata
Copy link
Contributor

cdata commented Sep 28, 2015

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!

@bicknellr
Copy link
Contributor

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>

@govis
Copy link

govis commented Oct 30, 2015

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.

@javier-pepe
Copy link

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

@misjob
Copy link

misjob commented Nov 9, 2015

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
    ]
});

@cdata
Copy link
Contributor

cdata commented Jan 27, 2016

It is still not decided if iron-selector should support this style of nested items.

@bicknellr
Copy link
Contributor

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. WICG/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. :/

@ergo
Copy link

ergo commented Dec 7, 2016

Any news on this?

I would like to use iron selector like:

<iron-selector selectable="foo > item">
    <slot name="foo"></slot>
</iron-selector>

@dman777
Copy link

dman777 commented Jan 16, 2018

Any updates to this? I need it for divs paper-radio-group

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests