How to dynamically modify <select> in materialize css framework
According to the Docs on Materialize Forms:
In addition, you will need a separate call for any dynamically generated select elements your page generates
So the best way is to just re-bind the generated select with an additional call to .material_select()
.
For re-usability, you can set up a listener when the elements have changed and then trigger that listener whenever you update the original select
// 1) setup listener for custom event to re-initialize on change$('select').on('contentChanged', function() { $(this).material_select();});// 2a) Whenever you do this --> add new option$selectDropdown.append($("<option></option>"));// 2b) Manually do this --> trigger custom event$selectDropdown.trigger('contentChanged');
This has the benefit of only needing to update the particular select element that has changed.
Demo in jsFiddle & Stack Snippets:
$(function() { // initialize $('.materialSelect').material_select(); // setup listener for custom event to re-initialize on change $('.materialSelect').on('contentChanged', function() { $(this).material_select(); }); // update function for demo purposes $("#myButton").click(function() { // add new value var newValue = getNewDoggo(); var $newOpt = $("<option>").attr("value",newValue).text(newValue) $("#myDropdown").append($newOpt); // fire custom event anytime you've updated select $("#myDropdown").trigger('contentChanged'); });});function getNewDoggo() { var adjs = ['Floofy','Big','Cute','Cuddly','Lazy']; var nouns = ['Doggo','Floofer','Pupper','Fluffer', 'Nugget']; var newOptValue = adjs[Math.floor(Math.random() * adjs.length)] + " " + nouns[Math.floor(Math.random() * nouns.length)]; return newOptValue;}
body { padding: 25px}
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.96.1/css/materialize.min.css" rel="stylesheet"><script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.96.1/js/materialize.min.js"></script><button class="waves-effect waves-light btn" id="myButton"> Add New Option to Dropdown</button><select id="myDropdown" class="materialSelect"> <option value="Happy Floof">Happy Floof</option> <option value="Derpy Biscuit">Derpy Biscuit</option></select>
You can reinitialize the select element after your data is bound successfully. Like so,
$('select').material_select();
Similar to this:
var next_id = $(".mtr-select");$.each(json, function(key, value) { $(next_id).append($("<option></option>").attr("value", value.id).text(value.name));});$(next_id).material_select();
It binds its option values to new ul>li
element by creating the dom object on load.
This is a valid solution for MaterializeCss v0.96.1. In version 0.97.0 it doesn't work: seems that there is a bug that appends a caret in the HTML.
Here the code for v0.97.0:
$(document).ready(function() { // Initialize $('select').material_select(); $("button").click(function() { // Clear the content $("select").empty().html(' '); // And add a new value var value = "New value"; $("select").append( $("<option></option>").attr("value",value).text(value) ); // Update the content clearing the caret $("select").material_select('update'); $("select").closest('.input-field').children('span.caret').remove(); }); });
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/css/materialize.min.css" rel="stylesheet"><script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.0/js/materialize.min.js"></script><button class="btn-large blue waves-effect waves-light">Change</button><div class="input-field"> <select> <option>Option 1</option> <option>Option 2</option> <option>Option 3</option> </select></div>