Reputation: 3861
With data like:
var days = ["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"];
I need to have the html structure become:
<div>
<input id="day0" type="checkbox">
<label for="day0">Sun</label>
<input id="day1" type="checkbox">
<label for="day1">Mon</label>
.... Etc
</div>
Currently my current failed solution is:
var selection = d3.select("div");
var enter = selection.selectAll("input").data(days).enter()
enter.append("input")
.attr("type","checkbox")
.attr("id",function(d,i){ return "day"+i;})
enter.append("label")
.attr("for",function(d,i){ return "day"+i;})
.text(function(d,i){return daysAbbr[i];})
Which gives me an incorrect dom of:
<div>
<input id="day0" type="checkbox">
<input id="day1" type="checkbox">
.... Etc
<label for="day0">Sun</label>
<label for="day1">Mon</label>
.... Etc
</div>
How would I go about creating all of these adjacent siblings?
Upvotes: 0
Views: 1035
Reputation: 109232
You're getting this structure because D3 does a batch processing of sorts with the selections. That is, each operation you perform on a selection is performed on all the elements at once.
In your case, you probably want to use .each()
, which allows you to call a function on each element of the selection. The code would look something like this.
var enter = selection.selectAll("input").data(days).enter();
enter.each(function() {
selection.append("input");
selection.append("label");
});
This won't work, as pointed out by @Holger because the .enter()
selection doesn't define .each()
. The way below will work though.
A better solution in your case would be to encapsulate the elements you want to appear together in another div
though. This would allow you to use D3 in a more standard way. The code would look like this.
var enter = selection.selectAll("input").data(days).enter();
var divs = enter().append("div");
divs.append("input");
divs.append("label");
Upvotes: 1