1

Good day, everyone.

I'm trying to use Bootstrap 5 (no jQuery!) to open a remote file as a modal and pass a variable (via $_GET in the URL) to that remote file. I've gotten the following code to load the variable length contents of the remote file; however, there are several problems:

  1. The code seems way to complex when the end goal is to simply have a modal button on one page open a modal that is housed on another page.
  2. Other javascript tools (such as Toms-Select in my example), do not work when loaded from test.html, but do work when testmodal.php?data1=OPTION3 is loaded directly.

I've tried everything--including opening the remote file as an iframe--but nothing really works. For example, the iframe solution can't vary the height of the modal-body based on the contents of the external file.

I would appreciate any help...

Richard


test.html:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Test</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    </head>
    <body>
        <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#optionModal" data-bs-id="testmodal.php?data1=OPTION1">Modal: Option1</button>
        <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#optionModal" data-bs-id="testmodal.php?data1=OPTION2">Modal: Option2</button>
        <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#optionModal" data-bs-id="testmodal.php?data1=OPTION3">Modal: Option3</button>
        <div id="optionModal" class="modal fade" tabindex="-1">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-body">
                    </div>
                </div>
            </div>
        </div>
            <script>
            function loadContent(url) {
                var httpRequest = new XMLHttpRequest();
                httpRequest.onreadystatechange = function() {
                    if(httpRequest.readyState === XMLHttpRequest.DONE) {
                        if(httpRequest.status === 200) {
                            updateModal(httpRequest.responseText);
                        }
                    }
                };
                httpRequest.open("GET", url, true);
                httpRequest.send();
            };
            function updateModal(response) {
                var optionModal = document.getElementById("optionModal");
                optionModal.querySelector(".modal-content").innerHTML = response;
            }
            document.addEventListener("DOMContentLoaded", function() {
                optionModal.addEventListener("show.bs.modal", function() {
                    var button = event.relatedTarget
                    var id = button.getAttribute('data-bs-id')
                    loadContent(id);
                });
            });
            </script>
    </body>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</html>

testmodal.php:

<?
$data1 = $_GET['data1'];
if($data1=="OPTION1"){
    ?>
    <p>This is option 1!  Do some cool stuff for that option here!</p>
    <?
}elseif($data1=="OPTION2"){
    ?>
    <p>This is option 2!  Do some cool stuff for that option here!</p>
    <p>This is option 2!  Do some cool stuff for that option here!</p>
    <p>This is option 2!  Do some cool stuff for that option here!</p>
    <p>This is option 2!  Do some cool stuff for that option here!</p>
    <p>This is option 2!  Do some cool stuff for that option here!</p>
    <?
}elseif($data1=="OPTION3"){
    ?>
    <p>This is option 3!  Do some cool stuff for that option here!</p>
    <link href="https://cdn.jsdelivr.net/npm/tom-select@2.0.0/dist/css/tom-select.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/tom-select@2.0.0/dist/js/tom-select.complete.min.js"></script>
    <select class="form-select" id="select-clients" name="cname"></select>
    <script>
        new TomSelect('#select-clients',{
        maxItems: 1,
        maxOptions: 10,
        valueField: 'value',
        labelField: 'text',
        options: [{value: "sc123",text: "Joe Smith"},{value: "sc234",text: "Jane Doe"}],
        create: false
        });
    </script>
    <?
}
?>
user1677409
  • 45
  • 1
  • 5
  • Not a PHP expert here but it seems like you return an entire HTML document not just the html that is in between the conditionals - why not just the sub-segment(s) – Mark Schultheiss Jan 21 '22 at 20:36
  • i.e. Like in this questions answer: https://stackoverflow.com/q/7333405/125981 – Mark Schultheiss Jan 21 '22 at 20:40
  • Hi, @MarkSchultheiss... and thanks. You're right--I can reduce the testmodal.php to just use the text that should be inserted into the modal's body (and I've updated my code above to reflect that). The issue, though, is that my solution still seems wildly complex and javascript loaded from within the modal body still won't work. For the second part of that, I mean that the "Toms-Select" works if you access the testmodal.php page directly, but not if it loads from within the test.php modal. Again, though, I appreciate the help and ideas! – user1677409 Jan 21 '22 at 22:04

1 Answers1

1

After days of searching and not finding anything with BS5 alone, I came across a workaround.

My solution was using Bootstrap 5 and "w3-schools HTML include" to load remote content in a modal via a URL (I think it has to be local file).

Edit: I forgot to mention that it does not embed the HTML in "test.html" and will only show up in the modal :)

test.html

<a href="#" data-bs-toggle="modal" data-bs-target="#optionModal">Link</a>

<div class="modal fade" id="optionModal">
  <div class="modal-dialog">
    <!-- the include file -->
    <div w3-include-html="test.php"></div> 
  </div>
</div>

<script>includeHTML();</script> 

test.php

<div class="modal-content">
  <div class="modal-header">
    <h5 class="modal-title">Header</h5>
    <button type="button" class="btn btn-primary btn-lg" data-bs-dismiss="modal" aria-label="Close">CLOSE</button>
  </div>
  <div class="modal-body container">
      ----- content here -----
  </div>
</div>

and then some Javascript

function includeHTML() {
  var z, i, elmnt, file, xhttp;
  z = document.getElementsByTagName("*");
  for (i = 0; i < z.length; i++) {
    elmnt = z[i];
    file = elmnt.getAttribute("w3-include-html");
    if (file) {
      xhttp = new XMLHttpRequest();
      xhttp.onreadystatechange = function() {
        if (this.readyState == 4) {
          if (this.status == 200) {elmnt.innerHTML = this.responseText;}
          if (this.status == 404) {elmnt.innerHTML = "Page not found.";}
          /* Remove the attribute, and call this function once more: */
          elmnt.removeAttribute("w3-include-html");
          includeHTML();
        }
      }
      xhttp.open("GET", file, true);
      xhttp.send();
      return;
    }
  }
}

You can find it here https://www.w3schools.com/howto/howto_html_include.asp

Marina
  • 101
  • 1
  • 7
  • I am curious if you've recently found any way to do this without the w3-schools method? – GoOutside Aug 18 '22 at 23:11
  • Unfortunately I haven't. :( Annoyingly though... it seems only to work on my localhost and not on a live server. – Marina Aug 22 '22 at 07:27
  • Edit: It actually did work on live. I had forgotten to add the modals to my struts-config.xml. :D – Marina Oct 10 '22 at 12:16