Skip to content

Instantly share code, notes, and snippets.

@vitosamson
Last active August 29, 2015 14:13
Show Gist options
  • Save vitosamson/78bef2c2106674a39bf2 to your computer and use it in GitHub Desktop.
Save vitosamson/78bef2c2106674a39bf2 to your computer and use it in GitHub Desktop.
Object.defineProperty data-binding
<html>
<head>
<script src="main.js"></script>
</head>
<body>
<div>
{{ foo }}
</div>
<input type="text" data-model="foo" id="foo">
</body>
</html>
'use strict';
var $scope = {},
models = {};
document.addEventListener('DOMContentLoaded', function(evt) {
var children = document.body.childNodes;
for (var child in children) {
var model;
child = children[child];
if (child.nodeType === 1) {
// input element, setup change listeners
if (child.localName === 'input') {
if (child.dataset) {
if (child.dataset.model) {
var el = child;
model = child.dataset.model;
el.onchange = function() {
$scope[model] = el.value;
};
el.onkeypress = el.onchange;
el.onpase = el.onchange;
el.oninput = el.onchange;
}
}
}
// any other element with a {{ model }} binding
else {
var text = child.innerHTML,
r = /{{.*}}/;
if (r.test(text)) {
var m = text.match(/[a-zA-Z]+/);
models[m] = models[m] || [];
models[m].push(child);
child.innerHTML = '';
}
}
Object.defineProperty($scope, model, {
set: function(value) {
var selectionStart,
selectionEnd;
if (el.selectionStart) {
selectionStart = el.selectionStart;
selectionEnd = el.selectionEnd;
}
el.value = value;
if (models[model]) {
models[model].forEach(function(m) {
m.innerHTML = value;
});
}
if (el.setSelectionRange)
el.setSelectionRange(selectionStart, selectionEnd);
}
});
}
}
$scope.foo = 'foo';
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment