Skip to content

Instantly share code, notes, and snippets.

@davidwhitney
Created October 19, 2023 14:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save davidwhitney/acf193576b7ad92adcf46a62fda551a8 to your computer and use it in GitHub Desktop.
Save davidwhitney/acf193576b7ad92adcf46a62fda551a8 to your computer and use it in GitHub Desktop.
The Worlds Smallest UI Binding Library
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
<script type="module">
function someClick() {
alert("hello");
}
const anything = {
foo: 'bar',
title: "google",
url: "https://www.google.com",
baz: {
qux: 'quux'
},
items: [
{ foo: "barry" }
]
};
renderTemplate("main", "someTemplate", anything);
function renderTemplate(targetId, templateId, data = null) {
const template = document.getElementById(templateId);
const clone = template.content.cloneNode(true);
const elements = clone.querySelectorAll("*");
elements.forEach(ele => {
const bindingAttrs = [...ele.attributes].filter(a => a.name.startsWith("data-bind"));
bindingAttrs.forEach(attr => {
const target = attr.name.replace(/data-bind-/, "").replace(/data-bind/, "");
const targetType = target.startsWith("on") ? "HANDLER" : "PROPERTY";
const targetProp = target === "" ? "innerHTML" : target;
const prefix = targetType === "PROPERTY" ? "data." : "";
const expression = prefix + attr.value.replace(/;\n\r\n/g, "");
// Maybe use a framework with more validation here ;)
ele[targetProp] = targetType === "PROPERTY" ? eval(expression) : () => { eval(expression) };
ele.removeAttribute(attr.name);
});
});
const target = document.getElementById(targetId);
target.innerHTML = "";
target.appendChild(clone);
}
</script>
</head>
<body>
<div id="main">
</div>
<template id="someTemplate">
<h1>Hello world</h1>
<div data-bind="foo" data-bind-onclick="someClick();"></div>
<div>
Nested: <span data-bind="baz.qux"></span>
</div>
<div data-bind="items[0].foo"></div>
<a data-bind-href="url" data-bind="title"></a>
</template>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment