solarroi
solarroi

Reputation: 13

Dynamically created Select Options behave differently when called from a button vs directly in function Materialize CSS

  document.addEventListener('DOMContentLoaded', function() {
    var elems = document.querySelectorAll('select');
    var instances = M.FormSelect.init(elems, {});
  });


  const container = document.getElementById("stringcontainer");
  var select = createSelect(1);
  select.addEventListener('change', hello);
  container.appendChild(select);

  function add(){

    var select1 = createSelect(2);
    select1.addEventListener('change', hello);
    container.appendChild(select1);

  }

  
  function createSelect(num){
  
    //Create array of options to be added
    var array = ["Option 1","Option 2","Option 3"];
    //Create and append select list
    var selectList = document.createElement("select");
    selectList.id = "asp"+num;
    //selectList.className = "browser-default";
    selectList.required = true;
    selectList.innerHTML += "<option disabled selected>Choose Option</option>"
    //Create and append the options
    for (var i = 0; i < array.length; i++) {
        var option = document.createElement("option");
        option.value = array[i].split(" ").join("").toLowerCase();
        option.text = array[i]; 
        selectList.appendChild(option);
    }
        return selectList;
  }
  
  function hello(){
    console.log("Added EventListener");
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@materializecss/[email protected]/dist/css/materialize.min.css">


 <div class="row">
     <div id="stringcontainer"/>
 </div><!-- CLOSE ROW -->
 
 <div class="row">
   <div class="input-field col s3">
       <button id="astring" class="waves-effect waves-light btn-small" 
        onclick="add()">Add</button>
   </div>
 </div><!-- CLOSE ROW -->
  

<script src="https://cdn.jsdelivr.net/npm/@materializecss/[email protected]/dist/js/materialize.min.js"></script>

Called from JS as a function:

enter image description here

Called from a button with the same function:

enter image description here

The result is an invisible unstyled select when you press the button.

I'm using Materialize CSS. The eventListener is also not working properly when adding from the button also. It works for a console log but anything more complex like getSelectedValues(), it fails

I expected the Select to render the same way as the first image. Can anyone explain why this happening and offer a solution?

Upvotes: 0

Views: 46

Answers (1)

Geshode
Geshode

Reputation: 3764

The problem is, you apply the css only once in the beginning by using

document.addEventListener('DOMContentLoaded', function() {
    var elems = document.querySelectorAll('select');
    var instances = M.FormSelect.init(elems, {});
});

You have to do the same, each time you add a new select. So, the following should work the way you want it to.

document.addEventListener('DOMContentLoaded', function() {
    applyCSS();
});


const container = document.getElementById("stringcontainer");
var select = createSelect(1);
select.addEventListener('change', hello);
container.appendChild(select);

function add(){

  var select1 = createSelect(2);
  select1.addEventListener('change', hello);
  container.appendChild(select1);
  applyCSS();
}

  
function createSelect(num){
  
    //Create array of options to be added
    var array = ["Option 1","Option 2","Option 3"];
    //Create and append select list
    var selectList = document.createElement("select");
    selectList.id = "asp"+num;
    //selectList.className = "browser-default";
    selectList.required = true;
    selectList.innerHTML += "<option disabled selected>Choose Option</option>"
    //Create and append the options
    for (var i = 0; i < array.length; i++) {
        var option = document.createElement("option");
        option.value = array[i].split(" ").join("").toLowerCase();
        option.text = array[i]; 
        selectList.appendChild(option);
    }
    return selectList;
}
  
function hello(){
    console.log("Added EventListener");
}
 
function applyCSS(){
    var elems = document.querySelectorAll('select');
    var instances = M.FormSelect.init(elems, {});
}
  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@materializecss/[email protected]/dist/css/materialize.min.css">


 <div class="row">
     <div id="stringcontainer"/>
 </div><!-- CLOSE ROW -->
 
 <div class="row">
   <div class="input-field col s3">
       <button id="astring" class="waves-effect waves-light btn-small" 
        onclick="add()">Add</button>
   </div>
 </div><!-- CLOSE ROW -->
  

<script src="https://cdn.jsdelivr.net/npm/@materializecss/[email protected]/dist/js/materialize.min.js"></script>

I moved the code, which applies the CSS into applyCSS and then call it once in the DOMContentLoaded event listener and also each time the add function is called.

Upvotes: 1

Related Questions