I have read your excellent articles on ESModules and but I cannot find anywhere how to import a web component that includes a since the link import has become obsolete. Any help would be great!
Thanks again
Hi,
This is the documentation on MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Thanks for your quick answer, but this new import does not allow to import html, like for example. It is limited to javascript.
How can I import HTML content (like tags)?
Hi
Can you give more info about the stack you are using please?
Hi @axel.buendia –
You mentioned web components. They are not managed with imports; they are managed through the CustomElementRegistry object. You can learn more in the Web Components section of MDN.
Hi, I am not using any stack, just good old html and js files.
I have developped several web components containing each a javascript part (the class of the component and the register part), with a html part (the tag).
With new import method () I cannot import anymore the html part containing the part. My question is how can I import the html part (the tag) into my main html file?
Thanks a lot and sorry if I was not clear
TBH I think you have a compatibility problem – this is an educated guess – but without digging into your code I can’t offer a solution. I do have one more suggestion: you should check out Pug. Good luck!
Thanks again, I can put the code:
mainhtmlfile.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Component</title> <link rel="import" href="template.html"/> </head> <body> <div-component>essai</div-component> </body> </html>
The html file that contains the template tag:
template.html
<template id="divComponent"> <style> .divComponentCl { border-top: 3px solid #c1002a !important; border-bottom: 3px solid #c1002a !important; padding: 3px 3px; text-align: justify; } </style> <div class="divComponentCl"> <table style="border: none;"><tr><td><img alt="icone" width="70"/></td><td></td></tr></table> </div> </template> <script> class DivMessage extends HTMLElement { constructor(){ super(); } connectedCallback(){ var template; if(typeof document.currentScript === 'undefined' || document.currentScript == null) template = document.getElementById('divMessage'); else template = document.currentScript.ownerDocument.getElementById('divMessage'); if(template == null){ window.console.error('Template [divMessage] not found in document'); return; } ... var clone = template.content.cloneNode(true); var shadow = this.attachShadow({mode:'open'}); shadow.appendChild(clone); } } window.customElements.define('div-message', DivMessage); </script>
This was working just fine. But the <link type=“import” is obsolete. So I decide to use the web component API (ESModule).
The main html file becomes:
mainhtmlfile.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Component</title> <script type="module" src="components.js"></script> </head> <body> <div-component>essai</div-component> </body> </html>
I cannot put any html tags into the components.js file. The web component js file, which includes the class:
component.js
class DivMessage extends HTMLElement { constructor(){ super(); } connectedCallback(){ var template; if(typeof document.currentScript === 'undefined' || document.currentScript == null) template = document.getElementById('divMessage'); else template = document.currentScript.ownerDocument.getElementById('divMessage'); if(template == null){ window.console.error('Template [divMessage] not found in document'); return; } ... var clone = template.content.cloneNode(true); var shadow = this.attachShadow({mode:'open'}); shadow.appendChild(clone); } } window.customElements.define('div-message', DivMessage);
So my question is, where do I put the <template> tag that used to be in the template.html?
I cannot put it into the main html file because I am a component provider, and I do not know in which html files my components will be used.
Thanks again for your help, I hope the code will clarify the situation.
I recommend using uhtml or lighterhtml, which allows you to include the contents of the <template>
element in your JS code as a tagged template literal:
// component.js
import { render, html } from "https://unpkg.com/uhtml?module";
// or
import { render, html } from "https://unpkg.com/lighterhtml?module";
class DivMessage extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: "open" });
render(shadow, html`
<style>
.divComponentCl {
border-top: 3px solid #c1002a !important;
border-bottom: 3px solid #c1002a !important;
padding: 3px 3px;
text-align: justify;
}
</style>
<div class="divComponentCl">
<table style="border: none;">
<tr>
<td><img alt="icone" width="70"/></td>
<td></td>
</tr>
</table>
</div>
`);
}
}
window.customElements.define("div-message", DivMessage);
I can see you have worked hard on this. Rather than try to salvage what you have already done; use React or another js lib because this will not work this way. You could read this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
and try to modify it. But I think you will have an easier time of it if you use a framework.
Thanks again for your answer. I will try string literals. I do not want to use framework yet
It is a shame that the consortium removed something that was useful (include of html tags)…
Thanks to everyone, here is the final version (for the record):
main.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>ComponentTest</title> <script type="module"> import {DivMessage} from './component.js'; </script> </head> <body> <div-message>message</div-message> </body> </html>
component.js
const divMessageInnerHTML = ` <style> .divMessageCl { border-top: 3px solid #c1002a !important; border-bottom: 3px solid #c1002a !important; padding: 3px 3px; text-align: justify; } .divMessageCl td { padding: 0; margin: 0em 1em; } .divMessageCl table { padding: 0; margin: 0; } .progress { height: 10px; background-color: orange; } </style> <div class="divMessageCl"> <table style="border: none;"><tr><td><img alt="icone" width="70"/></td><td></td></tr></table> </div>`; // DivMessage is a component to use to highlight a text in a box with an icon export class DivMessage extends HTMLElement { // cannot use this at this step because it has no content yet constructor(){ super(); } // this contains everything at this stage! connectedCallback(){ var template = document.createElement('template'); template.innerHTML = divMessageInnerHTML.trim(); var clone = template.content.cloneNode(true); var innerContent = innerImg.parentNode.nextSibling; innerContent.innerHTML = this.innerHTML; var shadow = this.attachShadow({mode:'open'}); shadow.appendChild(clone); } } customElements.define("div-message", DivMessage);