3

(Backend developer trying to do some front end development here)

I have a simple HTML form with some text field inputs and a select menu. When the form is submitted I see the text field values hitting the web server but I don't see the value for the select menu hitting the server. The code for the select menu is:

<div class="mdc-select mdc-select--outlined mdc-select--with-leading-icon role-list">
  <i class="material-icons mdc-select__icon" tabindex="0" role="button">work_outline</i>
  <div class="mdc-select__anchor role-width-class">
    <i class="mdc-select__dropdown-icon"></i>
    <div id="role" class="mdc-select__selected-text" aria-labelledby="roles-select-label"></div>
    <div class="mdc-notched-outline">
      <div class="mdc-notched-outline__leading"></div>
      <div class="mdc-notched-outline__notch">
        <label id="roles-select-label" class="mdc-floating-label">Role</label>
      </div>
      <div class="mdc-notched-outline__trailing"></div>
    </div>
  </div>

  <div class="mdc-select__menu mdc-menu mdc-menu-surface role">
    <ul class="mdc-list">
      <li class="mdc-list-item" data-value="0">
        Painter
      </li>
      <li class="mdc-list-item" data-value="1">
        Electrician
      </li>
      <li class="mdc-list-item" data-value="2">
        Decorator
      </li>
    </ul>
  </div>
</div>

The select menu is a material design component as described here.

The Javascript I have associated to this component is:

mdc.select.MDCSelect.attachTo(document.querySelector('.role-list'));

const role = new mdc.select.MDCSelect(document.querySelector('.role-list'));

role.listen('change', () => {
    alert(`Selected option at index ${role.selectedIndex} with value "${role.value}"`);
});

A couple of questions I have straight off the bat:

  1. Should I be using <li> instead of <option> - the code above follows the examples shown on the website.
  2. Should there be a name attribute?
capo11
  • 790
  • 3
  • 11
  • 32

2 Answers2

1

Create a hidden input:

<input type="hidden" name="my_select" id="my_select" value="">

Then store the value there:

mdc.select.MDCSelect.attachTo(document.querySelector('.role-list'));

const role = new mdc.select.MDCSelect(document.querySelector('.role-list'));

role.listen('change', () => {
    document.getElementById('my_select').value = role.value;
});
Triby
  • 1,739
  • 1
  • 16
  • 18
  • It seems that the MDC select component does not work in the same way as the browser's native select. So your solution is probably the way to go. –  Dec 03 '19 at 01:12
  • MDC select component is not an input, but it saves its value on the value property of instanced element, so this should work. – Triby Dec 03 '19 at 02:10
  • Yes it does work, but it seems like a hack. They could have designed the component to work with the browser's native select somehow. Not sure why they didn't do that –  Dec 03 '19 at 02:43
  • 1
    MDCSelect is a big hack itself, because there's no browser's native way to make a nice stylized select, but yes, it would be nice to have that behaviour without additional code. – Triby Dec 03 '19 at 03:47
1

There is a new update to this in material documentation in additional information section. It suggests doing the same thing that the accepted answer says but with no JavaScript.

Just wanted to put this out there for new people referring to this.

Select with hidden input (for HTML forms)

For convenient submission of Select's value in HTML forms, a hidden input element may be added under the root element. The component will synchronize its value with that of the hidden input.

<div class="mdc-select mdc-select--filled demo-width-class">
  <div class="mdc-select__anchor">
    <!-- Rest of component omitted for brevity -->
  </div>
</div>