32

I've read through the Components listing and read through the CSS provided, but I don't see any mention of select boxes - just regular inputs; text, radio, checkbox, textarea, etc.

How do you use Material Design Lite with a select box? Using the classes for a regular text input gets you halfway there, but it is certainly not correct.

Chase
  • 3,009
  • 3
  • 17
  • 23

10 Answers10

49

This worked pretty well for me (using fuel as an example):

<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
<script src="https://code.getmdl.io/1.3.0/material.min.js"></script>
      <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
        <select class="mdl-textfield__input" id="octane" name="octane">
          <option></option>
          <option value="85">85</option>
          <option value="87">87</option>
          <option value="89">89</option>
          <option value="91">91</option>
          <option value="diesel">Diesel</option>
        </select>
        <label class="mdl-textfield__label" for="octane">Octane</label>
      </div>

No libraries or anything needed just the standard MDL CSS and JavaScript.

Grim
  • 1,938
  • 10
  • 56
  • 123
John Knotts
  • 510
  • 4
  • 5
  • 6
    I found this site: http://creativeit.github.io/getmdl-select/ With different variations and options. Also, using standard MDL. – chimos Apr 05 '18 at 10:06
  • 1
    I do not recommend getmdl-select. Just attempted to use it and encountered annoying bugs with the display order/depth. – NGauthier Nov 19 '21 at 18:27
14

For now, what I did was a menu in JavaScript. I needed to do this in JavaScript anyway for my purposes, so it wasn't an issue to just use a menu instead of a drop down. Hope you find it useful!

<div id="insert-here"></div>

<script>
var onSelect = function(){
  this.button.innerHTML = this.innerHTML;
}

var insertPoint = 'insert-here';
var numberOfDropdowns = 0;
function makeDropdown(options){
  // create the button
  var button = document.createElement('BUTTON');
  button.id = numberOfDropdowns; // this is how Material Design associates option/button
  button.setAttribute('class', 'mdl-button mdl-js-button');
  button.innerHTML = 'Default';
  document.getElementById(insertPoint).appendChild(button);

  // add the options to the button (unordered list)
  var ul = document.createElement('UL');
  ul.setAttribute('class', 'mdl-menu mdl-js-menu mdl-js-ripple-effect');
  ul.setAttribute('for', numberOfDropdowns); // associate button
  for(var index in options) {
    // add each item to the list
    var li = document.createElement('LI');
      li.setAttribute('class', 'mdl-menu__item');
      li.innerHTML = options[index];
      li.button = button;
      li.onclick = onSelect;
      ul.appendChild(li);
  }
  document.getElementById(insertPoint).appendChild(ul);
  // and finally add the list to the HTML
  numberOfDropdowns++;
}

var optionsA = ["a", "b", "c", "d"];
makeDropdown(optionsA);
var optionsB = ["e", "f", "g", "h"];
makeDropdown(optionsB);
</script>

jsFiddle link: https://jsfiddle.net/zatxzx6b/3/embedded/result/

Jack Davidson
  • 4,613
  • 2
  • 27
  • 31
5

I ran into the same issue as well. Implementing yourself is always great but if you want to save time, this library did a pretty good job. https://github.com/MEYVN-digital/mdl-selectfield. Simply add this along with JS file in the <head>:

<div class="mdl-selectfield mdl-js-selectfield">
  <select id="myselect" name="myselect" class="mdl-selectfield__select">
    <option value=""></option>
    <option value="option0_value">option 0</option>
    <option value="option1_value">option 1</option>
  </select>
  <label class="mdl-selectfield__label" for="myselect">Choose option</label>
</div>

JSFiddle

novasaint
  • 700
  • 8
  • 13
3

I'm using this one in an Angular2 app. It was easy to setup/install/use:

https://github.com/mebibou/mdl-selectfield

npm install mdl-selectfield

Then include the CSS and JS:

<link rel="stylesheet" href="./node_modules/mdl-selectfield/dist/mdl-selectfield.min.css">

Then add classes to your HTML. Here's an example:

<div class="mdl-selectfield mdl-js-selectfield">
  <select id="gender" class="mdl-selectfield__select">
    <option value=""></option>
    <option value="option1">option 1</option>
    <option value="option2">option 2</option>
  </select>
  <label class="mdl-selectfield__label" for="gender">User gender</label>
  <span class="mdl-selectfield__error">Select a value</span>
</div>
theUtherSide
  • 3,338
  • 4
  • 36
  • 35
2

Project Polymer is by Google and its the best option for various components that are missing from Material Design lite. You can find details on how to get polymer elements here https://elements.polymer-project.org/guides/using-elements

Specifically, you can find a select dropdown web component here - https://elements.polymer-project.org/elements/paper-dropdown-menu?view=demo:demo/index.html

