PolymerElements / paper-dropdown-menu

A Material Design browser select element
https://www.webcomponents.org/element/PolymerElements/paper-dropdown-menu
61 stars 107 forks source link

Pre-select item on <paper-dropdown-menu> doesn't works after a form reset #114

Open vmozhara opened 8 years ago

vmozhara commented 8 years ago

I'm using <paper-dropdown-menu> inside the iron-form. So, it works properly after the initial loading of a form and shows pre-selected value. But after the form reset - this value disappears. Moreover I can not select it again. 2 Here's the code to replicate that behavior:

<dom-module id="test-form">
  <template>
    <form is="iron-form" id="form">
      <paper-dropdown-menu label="Dropdown">
        <paper-menu selected="1" class="dropdown-content">
          <paper-item>Option A</paper-item>
          <paper-item>Option B</paper-item>
        </paper-menu>
      </paper-dropdown-menu>
      <paper-button on-tap="reset">Reset</paper-button>
    </form>
  </template>
</dom-module>

<script>
  (function () {
    Polymer({
      is: 'test-form',

      reset: function () {
        this.$.form.reset();
      }
    });
  })();
</script>
SandeepSuddala commented 8 years ago

+1

cdata commented 8 years ago

Thanks, looks like this is causing a fundamental incompatibility between paper-dropdown-menu and iron-form. Resetting value needs to somehow affect the paper-menu.

cdata commented 8 years ago

/cc @notwaldorf

mrherndon commented 8 years ago

It also, in this same set up, doesn't validate after a form reset.

Edit: it looks like setting the paper-menu.selected to undefined on reset fixes both of these issues, but I wouldn't know how to put that into the paper-dropdown-menu code.

mercmobily commented 8 years ago

I've just watched some of you at the final panel @ Polymer Summit 2016. So, I somehow doubt this is gonna get seen soon. But... I have this in my TODO for tomorrow. Where should I start poking to get this fixed? Any hints will be most welcome, will provide a PR if I am successful!

mercmobily commented 8 years ago

OK, I looked into this (pushed it to 2AM!) paper-dropdown-menu contains a paper-input which is also registered with the form, and reset. When it's reset, it's set to ''. For some VERY STRANGE reason, once that happens you are then unable to re-set it with the OLD value.

At least now I can reproduce it with a simple tap... more on this once (and if) I've figured out why specifically the old value is somehow blacklisted.

mercmobily commented 8 years ago

OF COURSE! _onIronSelect in paper-dropdown-menu ISN'T fired, because even though the selection has disappeared from paper-dropdown-menu, the contained paper-listbox still "thinks" that it has the item selected, therefore NOT firing the event.

I am going to bed, but at this point it's a matter of making sure either that paper-listbox knows that the selection is changed, or... or I don't know. Will look into it tomorrow. But, at least now we know what's causing the problem...

mercmobily commented 8 years ago

Here is the rundown of the problem. iron-form does this:

        var value = this._customElementsInitialValues[i];
        if (value === undefined) {
          value = null;
        }
        el.value = value;

The last line is the important one. The issue here is that for paper-dropdown-menu the value property is read-only, and it depends on what's been selected. Ideally, I would put an observer on value in paper-dropdown-menu. However, that won't work because value is read-only.

The only solution I've come up with is the following:

1) Change iron-form so that it deals properly with read-only values. In this case:

        var value = this._customElementsInitialValues[i];
        if (value === undefined) {
          value = null;
        }
        if( el._setValue ) {
          el._setValue( value );
        } else {
          el.value = value;
        }

2) Add an observer to paper-dropdown-menu so that when value is changed using _setValue(), the contentElement is set:

    observers: [
      '_selectedItemChanged(selectedItem)',
      '_valueChanged(value)'
    ],

    _valueChanged: function( v ){
      // Handle reset. The "if" here is not strictly necessary
      if( v === null ){
          this.contentElement.selected = v;
      }
    },

Before I spam you -- and the iron-form guys -- with pull requests, please let me know if I missed something. I spent a while on this, and I really tried my best to come up with the most elegant, less far-fetching solution...

mercmobily commented 8 years ago

I forgot to mention that another possible solution would be to make iron-selector fire an event EVEN if the selected item hasn't changed. I tried that route, but -- frankly -- I didn't even manage to make it happen!

orenagiv commented 7 years ago

Any updates on this one?

middletonsp commented 7 years ago

I was able to fix the problem by using a paper-listbox inside the paper-dropdown-menu instead of a paper-menu. Every time the form is reset, I selected the paper-listbox by id and set its selected to null.

this.$.formWithDropDown.reset(); this.$.dropDownListbox.selected = null;

kaseyhinton commented 6 years ago

I think another way to fix this is to bind the value used in selected on the listbox to the value of the paper dropdown menu. This causes iron form reset to function as normal.

<paper-dropdown-menu value="{{val}}">
    <paper-listbox selected="{{val}}"></paper-listbox>
</paper-dropdown-menu>