• Thanks, that works. I will use that for now. – user1432882 Mar 18 '15 at 21:52
  • You should review answers, the correct flagged one works only for old versions of materialize. – Danfoa Sep 11 '18 at 14:44
  • 7 Answers7

    50

    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>
    KyleMit
    • 30,350
    • 66
    • 462
    • 664
    • 1
      Just a note: you have to subscribe to the `contentChanged` before you `trigger()` it if you're doing it within a method for Angular2 w/ TypeScript ;) – Levi Fuller Jun 13 '16 at 04:31
    • This is outdated! $(this).material_select(); no longer works. The right function call is $(this).formSelect(); – btomtom5 Oct 09 '21 at 06:15
    9

    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.

    Robbie Wxyz
    • 7,671
    • 2
    • 32
    • 47
    nimsrules
    • 2,026
    • 20
    • 22
    6

    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>
    Davide Caruso
    • 104
    • 2
    • 5
    4

    This works for Materialize 1.0.0-rc.1 :

    the situation: I have two fields; first is to select a category

    <select name="category" id="category">
        <option value="0">Choisissez une Catégorie</option>
        <option value="1">Audios</option>
        <option value="2">Vidéos</option>
        <option value="3">Applications</option>
        <option value="4">Jeux Vidéos</option>
    </select>
    

    after category is selected, the second select id="subcategory" is populated with good subcats according to the parent category:

    <select name="subcategory" id="subcategory" disabled="disabled">
        <option value="0">Choisissez une sous-catégorie</option>
    </select>
    
    var subCategoriesNames = ['Tout', ['Tout', 'Musiques', 'Concerts', 'Comédies'], ['Tout', 'Films', 'Séries TV', 'Emissions TV', 'Documentaires', 'Animations', 'Animations Séries', 'Concerts', 'Sports'], ['Tout', 'Livres', 'Magazines', 'Presses', 'Mangas', 'BD'], ['Tout', 'Formations', 'Android', 'Windows', 'Linux', 'Web', 'Emulateurs'], ['Tout', 'Android', 'Windows', 'Consoles', 'Linux']],
    subCategoriesIds = ['1', ['2', '3', '4', '5'], ['6', '7', '8', '9', '10', '11', '12', '13', '14'], ['15', '16', '17', '18', '19', '20'], ['21', '22', '23', '24', '25', '26', '27'], ['28', '29', '30', '31', '32']],
    idx = 0,
    subsName;
    
    $(document).ready(function(){
        $('#category').on('change', function(){
            idx = this.selectedIndex;
            if(idx > 0){
                $('select#subcategory').attr('disabled', false);
                for(subsName in subCategoriesNames[idx]) $('select#subcategory').append('<option value="'+subCategoriesIds[idx][subsName]+'">'+subCategoriesNames[idx][subsName]+'</option>');
            }else{
                $('select#subcategory').attr('disabled', true);
            }
            var subcatSelectElem = document.querySelectorAll('#subcategory');
            var subcatSelectInstance = M.FormSelect.init(subcatSelectElem, {});
        })
    });
    
    Huntr
    • 59
    • 1
    • 5
    3

    Hi as you are using materialize framework, using simple generates other container elements for the same. hence using jquery select tag wont do the required task you need

    I found this which works fine for me

        <select class="className"></select> 
        **$('.className').formSelect().append($('<option>'+data[i]+'</option>'))**
    

    hope this works for you too

    2

    In Materialize v1.0.0, all you have to do is call $('.yourSelect').formSelect(); after removing or adding option elements from your select element.

    jsea
    • 3,859
    • 1
    • 17
    • 21
    0
    $('select').material_select(); // for initializing the material select box
    $("select").closest('.input-field').children('.select-wrapper').children("span").html("");
    
    Dhia
    • 10,119
    • 11
    • 58
    • 69
    • 1
      While this code snippet may solve the question, [including an explanation](https://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations! – Box Box Box Box Jun 02 '16 at 12:16