Include HTML with dynamic URL

Include HTML with dynamic URL

feels like iframe but there is no extra frame

·

2 min read

Here is a solution to dynamically load any HTML into any HTML element that has a w3-include-html attribute.

  • Use w3-include-html to specify the URL of HTML to include.
  • Put the below script into the page.

The solution is not authored by me. It was copied some where years back. I can not traceback the source now.

The solution:

    <script>
        function includeHTML() {
            var z, i, elmnt, file, xhttp;
            /* Loop through a collection of all HTML elements: */
            z = document.getElementsByTagName("*");
            for (i = 0; i < z.length; i++) {
                elmnt = z[i];
                /*search for elements with a certain atrribute:*/
                file = elmnt.getAttribute("w3-include-html");
                if (file) {
                    /* Make an HTTP request using the attribute value as the file name: */
                    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();
                    /* Exit the function: */
                    return;
                }
            }
        }
        includeHTML();
    </script>

Usage:

        <div class="card">
            <div class="card-content">
                <span class="card-title orange-text">Correlation (As syncronised signals)</span>
                <div w3-include-html="/report/{{task_instance_slug}}/table_corr_gradient.html"></div>
            </div>
        </div>

In my use case, the {{task_instance_slug}} is interpolated by Flask every time the user triggers one execution. The system generates a report that is composed of multiple standalone files. Some of those files are images which are straightforward to include in the report template. Some of those files are HTML files, generated by DataFrame.to_html() function. We apply the techniques above to include those HTMLs.

Rationale:

  • Why do I load those charts/ tables separately, instead of one integral report? -- I want to separate the computation and presentation. Even if we computed some charts, we can dynamically adjust the presentation template to show some of those charts and can easily regroup/ reorder them.
  • Why do I generate those charts / tables and load from template, instead of issuing multiple HTTP requests to generate on the fly when loading the report? -- Some charts are very quick to generate but some require much more time. Pre-computation is needed to ensure the report loading speed is satisfactory.

Did you find this article valuable?

Support Building blocks by becoming a sponsor. Any amount is appreciated!