Reputation: 41
I've run into a strange scenario using D3 to create a simple form-like experience.
The flow goes something like this...
1) Create the element using D3, with a default value
2) Bind a function to a button to read the value of this text area and do stuff
var content = d3.select('#content');
content.append('div')
.append("input")
.attr("type", "text")
.attr("id", "textinput")
.attr("size", "40")
.attr("value","Default Text");
content.append('div')
.html('Get contents...')
.on("click", function () {
console.log("D3 Selection: " + d3.select("#textinput").attr('value'));
console.log("DOM Selection: " + document.getElementById("textinput").value);
});
The value of the DOM selection is whatever has been entered by the user, and the value of the D3 selection is always "Default Text", no matter what the user has entered:
D3 Selection: Default Text
DOM Selection: I typed something
What am I missing (aside from the obvious knowledge, skill etc. - in my defense I mostly just do this for fun)? Is the D3 selector not supposed to function in this way?
Dave
Upvotes: 2
Views: 1508
Reputation: 10886
Instead of using .attr(), you should use .property() instead.
according to: https://github.com/d3/d3-3.x-api-reference/blob/master/Selections.md#property
Some HTML elements have special properties that are not addressable using standard attributes or styles. For example, form text fields have a
value
string property, and checkboxes have achecked
boolean property. You can use the property operator to get or set these properties, or any other addressable field on the underlying element, such asclassName
.
The reason why you can set the value via the .attr() method, but not get it, is because .attr() interacts with the underlying HTML. User interaction doesn't affect the HTML, so those changes aren't reflected when you get via .attr().
Edit: Updated the link to the d3v3 API. The same also holds true for d3v4, though the description is slightly different: https://github.com/d3/d3-selection/blob/master/README.md#selection_property
Upvotes: 3
Reputation: 20422
You would get the same "Default Text" from DOM if you called:
document.getElementById("textinput").getAttribute("value")
You can get the input value from a d3 selction accessing node()
first:
d3.select("#textinput").node().value
Upvotes: 1
Reputation: 40647
When you do
.attr("id", "textinput")
.attr("size", "40")
.attr("value","Default Text");
You are giving the #textinput element a value=Default text i.e:
<div id="textinput" value="Default Text"></div>
So you are not making its innerHTML Default Text but you are giving it an attribute like a class. And in the console you are asking for that value with your d3 selection.
Upvotes: 0