Skip to content

Instantly share code, notes, and snippets.

@victornpb
Created April 14, 2019 02:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save victornpb/c1f1588ee0d0476a2269baad9b661964 to your computer and use it in GitHub Desktop.
Save victornpb/c1f1588ee0d0476a2269baad9b661964 to your computer and use it in GitHub Desktop.
Two way data binding DOM and vanilla Javascript in under 100 lines
function dd(context = {}) {
const values = {};
const boundElms = {};
const elms = Array.from(document.querySelectorAll('[data-bind]'));
elms.forEach(el => {
const prop = el.getAttribute('data-bind');
if (!boundElms[prop]) boundElms[prop] = [];
boundElms[prop].push(el);
if ('value' in el) {
el.addEventListener('input', () => {
values[prop] = getDOMValue(el);
updateDOM(prop);
});
}
});
Object.keys(boundElms).forEach(prop => {
values[prop] = context[prop]; //initial value
Object.defineProperty(context, prop, {
get() {
return values[prop];
},
set(newValue) {
values[prop] = newValue;
updateDOM(prop, newValue);
},
enumerable: true,
configurable: true,
});
updateDOM(prop, values[prop]); //first update
});
function updateDOM(prop) {
const value = values[prop];
boundElms[prop].forEach(el => {
if(el.type==='checkbox'){
el.checked = value;
}
else if('value' in el){
el.value = value;
}
else{
el.textContent = value;
}
});
}
function getDOMValue(el){
let value;
if(el.type==='checkbox'){
value = el.checked;
}
else if('value' in el){
value = el.value;
}
else{
value = el.textContent;
}
return value;
}
return context;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment