Created
October 5, 2022 11:00
-
-
Save vidaj/b27f1140a8ae711c7df2372c4b5cfeea to your computer and use it in GitHub Desktop.
HTML template with slots
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Testing templates with slots</title> | |
</head> | |
<body> | |
<template id="myTemplate"> | |
<section> | |
<header> | |
<h1><slot name="header"></slot></h1> | |
</header> | |
<dl> | |
<dt>Name</dt> | |
<dd><slot name="name"></slot></dd> | |
</dl> | |
</section> | |
</template> | |
<template id="fancyHeaderTemplate"> | |
<span style="color: blue;">This</span> is a <span style="font-style:italic;">fancy</span> templated header | |
</template> | |
<label for="input_name">Name:</label> | |
<input type="text" id="input_name"/> | |
<button onclick="addFancy()">Add fancy</button> | |
<button onclick="addPlain()">Add plain</button> | |
<button onclick="updateLast()">Update last added</button> | |
<script type="text/javascript"> | |
class Template { | |
constructor(templateName) { | |
this.template = document.getElementById(templateName); | |
this.content = this.template.content.cloneNode(true); | |
let slots = {}; | |
Array.prototype.forEach.call(this.content.querySelectorAll("slot"), slot => { | |
let name = slot.getAttribute("name"); | |
slots[name] = slot; | |
}); | |
this.slots = slots; | |
} | |
update(values) { | |
if (values === undefined) { | |
return; | |
} | |
let keys = Object.keys(values); | |
let slots = this.slots; | |
keys.forEach(key => { | |
if (key in slots) { | |
let slot = slots[key]; | |
let newValue = values[key]; | |
if (newValue instanceof Template) { | |
newValue = newValue.content; | |
} | |
else if (!(newValue instanceof Node)) { | |
newValue = document.createTextNode(newValue); | |
} | |
slot.replaceWith(newValue); | |
slots[key] = newValue; | |
} | |
}); | |
} | |
render(element, values) { | |
if (values !== undefined) { | |
this.update(values); | |
} | |
element.appendChild(this.content); | |
} | |
} | |
function getName() { | |
return document.getElementById("input_name").value; | |
} | |
let lastTemplate = undefined; | |
function addFancy() { | |
var headerTemplate = new Template("fancyHeaderTemplate"); | |
var template = new Template("myTemplate"); | |
template.render(document.body, { | |
name: getName(), | |
header: headerTemplate | |
}); | |
lastTemplate = template; | |
} | |
function addPlain() { | |
var template = new Template("myTemplate"); | |
template.render(document.body, { | |
name: getName(), | |
header: "This is a plain header" | |
}); | |
lastTemplate = template; | |
} | |
function updateLast() { | |
if (lastTemplate !== undefined) { | |
lastTemplate.update({"name": getName()}); | |
} | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment