Reputation: 1587
I want to use a dataset to create a set of radio buttons and mark a specific one as default. There are two issues:
First, the text is aligned to the left of the radio button, but it is customary to see it to the right, in HTML like this:
<form><label><input type="radio"...> First label<input...></label>
I've tried using D3 on the labels collection to place the label text after I've set the input tag, but this appears to over-write the input tags.
Second, the default button is indicated with just an unqualified attribute name, "checked" or "selected". I've tried this in the final line of code, but it doesn't appear to work.
This is the code as it stands now, with associated JSFiddle.
var shapeData = ["Arrow", "Cross", "Hexagon", "Star", "Triangle"],
j = 3; // Choose the star as default
// Create the shape selectors
var form = d3.select("body").append("form");
labels = form.selectAll("label")
.data(shapeData)
.enter()
.append("label")
.text(function(d) {return d;})
.append("input")
.attr({
type: "radio",
class: "shape",
name: "mode",
value: function(d, i) {return i;}
})
.attr(function(d, i) {return i==j?"selected":null;});
Upvotes: 2
Views: 5389
Reputation: 1587
A simpler version that avoids using the span and so does it in one step, using D3's insert instead of append.
labels = form.selectAll("label")
.data(shapeData)
.enter()
.append("label")
.text(function(d) {return d;})
.insert("input")
.attr({
type: "radio",
class: "shape",
name: "mode",
value: function(d, i) {return i;}
})
.property("checked", function(d, i) {return i===j;});
Upvotes: 2
Reputation: 4195
First, to get the label/input ordered correctly, you should avoid nesting the input inside the label. So, instead you can insert a div or span on enter and then add the label and the input inside the span like so:
var labelEnter = form.selectAll("span")
.data(shapeData)
.enter().append("span");
labelEnter.append("input")
.attr({
type: "radio",
class: "shape",
name: "mode",
value: function(d, i) {return i;}
})
.property("checked", function(d, i) {
return (i===j);
});
labelEnter.append("label").text(function(d) {return d;});
While this is a bit of a cheat, I believe it's the only way to do what you want here. I don't think there's any way to specify where text is appended in relation to the children of an element in D3. If you were adding elements as children, you could use append() vs insert() to specify whether to append to the end of the list of children or to insert at the beginning. Maybe adding a similar capability for text (if possible) would be a worthwhile pull request to submit to D3.
Now, this also addresses the second question, which is to set the "selected" element, you want to use the d3 selection.property() function, which is made for setting the non-attribute attributes on dom elements. Also, you want to use "checked", not "selected" as the attribute being set:
.property("checked", function(d, i) {
return (i===j);
});
Check out this Fiddle: http://jsfiddle.net/reblace/YyuY4/9/
Upvotes: 2