block by mhkeller da85c740f768b43904af

Two-way data binding experiment from https://groups.google.com/forum/#!topic/d3-js/xJVirdXdaLw

Full Screen

index.html

    <!DOCTYPE html>

    <html xmlns="//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>