score:3

Accepted answer

According to your comment, you are not sending this information to anywhere. Therefore, you don't need a form.

So, just append regular text inputs to that div...

var div = d3.select("#rectInfo")

var labelText = div.append("p")
    .text("Label: ");

var labelInput = labelText.append("input")
    .attr("size", "15")
    .attr("type", "text")
    .attr("value", d.label);

var xPosText = div.append("p")
    .text("X pos: ");

var xPosInput = xPosText.append("input")
    .attr("size", "15")
    .attr("type", "text")
    .attr("value", d.x);

var yPosText = div.append("p")
    .text("Y pos: ");

var yPosInput = yPosText.append("input")
    .attr("size", "15")
    .attr("type", "text")
    .attr("value", d.y);

... and create a button that, on "click", gets the values of the inputs and changes the x, y and label properties:

var button = div.append("button")
    .text("Submit/Hide")
    .on("click", function() {
        d3.select(self).attr("x", function(d) {
            return d.x = +xPosInput.node().value
        }).attr("y", function(d) {
            return d.y = +yPosInput.node().value
        });
        d3.select("#text" + i).text(function(d) {
                return "Label: " + (d.label = labelInput.node().value);
            })
            .attr("x", function(d) {
                return d.x = +xPosInput.node().value + 10
            }).attr("y", function(d) {
                return d.y = +yPosInput.node().value + 10
            });
    })

Pay attention to this pattern:

return d.x = +xPosInput.node().value

It does two things:

  1. It returns a value (in this case, +xPosInput.node().value);
  2. It assigns that value to d.x, therefore changing our datum.

Also, the input returns a string, even if the user types a number... that's why there is a unary plus operator before xPosInput.node().value in the example above.

As a final note, I'm not a fan of removing/re-appending elements (I'm talking about the div). You could simply updated them. However, as I told you in my other answer, this is a different issue and here at S.O. we try to keep just one issue per question (so, I'm not dealing with it in this answer).

Here is your code with those changes:

var rectInfoActive = false;
var rectData = [{
  "label": "one",
  "x": 100,
  "y": 50,
  "height": 100,
  "width": 120,
  "color": "green"
}, {
  "label": "two",
  "x": 250,
  "y": 50,
  "height": 100,
  "width": 120,
  "color": "purple"
}, {
  "label": "three",
  "x": 400,
  "y": 50,
  "height": 100,
  "width": 120,
  "color": "red"
}];

var svg = d3.select("body").append("svg")
  .attr("width", 600)
  .attr("height", 200);

var rects = svg.selectAll("rect")
  .data(rectData)
  .enter()
  .append("g");

rects.append("rect")
  .attr("x", function(d) {
    return d.x;
  })
  .attr("y", function(d) {
    return d.y;
  })
  .attr("height", function(d) {
    return d.height;
  })
  .attr("width", function(d) {
    return d.width;
  })
  .style("fill", function(d) {
    return d.color;
  })
  .on('mouseover', function(d) {
    var rectSelection = d3.select(this)
      .style({
        opacity: '0.5'
      })
  })
  .on('mouseout', function(d) {
    var rectSelection = d3.select(this)
      .style({
        opacity: '1'
      })
  })
  .on("click", function(d, i) {

    var self = this;

    if (rectInfoActive == true) {
      // clicked a node while previous info block displayed
      d3.selectAll("input").remove();
      d3.selectAll(".formEle").remove();
      d3.select("#rectInfo").selectAll("*").remove();
      d3.select("#rectInfo").style("opacity", 0);
    }

    d3.select("#rectInfo").style("opacity", 1);

    // Form displayed in /div becomes visible onclick of a rect.
    // submit button clears the form. No data update yet.
    var div = d3.select("#rectInfo")

    var labelText = div.append("p")
      .text("Label: ");

    var labelInput = labelText.append("input")
      .attr("size", "15")
      .attr("type", "text")
      .attr("value", d.label);

    var xPosText = div.append("p")
      .text("X pos: ");

    var xPosInput = xPosText.append("input")
      .attr("size", "15")
      .attr("type", "text")
      .attr("value", d.x);

    var yPosText = div.append("p")
      .text("Y pos: ");

    var yPosInput = yPosText.append("input")
      .attr("size", "15")
      .attr("type", "text")
      .attr("value", d.y);

    var button = div.append("button")
      .text("Submit/Hide")
      .on("click", function() {
        d3.select(self).attr("x", function(d) {
          return d.x = +xPosInput.node().value
        }).attr("y", function(d) {
          return d.y = +yPosInput.node().value
        });
        d3.select("#text" + i).text(function(d) {
            return "Label: " + (d.label = labelInput.node().value);
          })
          .attr("x", function(d) {
            return d.x = +xPosInput.node().value + 10
          }).attr("y", function(d) {
            return d.y = +yPosInput.node().value + 10
          });

        d3.select("#rectInfo").selectAll("*").remove();
        d3.select("#rectInfo").style("opacity", 0);
      })

    rectInfoActive = true;



  });
// END OF FORM

// Rectangle Label
rects.append("text")
  .attr("id", function(d, i) {
    return "text" + i
  })
  .style("fill", "black")
  .attr("dy", ".35em")
  .attr("x", function(d) {
    return d.x + 10;
  })
  .attr("y", function(d) {
    return d.y + 10;
  })
  .text(function(d) {
    return "Label: " + d.label
  });



// Misc functions -------------------------------------------------------------
// clearTheForm ----
// Clear the form and input values. This will later become the Update function
//  that will update changed values back into the JSON array.
#rectInfo {
  background-color: white;
  position: relative;
  padding: 10px;
  width: 230px;
  height: 100px;
  border: 2px;
  outline: grey solid thin;
}

#rectInfo p {
  margin: 4px;
}

.formLabel {
  font-family: courier;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!-- Click on a shape to see its label, x, y pos.
  Submit button clears the div (not working here in fiddle)
  but should be changed to instead call a fnt that updates the data with values changed in the form.
-->

<div id="rectInfo" style="opacity:0">
  <!-- Rect info will appear here -->
</div>


Related Query

More Query from same tag