Skip to content

Instantly share code, notes, and snippets.

@mhkeller
Created September 13, 2014 03:35
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 mhkeller/da85c740f768b43904af to your computer and use it in GitHub Desktop.
Save mhkeller/da85c740f768b43904af to your computer and use it in GitHub Desktop.
Two-way data binding experiment from https://groups.google.com/forum/#!topic/d3-js/xJVirdXdaLw
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
</head>
<body>
<div>sourceData = [4, 8, 15, 16, 23, 42]</div>
<div>.bind(sourceData, validationFunction)</div>
<div id="example1" >
<textarea style="color: gainsboro;">not bound</textarea>
</div>
<div>sourceData = { nums: [4, 8, 15, 16, 23, 42] }</div>
<div>.bind(sourceData.nums, validationFunction)</div>
<div id="example2" >
<input value="not bound" style="color: gainsboro;"/>
</div>
<div>{ "nums": [ { "id": 1, "data": 4 }, { "id": 2, "data": 8 }, { "id": 3, "data": 15 },
{ "id": 4, "data": 16 }, { "id": 5, "data": 23 }, { "id": 6, "data": 42 }] }</div>
<div>.bind(sourceData.nums, 'data', validationFunction)</div>
<div id="example3" >
<input value="not bound" style="color: gainsboro;"/>
</div>
<button onclick="alert( JSON.stringify(sourceData1) + JSON.stringify(sourceData2) + JSON.stringify(sourceData3) ); " >show</button>
<script type="text/javascript">
var sourceData1 = [4, 8, 15, 16, 23, 42];
var sourceData2 = { nums: [4, 8, 15, 16, 23, 42] };
var sourceData3 = { "nums": [ { "id": 1, "data": 4 }, { "id": 2, "data": 8 }, { "id": 3, "data": 15 },
{ "id": 4, "data": 16 }, { "id": 5, "data": 23 }, { "id": 6, "data": 42 }] };
//var sourceData = [4, 8, 15, 16, 23, 42];
//NEW function .enter().append("input").bind(sourceData, validationFunction)
//var sourceData = { nums: [4, 8, 15, 16, 23, 42] };
//NEW function .enter().append("input").bind(sourceData.nums, validationFunction)
//var sourceData = { "nums": [ { "id": 1, "data": 4 }, { "id": 2, "data": 8 }, { "id": 3, "d...
//NEW function .enter().append("input").bind(sourceData.nums, 'data', validationFunction)
d3.selection.prototype.bind = function(target, field, validationFunction) {
if (!(validationFunction) && (field) && (field.constructor) && (field.call)) {
validationFunction = field;
field = null;
}
this.each(function(d, i) {
if ( (this.toString() === '[object HTMLInputElement]') || (this.toString() === "[object HTMLTextAreaElement]") ) {
this['Data-BindingTarget'] = target;
this['Data-BindingPath'] = i;
this['Data-BindingField'] = field;
}
});
this.on("keyup.bindingData", function(d, i) {
if ( (this.toString() === '[object HTMLInputElement]') || (this.toString() === "[object HTMLTextAreaElement]") ) {
if ( !(validationFunction) || (validationFunction(d, i, this.value))) {
if (this['Data-BindingField']) {
var fieldName = this['Data-BindingField'];
this['Data-BindingTarget'][this['Data-BindingPath']][fieldName] = this.value;
} else {
this['Data-BindingTarget'][this['Data-BindingPath']] = this.value;
}
}
}
});
return this;
};
d3.select("#example1")
.selectAll("input")
.data(sourceData1)
.enter()
.append("textarea")
.property("value", function(d, i) {
return d;
})
//var sourceData = [4, 8, 15, 16, 23, 42];
//NEW function bind(sourceData, validation)
.bind(sourceData1, function(d, i, value) {
value = +value;
return (value < 100);
})
//END
.sort(function(a, b) {
if (a < b) return 1; if (a > b) return -1; return 0;
});
d3.select("#example2")
.selectAll("input")
.data(sourceData2.nums)
.enter()
.append("input")
.property("value", function(d, i) {
return d;
})
//var sourceData = { nums: [4, 8, 15, 16, 23, 42] };
//NEW function bind(sourceData.nums, null, validation)
.bind(sourceData2.nums, function(d, i, value) {
value = +value;
return (value < 100);
})
//END
.sort(function(a, b) {
if (a < b) return 1; if (a > b) return -1; return 0;
});
d3.select("#example3")
.selectAll("input")
.data(sourceData3.nums, function(d, i) {
if (d)
return d.id;
else
return sourceData3.nums[i].id;
} )
.enter()
.append("input")
.property("value", function(d, i) {
return d.data;
})
// var sourceData = { "nums": [ { "id": 1, "data": 4 }, { "id": 2, "data": 8 }, { "id": 3, "...
//NEW function bind(sourceData.nums, data, validation)
.bind(sourceData3.nums, 'data', function(d, i, value) {
value = +value;
return (value < 100);
})
//END
.sort(function(a, b) {
if (a.data < b.data) return 1; if (a.data > b.data) return -1; return 0;
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment