JSFiddle - React, Tailwind, and code Playground
HTML
<form>
<label>Name
<input name='firstName' />
</label>
<label>Last Name
<input name='lastName' />
</label>
<label>Age
<input name='age' />
</label>
</form>
<div id='result'></div>
CSS
form {
width:500px;
}
form label {
display:block;
/* lol */
text-align:right;
}
JavaScript
var form = document.forms[0];
var lf = liveForm(form);
var result = document.getElementById('result');
lf.onChange(function () {
result.textContent = JSON.stringify(lf);
});
setTimeout(function(){
console.log("HERE! fn:",lf.firstName);
lf.firstName = "John";
},1000);
function Person() {}
function liveForm(form) {
var obj = Object.create(Person, {__cbs: { value: [] } });
Object.defineProperty(obj, "onChange", { value: function (cb) { obj.__cbs.push(cb); } });
form.addEventListener("keyup", update);
function update() {
var updated = serializeForm(form);
for (var o in updated) {
Object.defineProperty(obj,o,{
enumerable:true,
configurable:true,
get: function(o){ return updated[o]; }.bind(null,o),
set: function(o,val){ console.log("hi",updated[o],val);
updated[o] = val;
form[o].value = val;
update();
}.bind(null,o)
});
}
obj.__cbs.forEach(function (cb) { cb(obj); });
}
setTimeout(update,0);
return obj;
}
function serializeForm(form) {
var obj = {};
var items = form.querySelectorAll("input[name]");
for (var i = 0; i < items.length; i++) obj[items[i].name] = items[i].value;
return obj;
}