Created
November 27, 2014 21:00
-
-
Save michaelcpuckett/da6ba265429bb6508034 to your computer and use it in GitHub Desktop.
Native Client-side Templating with Databinding
This file contains hidden or 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>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