0

This concept is based on the post Multiple modals overlay

I am trying to create a folder modal, and within every folder modal the user should be able 1) open existing or 2) create a new file modal

Please run the code below to understand how it works. You will have to click buttons and the list items for opening the modals

But this operates in a bootstrap full screen mode instead of dialog

enter image description here

Clicking on the button creates a folder in the list When you click the "This is folder ###" it opens a modal as shown below

enter image description here

Now I could create a file

enter image description here

The issue is that needs to be fixed is when file item is cliked, the file modal should overlay on top of the folder modal, But now its closing and both modals wont stay.

<!doctype html>
<html lang="en">

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous" -->


    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
</head>

<body>

    <button class="btn btn-primary" id="addnewfolder">Create new folder</button>

    <ul class="list-group folder"></ul>

    <script>
        $("#addnewfolder").click(function(event) {

            var code = (Math.random() + 1).toString(36).substring(7)

            $(".folder").append(`<li class="list-group-item">
    <img src="https://img.icons8.com/officel/48/null/live-folder.png" class="float-start" />


    <div class="ms-5" data-bs-toggle="modal" href="#modal-toggle-${code}">This is folder ${code}<br />

        <div>
            <div class="modal fade" id="modal-toggle-${code}" aria-hidden="true" aria-labelledby="modal-toggleLabel" tabindex="-1">
                <div class="modal-dialog modal-fullscreen">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h1 class="modal-title fs-5" id="modal-toggleLabel">Inside Folder ${code}</h1>
                            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                        </div>
                        <div class="modal-body">
                            <ul class="list-group file"></ul>
                            <button data-bs-target="#modal-toggle2" data-bs-toggle="modal" class="btn btn-primary file-${code}">Add File Inside ${code}</button>
                        </div>
                        <div class="modal-footer">
                            <button class="btn btn-primary">Save</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</li>`);
            //$(`#modal-toggle-${code}`).modal("show");

            $(`.file-${code}`).click(function(event) {
                        var dcode = Math.floor(Math.random() * 10);
                        $(".file").append(`<li class="list-group-item">
    <img src="https://img.icons8.com/cotton/64/null/happy-file.png" class="float-start" />




    <div class="ms-5">This is file inside ${code}-${dcode}<br />
        <small class="text-secondary">This is a ${code}-${dcode} item description</small>
        <div>
            <div class="modal fade" id="modal-toggle-${code}-${dcode}" aria-hidden="true" aria-labelledby="modal-toggleLabel" tabindex="-1">
                <div class="modal-dialog modal-fullscreen">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h1 class="modal-title fs-5" id="modal-toggleLabel">Inside Folder</h1>
                            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                        </div>
                        <div class="modal-body">
                            Hello World
                        </div>
                        <div class="modal-footer">
                            <button class="btn btn-primary">Save</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</li>`);
            
            //$(`#modal-toggle-${code}-${dcode}`).modal("show");

            });

        });
        
        
$(document).on('show.bs.modal', '.modal', function() {
  const zIndex = 1040 + 10 * $('.modal:visible').length;
  $(this).css('z-index', zIndex);
  setTimeout(() => $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack'));
});

    </script>

</body>
Code Guy
  • 3,059
  • 2
  • 30
  • 74
user16731842
  • 83
  • 1
  • 10

1 Answers1

-1

Don't stack Bootstrap modals.

Bootstrap only supports one modal window at a time. Nested modals aren’t supported as we believe them to be poor user experiences.

https://getbootstrap.com/docs/5.2/components/modal/#how-it-works

Toggle between multiple modals with some clever placement of the data-bs-target and data-bs-toggle attributes. Please note multiple modals cannot be open at the same time—this method simply toggles between two separate modals.

https://getbootstrap.com/docs/5.2/components/modal/#toggle-between-modals

Therefore toggle the modals instead of stacking them. Better UX and no need for any z-index tricks.

Your issue.

With that out of the way, the reason why the modal is closing when clicking the "Add File" button is because...

<button data-bs-target="#modal-toggle2" data-bs-toggle="modal" class="btn btn-primary file-${code}">Add File Inside ${code}</button>

...you have a data-bs-target & -toggle on your button that creates a new 'file'. This will toggle modal #modal-toggle2, and since it doesn't exists on your page you get the error of an undefined modal.

You also have a few typos, like forgetting to close a <div> in a few places.

Your solution...

  • Appends the modal to the body, not the <li> element.
  • Uses the data attributes data-bs-target and data-bs-toggle to toggle the modals.
  • Features a "Go back to folder" button when accessing the 'file' modal.

$(document).ready(function() {
  $("#addnewfolder").click(function() {
    var code = (Math.random() + 1).toString(36).substring(7)
    $(".folder").append(`
      <li class="list-group-item" data-bs-toggle="modal" data-bs-target="#modal-${code}">
        <img src="https://img.icons8.com/officel/48/null/live-folder.png" class="float-start" />
        <div class="ms-5">This is folder ${code}</div>
      </li>
    `);
    $('body').append(`
      <div class="modal fade" id="modal-${code}" tabindex="-1" aria-labelledby="modal-${code}-label" aria-hidden="true">
        <div class="modal-dialog modal-fullscreen">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title" id="modal-${code}-label">Folder ${code}</h5>
              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
              <button class="btn btn-primary file-${code}">Add new File</button>
              <ul class="list-group file"></ul>
            </div>
            <div class="modal-footer">
              <button class="btn btn-primary">Save</button>
            </div>
          </div>
        </div>
      </div>    
    `)
      $(`.file-${code}`).click(function() {
        var dcode = Math.floor(Math.random() * 10);
        $(this).closest('.modal').find('.file').append(`
          <li class="list-group-item" data-bs-toggle="modal" data-bs-target="#modal-${code}-${dcode}">
            <img src="https://img.icons8.com/cotton/64/null/happy-file.png" class="float-start" />
            <div class="ms-5">
              This is file inside ${code}-${dcode}
              <br>
              <small class="text-secondary">This is a ${code}-${dcode} item description</small>
            </div>
          </li>
        `)
        $('body').append(`
          <div class="modal fade" id="modal-${code}-${dcode}" tabindex="-1" aria-labelledby="modal-${code}-${dcode}-label" aria-hidden="true">
            <div class="modal-dialog modal-fullscreen">
              <div class="modal-content">
                <div class="modal-header">
                  <h5 class="modal-title" id="modal-${code}-${dcode}-label">File ${code}-${dcode}</h5>
                  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                  <p>Hello World</p>
                </div>
                <div class="modal-footer">
                  <button class="btn btn-primary">Save</button>
                  <button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#modal-${code}" >Go back to folder ${code}</button>
                </div>
              </div>
            </div>
          </div>    
        `)
      })
  })
})
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

<button class="btn btn-primary" id="addnewfolder">Create new folder</button>
<ul class="list-group folder"></ul>

If you also want the top-right close button (X) in the 'File' modal to act as going back to the 'folder' modal, simply do:

<button type="button" class="btn-close" data-bs-toggle="modal" data-bs-target="#modal-${code}" aria-label="Close"></button>
Cooleronie
  • 1,225
  • 1
  • 9
  • 9