ChicagoSky
  • 1,290
  • 3
  • 22
  • 50
  • 6
    Thanks for the tip but it is a time sink to install/use Polymer. If you can't install it by simply including js and/or css then I ain't interested... – Ronnie Royston Oct 24 '15 at 21:38
  • I would not call polymer the "best option" for things not included in MDL. Polymer presents a great deal of overhead for simply styling and adding behavior to a ` – theUtherSide Jun 08 '16 at 00:15
1

I use a jquery code and class css to input type text, like this:

jquery code:

$(document).ready(function () {
    $("select").change(function () {
        if ($('#' + $(this).attr("id") + ' option:selected').val() === '') {
            $(this).parent('div').removeClass('is-dirty');
        } else {
            $(this).parent('div').addClass('is-dirty');
        }
     });
});

in html (the first option must by empty ) :

<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
            <select id="example" class="mdl-textfield__input">
                <option value=""></option>
                <option value="1">Option</option>
            </select>
            <label class="mdl-textfield__label is-dirty" for="example">example</label>
        </div>
Pedro Dias
  • 44
  • 3
0

I know this post is old. But, I had a different solution which worked great for me, and wanted to share.

I built on @John Knott's solution to use mdl textfield with select as mdl-textfield__input + @user2255242's solution of a menu but without the js involved.

Here is a fiddle illustrating the solution.

JS fiddle for MDL select box

HTML - I have used a textfield + a menu (ul + li) to act as the select, the css does the rest.

<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
<script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>


<div id="app">

  <div class="sorter-holder">

    <!-- the textfield, notice the readonly on input -->
    <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
      <input class="mdl-textfield__input" type="text" v-model="sortBy" id="sorterHolder" readonly>
      <label class="mdl-textfield__label" for="sorterHolder">Sort by</label>
    </div>

    <!-- menu which will act as the options of select. The menu is for the input, and not the div which has mdl-textfield class -->
    <ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect sorter-menu" for="sorterHolder">
      <li class="mdl-menu__item" v-for="srtr in sortables" @click="update(srtr)">{{ srtr }}</li>
    </ul>

  </div>

</div>

CSS - the main part is the css

/* 
The menu is positioned absolute, and it's positions are calculated dynamically (I think). I wanted it to extend for the entire width of input, and for that needed a relative parent.
Also, the display inline-block was not required in where I actually implemented it. Over there, it was block. So, this might need to change according to layout. */
.sorter-holder {
  position: relative;
  display: inline-block;
}

/* just giving them a width of 100% to extend for the entire textfield */
.sorter-holder .mdl-menu__outline,
 .sorter-holder .mdl-menu__container, 
 .sorter-menu {
   width: 100% !important;
}

VueJS - the example is in Vue JS, but can be replicated easily in any other framework, as the main thing is performed by HTML + CSS

new Vue({
  el: "#app",
  data: {
    sortables: [
      'Name (A-Z)',
      'Name (Z-A)',
      'Newest First',
      'Oldest First'
    ],
    sortBy: null
  },
  methods: {
    update: function (sortBy) {
      this.sortBy = sortBy;
    }
  }
})

Why I did it this way?

Menu looked visually better than the default browser's select box. But, didn't want to do some css magic on the select's option. And, this seemed easier than that.

This can be done in a lot of other ways. I found it better and implemented in one of my projects. Hope it helps! :)

Jeevan MB
  • 148
  • 1
  • 11
0

You can sort of recreate it using already existing components. Using the textfield and menu to be specific.

  • EXAMPLE: https://repl.it/@bryku/AngelicUnsightlyUsername

  • NOTE: I added mdl-select to the mdl-textfield and mdl-select-option to the mdl-menu__item.

    <div class="mdl-textfield mdl-select mdl-js-textfield mdl-textfield--floating-label">
      <input class="mdl-textfield__input" type="text" id="formState" name="pageCollection" value="">
      <label class="mdl-textfield__label" for="formState">State...</label>
      <ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="formState">
          <li class="mdl-menu__item mdl-select-option">CA</li>
          <li class="mdl-menu__item mdl-select-option">WA</li>
          <li class="mdl-menu__item mdl-select-option">IA</li>
      </ul>
    

However, you still need to add some javascript.

var mdlAddon = {
    _select: function(){
        var e = document.querySelectorAll('.mdl-select-option');
        for(var i = 0; i < e.length; i++){
            e[i].addEventListener('click', function(event){
                var value = event.target.innerText;
                var id = event.target.parentElement.getAttribute('for');
                var target = document.getElementById(id);
                    target.value = value;
                    target.parentElement.classList.add('is-dirty');
            });
        }
    },
}
mdlAddon._select();

This adds a event listener to all the mdl-select-option, but you can easily change it by adding the onclick="" if you want.

I would also suggest making it so the user can't physically type in the textbox.

var mdlAddon = {
    _select: function(){
        var e = document.querySelectorAll('.mdl-select-option');
        for(var i = 0; i < e.length; i++){
            e[i].addEventListener('click', function(event){
                var value = event.target.innerText;
                var id = event.target.parentElement.getAttribute('for');
                var target = document.getElementById(id);
                    target.value = value;
                    target.parentElement.classList.add('is-dirty');
            });
        }
        var e = document.querySelectorAll('.mdl-select');
        for(var i = 0; i < e.length; i++){
            e[i].addEventListener('keydown', function(event){
                event.preventDefault();
            });
        }
    },
}
mdlAddon._select();

Just make sure to run it after the elements are loaded. This is pretty simply, but at least it doesn't require additional css when using MDL.

Dillon Burnett
  • 473
  • 4
  • 11
-1

Anyway, take a look how Angular Material team has implement it: https://material.angularjs.org/latest/#/demo/material.components.select

Yep, just like a input+dropdown

S Panfilov
  • 16,641
  • 17
  • 74
  • 96
-1

While the Google team is working on this, I needed to create a quick-and-easy solution to this problem and wrote a javascript/jquery function:

Material Design Lite--Select

trentsp
  • 19
  • 1