Skip to content

Instantly share code, notes, and snippets.

@michaelcpuckett
Created November 27, 2014 21:00
Show Gist options
  • Save michaelcpuckett/da6ba265429bb6508034 to your computer and use it in GitHub Desktop.
Save michaelcpuckett/da6ba265429bb6508034 to your computer and use it in GitHub Desktop.
Native Client-side Templating with Databinding
<!doctype html>
<html>
<head>
<title>Native Client-side Templating with Databinding</title>
<style>[data-key]{font-weight:bold;}</style>
</head>
<body>
<select id="language-select">
<option>Select a language</option>
<option value="en">English</option>
<option value="es">Espanol</option>
</select>
<div id="account-view">
<!-- [Object object] will be converted to <span data-key/>s for template consumption -->
</div>
<br>First Name = <input id="input">
<template id="account-tpl-en">
Hi. My name is <content select="[data-key=firstName]"></content>.
</template>
<template id="account-tpl-es">
<section>
Hola. Mi nombre es <content select="[data-key=firstName]"></content>.
</section>
</template>
<script>
function Ctrl (ctrl, payload) {
var viewEl = document.getElementById(ctrl + '-view');
this.data = {};
function createEl (key, value) {
var el = document.createElement('span');
el.setAttribute('data-key', key);
el.innerText = value;
return el;
}
function getEl (key) {
return viewEl.querySelectorAll('[data-key=' + key + ']')[0];
}
function appendEl (childEl, parentEl) {
childEl = childEl || this;
parentEl = parentEl || viewEl;
parentEl.appendChild(childEl);
return childEl;
}
function updateEl (el, value) {
el = el || this;
el.innerText = value;
return el;
}
function renderDataToDom (changes) {
changes.forEach(function (change) {
switch (change.type) {
case 'add':
appendEl( createEl(change.name, change.object[change.name]) );
break;
case 'remove':
removeEl( getEl(change.name) );
break;
case 'update':
updateEl( getEl(change.name), change.object[change.name] );
break;
default:
break;
}
renderTemplate();
});
}
Object.observe(this.data, renderDataToDom);
function renderTemplate (locale) {
locale = locale || this.locale;
this.locale = locale;
var shadowRoot = viewEl.shadowRoot,
templateEl = document.getElementById(ctrl + '-tpl-' + this.locale),
templateContent;
shadowRoot.innerHTML = '';
if (templateEl) {
templateContent = document.importNode(templateEl.content, true);
shadowRoot.appendChild(templateContent);
}
}
document.getElementById('language-select').addEventListener('change', function (e) {
renderTemplate(this.value);
});
viewEl.createShadowRoot();
}
Ctrl.prototype.set = function (key, value) {
this.data[key] = value;
}
var accountCtrl = new Ctrl('account');
var inputEl = document.getElementById('input');
inputEl.addEventListener('keyup', function (e) {
accountCtrl.set('firstName', this.value);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment