apps script web app + materialize autocomplete problem

40 views
Skip to first unread message

Raf

unread,
Jun 19, 2024, 7:03:54 AM (10 days ago) Jun 19
to Google Apps Script Community
Hi,

I have problem with materialize autocomplete and dynamic table.
...it does not work.

To create html table I am using js document.createElement.

For test purposes I also created autocomplete in static element of the table. It works fine. 
image.png

When checking console (console.log(tbody)) html looks the same in both cases so in my opinion the problem can be with js event. 

console:
image.png



My code:

**********
HTML:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <meta charset="utf-8" />
<?!= include("page-css"); ?>
  <script type="text/javascript" src="autosearch.js"></script>  
  </head>
  <body>

        <footer class="page-footer #2196f3 red">
           <div class="container">
              <table>
                 <tr>
                 <h3 style="text-align: center; vertical-align: middle;">Requested projects:</h3>

                 </tr>
              </table>
           </div>
        </footer>
 
 
<br>
<br>


<div class="container-fluid" style="width:100%; font-size:13px;  padding:0px; margin:0px;">
   
      <table border = "1" id="tableData" class = "#eeeeee grey lighten-3" style="width:90%; margin: 0px auto; align: center;">
        <thead>

          <tbody>
          <tr>
            <td>
Static autocomplete for test purposes:
              <th>
                      <div class="input-field">
                        <input type="text" id="autocomplete-input" class="autocomplete">
                        <label for="autocomplete-input"></label>
                      </div>
              </th>
            <td>
          </tr>
          </tbody>

          <tr>
              <th>Job</th>
              <th>namen</th>
              <th>Please select project:</th>
          </tr>
        </thead>
        <tbody id="table-body">

        </tbody>
      </table>  
   

<?!= include("page-js"); ?>

  </body>
</html>




**********
JS:
<script>

//EVENTS


  //ON LOAD EVENT
  window.addEventListener('load', () => {
  loadingData();
  });


  //AUTOCOMPLETE EVENT
  document.addEventListener('DOMContentLoaded', function() {
    var elems = document.querySelectorAll('.autocomplete');
    var instances = M.Autocomplete.init(elems,{
      data:{
        'option 1':null,
        'option 2':null,
        'option 3':null
      }, minLength: 0
    });
  });




//FUNCTIONS

  function loadingData(){
   //just loading rotating thing
  }



  function generateTable(dataArray){
    console.log("generateTable")
    var tbody = document.getElementById("table-body")

    let numb = tbody.childNodes.length;

    for (a = 1; a<numb; a++){
      tbody.removeChild(tbody.firstElementChild);
    }

    dataArray.forEach(function(r){
      var row = document.createElement("tr");

      var col1 = document.createElement("td");
      col1.textContent = r[0];
      row.appendChild(col1);

      var col2 = document.createElement("td");
      col2.textContent = r[1];
      row.appendChild(col2);

      var col3 = document.createElement("td");
     
//not working dynamic autocomplete
      var th = document.createElement("th");
      col3.appendChild(th);
      var div = document.createElement("div");
      div.setAttribute("class", "input-field");
      th.appendChild(div);
      var input = document.createElement("input");
      input.setAttribute("type", "text");
      input.setAttribute("id", "autocomplete-input");
      input.setAttribute("class", "autocomplete");
      div.appendChild(input);
      var label = document.createElement("label");
      label.setAttribute("for", "autocomplete-input");
      input.appendChild(label);

     
      row.appendChild(col3);

      tbody.appendChild(row);

      console.log(tbody)
      const old_tbody = document.getElementById("table-body")
    });  
  }
</script>



For sure this is some stupid mistake but I am quite new to web apps and I have no clue what am I doing wrong.



Jhonatas Henrique

unread,
Jun 19, 2024, 10:17:36 AM (10 days ago) Jun 19
to Google Apps Script Community
The problem you are facing is that MaterializeCSS needs the M.Autocomplete.init() function to be called after the input elements are created,
so that autocomplete is correctly initialized on new table elements. Additionally, you must ensure that each input element has a unique id.
Here is a revised version of your code to fix these issues:
        <table border="1" id="tableData" class="#eeeeee grey lighten-3" style="width:90%; margin: 0px auto; align: center;">
            <thead>
                <tr>
                    <th colspan="3">Static autocomplete for test purposes:</th>
                </tr>

                <tr>
                    <th>Job</th>
                    <th>namen</th>
                    <th>Please select project:</th>
                </tr>
            </thead>
            <tbody id="table-body">
                <tr>
                    <td>
                        <div class="input-field">
                            <input type="text" id="autocomplete-input-static" class="autocomplete">
                            <label for="autocomplete-input-static"></label>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>


    <?!= include("page-js"); ?>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</body>
</html>

JavaScript:
<script>
  //EVENTS

  window.addEventListener('load', () => {
    loadingData();
  });

  document.addEventListener('DOMContentLoaded', function() {
    var elems = document.querySelectorAll('.autocomplete');
    var instances = M.Autocomplete.init(elems, {
      data: {
        'option 1': null,
        'option 2': null,
        'option 3': null
      },
      minLength: 0
    });
  });

  //FUNCTIONS
  function loadingData() {
    //just loading rotating thing
  }

  function generateTable(dataArray) {
    console.log("generateTable");
    var tbody = document.getElementById("table-body");

    // Clear existing rows
    tbody.innerHTML = '';

    dataArray.forEach(function(r, index) {

      var row = document.createElement("tr");

      var col1 = document.createElement("td");
      col1.textContent = r[0];
      row.appendChild(col1);

      var col2 = document.createElement("td");
      col2.textContent = r[1];
      row.appendChild(col2);

      var col3 = document.createElement("td");
      var div = document.createElement("div");
      div.setAttribute("class", "input-field");
      col3.appendChild(div);


      var input = document.createElement("input");
      input.setAttribute("type", "text");
      input.setAttribute("id", `autocomplete-input-${index}`);

      input.setAttribute("class", "autocomplete");
      div.appendChild(input);

      var label = document.createElement("label");
      label.setAttribute("for", `autocomplete-input-${index}`);
      div.appendChild(label);

      row.appendChild(col3);

      tbody.appendChild(row);
    });

    // Initialize the autocomplete for new elements

    var elems = document.querySelectorAll('.autocomplete');
    var instances = M.Autocomplete.init(elems, {
      data: {
        'option 1': null,
        'option 2': null,
        'option 3': null
      },
      minLength: 0
    });

    console.log(tbody);
  }
</script>

Explanation of changes:
Unique ID for Autocomplete: In generateTable, each autocomplete input receives a unique id, based on the row index.
Resetting Autocomplete: After creating new elements in the table, reset autocomplete for these elements.
Table Cleaning: Use tbody.innerHTML = ''; to clear all lines before adding new ones.
These changes should fix the issue and allow autocomplete to work correctly on dynamically generated table elements.
Reply all
Reply to author
Forward
0 new messages