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

Add option to set a specific value sent to the server for each option AND fire 'change' #195

Open mercmobily opened 7 years ago

mercmobily commented 7 years ago

At the moment, if you have a dropdown menu like this:

        <paper-dropdown-menu name="country" id="country" label="Your country">
          <paper-listbox attr-for-selected="choice" selected="[[countryDefault]]" class="dropdown-content">
            <paper-item choice="it">Italy</paper-item>
            <paper-item choice="fr">France</paper-item>
            <paper-item choice="">Other</paper-item>
          </paper-listbox>
        </paper-dropdown-menu>

After submitting, the server will receive "Italy", "France" or "". There is no way, at the moment, for it to behave like a native select box:

<select>
  <option value="it">Italy</option>
  <option value="fr">France</option>
  <option value="">Other</option>

The only option to send the right data to the server is by setting the "label" attribute for the various elements. However, this has the side effect that after making the selection, the user will see "it", "fr" etc.

This patch addresses that: if value is set for the selected item, THAT is the value considered and assigned to the paper-dropdown-menu.

I wouldn't have tortured you with a PR if I had found a way to do this in other ways... sorry!

mercmobily commented 7 years ago

Just so that you know how desperate I am for this patch, this is what I am in my main app :D

  ready: function(){

    /* MONKEY PATCH paper-dropdown-menu, IMPLEMENTS:
     * https://github.com/PolymerElements/paper-dropdown-menu/pull/195
     */
    var e = document.createElement('paper-dropdown-menu');
    var p = Object.getPrototypeOf( e );

    p._selectedItemChanged = function(selectedItem) {
      var value = '';
      var labelValue = '';
      if (selectedItem) {
        value = selectedItem.getAttribute('value') || selectedItem.label || selectedItem.getAttribute('label') || selectedItem.textContent.trim();
        labelValue = selectedItem.label || selectedItem.getAttribute('label') || selectedItem.textContent.trim();
      }
      this._setValue(value);
      this._setSelectedItemLabel(labelValue);
    };

  },
mercmobily commented 7 years ago

I just broadened the scope of this PR a little. Since this IS an element that is meant to be used in forms, it should fire up "change" when it's changed. I am writing an application where I monitor 'change' events, and while paper-input does it (well, it proxies the native "change" event), paper-dropdown-menu fails.

I noticed that 4 tests fail with this latest change. Maybe it's me doing something stupid; I can't figure out why they would though.