PolymerElements/paper-radio-group

Issues with polymer 1.0 paper-radio-group dom-repeat templates and the selected property

Closed this issue ยท 10 comments

Hi,
I am having issues in polymer 1.0 with the paper radio group, specifically when using the selected attribute, but only when the paper-radio-buttons contained within are in a dom-repeat template.

Also note that If any dom-repeat template breaks, all break paper-radio-group dom-repeat templates break.
i.e if second group below is commented out, the first one works, if it is included, both the first and second templated groups break. Selected attribute always works on non-templated radio buttons in the group.

<p>works</p>
<paper-radio-group>
  <template is="dom-repeat" items="{{sizes}}">
    <paper-radio-button name="{{item.name}}" >{{item.name}}</paper-radio-button>
  </template>
</paper-radio-group>

<p>Doesn't work</p>
<paper-radio-group selected="Large">
  <template is="dom-repeat" items="{{sizes}}">
    <paper-radio-button name="{{item.name}}" >{{item.name}}</paper-radio-button>
  </template>
</paper-radio-group>

<p>works</p>
<paper-radio-group>
  <paper-radio-button name="Small" >Small</paper-radio-button>
  <paper-radio-button name="Medium" >Medium</paper-radio-button>
  <paper-radio-button name="Large" >Large</paper-radio-button>
</paper-radio-group>

<p>works</p>
<paper-radio-group selected="Large">
  <paper-radio-button name="Small" >Small</paper-radio-button>
  <paper-radio-button name="Medium" >Medium</paper-radio-button>
  <paper-radio-button name="Large" >Large</paper-radio-button>
</paper-radio-group>

and defining the equivalent sizes array in ready:

ready: function() {
this.sizes = [{name:'Small'},{name:'Medium'},{name:'Large'}];
}

On a side note also, i am trying to set vertical layout to the buttons (), which i can do using the @apply(--layout-vertical); style, however alignment is forced in flex-direction: column. Only way i can get it to align correctly with the radio buttons with their labels is to force flex-direction: row using !important. Is there a good way of toggling vertical alignment?

paper-radio-button[vertical="true"] { @apply(--layout-vertical); flex-direction: row !important; }
Many thanks,
Grant.

jlg7 commented

+1 regarding the usage of paper-radio-group with dom-repeat. The distributed dom does not appear ready when the index is obtained. If a domReady event still isn't available, perhaps flushing the dom using Polymer.dom.flush() or adding addl. latency to the async might be needed when selected is changed.

m4b commented

I've noticed similar problems when using a dom-repeat inside a <paper-radio-group>; it reports an error on the checked attribute for some reason.

The workaround proposed by @jongeho1 did the trick for us: Have the application wait until the browser event loop returns before setting the 'selected' property.

I identified another issue with <paper-radio-group> and dom-repeat: The paper-radio-button sets the _selectedIndex to 0 at initialization. At that point of time, nodes[0] is the template. Hence the paper-radio-group sets the checked attribute on the template instead of the first paper-radio-button.
Worse, it's now no longer possible to select the first paper-radio-button because paper-radio-group._selectIndex checks if the requested new index is the same as the formerly set index.
Deactivating this check works around this issue:

     _selectIndex: function(index) {
-      if (index == this._selectedIndex)
-        return;
+      // Workaround for bug https://github.com/PolymerElements/paper-radio-group/issues/8
+      //if (index == this._selectedIndex)
+      //  return;

       var nodes = this.items;

@ghawkins-pulsemining I think the original issue is fixed in the latest release (1.0.2). Would you mind double checking it's okay on your end? Thanks!

@ghawkins-pulsemining For displaying buttons veritcally, all you need is to set display:inline-block:

paper-radio-button {
  display: inline-block;
}

Looks like this:
screen shot 2015-06-15 at 2 23 32 pm

m4b commented

confirmed this fixed on FF and Chrome, nice job. I can't seem to initially select the first element (I can initially select the 2nd, 3rd, etc.), but quickly testing, so could be something else.

Yay! I had this, which selects the first item on all the things, so maybe your example is grumpy:

<template is="dom-bind" items="{{sizes}}" id="t">

  <paper-radio-group selected="Small">
    <template is="dom-repeat" items="{{sizes}}">
      <paper-radio-button name="{{item.name}}" >{{item.name}}</paper-radio-button>
    </template>
  </paper-radio-group>

  <paper-radio-group selected="Large">
    <template is="dom-repeat" items="{{sizes}}">
      <paper-radio-button name="{{item.name}}" >{{item.name}}</paper-radio-button>
    </template>
  </paper-radio-group>

  <script>
    document.getElementById('t').sizes = [{name:'Small'},{name:'Medium'},{name:'Large'}];
  </script>

</template>
m4b commented

selected="1" seems to work fine, etc. Maybe cause I'm using [[index]] (not even sure if that's allowed anymore ๐Ÿ˜ฎ )

<dom-module id="radio-group">
  <style>
  </style>
  <template>
    <paper-radio-group selected="0">
      <template is="dom-repeat" items="[[data]]">
        <paper-radio-button name="[[index]]">[[item.title]]</paper-radio-button>
      </template>
    </paper-radio-group>
    <iron-ajax auto url="http://jsonplaceholder.typicode.com/posts" handle-as="json" last-response="{{data}}">
    </iron-ajax>
  </template>
  <script>
    Polymer({
      is: 'radio-group',
      properties: {
        data: {
          type: Array,
          notify: true,
          observer: 'dataChanged'
        }
      },
      dataChanged: function(data) {
        console.log(data);
      }
    });
  </script>
</dom-module>

Awesome! Closing this! ๐Ÿ’ƒ ๐ŸŽ‰