Search code examples
javascripthtmlmaterialize

Programmatically injected modal to HTML does not function


So currently I am learning JavaScript and I am trying to inject some data which I'm grabbing from a JSON file into HTML/Materialize Modal pragmatically.

The data shows, and the tag which is button gets the name from the file but the Modal does not popup.

Now I have left one hard-coded Modal in HTML to test it and that one works but the ones which I get from JSON and inject them to HTML doesn't popup! I think the issue comes from the fact that the Modal initialization need to re-initialize after the injection is finished but I could be wrong! Either way, I am failing to get this started and i was wondering if anyone know where am I going wrong with this.

Here is the simple html:

<div class="container">
    <div class="row">
    </div>
    <!-- Modal Trigger -->
    <a class="waves-effect waves-light btn modal-trigger" href="#modal1">Modal</a>

    <!-- Modal Structure -->
    <div id="modal1" class="modal bottom-sheet">
        <div class="modal-content">
            <h4>Modal Header</h4>
            <p>A bunch of text</p>
        </div>
        <div class="modal-footer">
            <a href="#!" class="modal-close waves-effect waves-green btn-flat">Agree</a>
        </div>
    </div>
</div>

Here is my simple JS code:

const content = document.querySelector('.row');
fetch('./perTab.json')
    .then((response) => {
        console.log(response, 'resolved');
        return response.json();
    }).then(data => {
        html = ``;
        console.log(data);
        data.forEach((element, index) => {
            html += `
            <!-- Modal Trigger -->
            <a class="waves-effect waves-light btn modal-trigger" href="#modal${index + 2}">${element.Name}</a>
    
            <!-- Modal Structure -->
            <div id="modal${index + 2}" class="modal bottom-sheet">
                <div class="modal-content">
                    <h4>h4</h4>
                    <p>A bunch of text</p>
                </div>
                <div class="modal-footer">
                    <a href="#!" class="modal-close waves-effect waves-green btn-flat">Agree</a>
                </div>
            </div>
            `;
        });
        content.innerHTML = html;
    }).catch((error) => {
        console.log(error, ' broke the promise')
    })

//this is Modal initialization
document.addEventListener('DOMContentLoaded', () => {
    var elems = document.querySelectorAll('.modal');
    var instances = M.Modal.init(elems);
});

Solution

  • I think you need to do var instances = M.Modal.init(elems); after adding it to the innerHTML of content.

    // For the dynamically generated modals :
    content.innerHTML = html;
    initializeModal();
    ..
    
    // for DOMContentLoaded
    document.addEventListener('DOMContentLoaded', initializeModal);
    
    function initializeModal() {
      var elems = document.querySelectorAll('.modal');
      var instances = M.Modal.init(elems);
    }