user3654762
user3654762

Reputation: 41

Simple D3.js text selection

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

Answers (4)

Steve
Steve

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 a checked boolean property. You can use the property operator to get or set these properties, or any other addressable field on the underlying element, such as className.

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

Lukasz Wiktor
Lukasz Wiktor

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

eko
eko

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

Pavel Gatnar
Pavel Gatnar

Reputation: 4053

Use .property('value') instead of .attr('value').

Upvotes: 0

Related Questions