0

I've been reading with interest about the dialog element in HTML:

  <dialog id="helpOnName">
    <p>
     The name is arbitrary. There is no validation, whatsoever.
    </p>
  </dialog>

So, that's well for this simple text. However, with growing complexity, I'd rather have something like

  <dialog url="helpOnName.html"></dialog>

In other words: Rather than embedding the dialog contents into the opening page, I'd like it to be read from another file.

Is that possible? How? (Using JQuery would be fine.)

user1774051
  • 843
  • 1
  • 6
  • 18

2 Answers2

2

You may have different options to achieve the goal to have content loaded from an external resource.

  • Doing an ajax request that will return a response to embed dynamically in the dialog
  • Embedding the content inside an <iframe> tag
  • Referencing the content with an <object> tag

This is the demo for the third and most original option of those.

The content for the <dialog> is specified by an <object> element fed by an url having its content. As a fallback, I added the option that will override its content with a default template defined in the page itself.

<object>: The External Object element

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object

:scope (worth of mention)

*for selecting only starting from the direct children

https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

This is an answer better covering <iframe> <embed> <object>

Difference between iframe, embed and object elements

And I would add I forgot to mention <link>

document.addEventListener('DOMContentLoaded', ()=>{
  const dialog = document.getElementById('primaryDialog');
  fillDialogContent(dialog);
})

function fillDialogContent(dialog){  
  const template = dialog.querySelector(':scope > .fallback');  
  const content = template.content.cloneNode(true);  
  const objectEl = dialog.querySelector('object');  
  objectEl.append(content); 
}
<dialog id="primaryDialog" open>
    <object data="your-custom-dialog-content.html" type="text/html"></object>
    
    <template class="fallback">
      <div class="container">
        <p>This is the default dialog content</p>
        <p>An error occurred in the attempt to load the custom template</p>
      </div>
    </template>
    
</dialog>
Diego D
  • 6,156
  • 2
  • 17
  • 30
  • Been web coding for 25 years and I thought objects were dead after Flash. Cool trick. But the iframe is the simplest way, eh? – Ruan Mendes Dec 13 '22 at 15:21
  • 1
    yes it's a very very old idea long gone .. and the reason why I decided to adopt it for this answer was because I was afraid to involve added constraints due to iframe isolation and security engaged. I gave for granted that the object element was not going to be as that strict. But to be fair I didn't test if the content loaded from external asset was going to work. By the way I added the mdn page now for the sake of giving it some legitimacy – Diego D Dec 13 '22 at 15:39
  • I didn't stress it out but this part was the most interesting `.querySelector(':scope > .fallback');` that just limits the query to the ***direct*** children using the `:scope` pseudo-class – Diego D Dec 13 '22 at 15:45
0

Here is another way of doing it with fetch():

document.addEventListener('DOMContentLoaded', function(ev) {
  document.querySelectorAll("[data-url]").forEach(el=>
   fetch(el.dataset.url).then(r=>r.text()).then(html=>el.innerHTML=html)
  )
});
<h3>First dialogue</h3>
<div data-url="https://baconipsum.com/api/?type=all-meat&paras=3&format=html">hello</div>
<h3>Second dialogue</h3>
<div data-url="https://baconipsum.com/api/?type=all-meat&paras=5&make-it-spicy=1&format=html">hello again</div>
Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
  • Reminder that this won't work if you have [hardened CSP policies](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) in place, which you should since they prevent XSS. – Ruan Mendes Dec 13 '22 at 14:59
  • @RuanMendes this is a valid point to be aware of! However, assuming the OP wants to include text files containing HTML markup from the same (their own) site, strict CSP policies should not be a critical issue here. – Carsten Massmann Dec 13 '22 at 15:05
  • If there are no scripts in that same-site HTML, that is correct. My main point is that to do this, they should understand what CSP is. `iframe`s would be a simpler way. – Ruan Mendes Dec 13 '22 at 15:07
  • 1
    Point taken. However, DOM elements contained in `iframes` cannot be addressed in the same way as other DOM elements from the embedding document. This might make it a little bit harder to supply JavaScript based methods (rooted in the embedding document) for augmenting the actual dialogue logic. – Carsten Massmann Dec 13 '22 at 16:06