19

I have a form that can be dynamically duplicated (with JS) so that the user can enter as much data as he wants. This works great for text inputs, because I just leave the name attribute the same (ending with a []) and then when the values are posted, it just returns me an array. Now I just realized that this doesn't work so well for radio buttons, because the names actually need to be unique for each set. But from the data standpoint, each set only returns one value, so retrieving the data from the POST data wouldn't be a problem, it just screws up the functionality of my form. There's no way around this, is there? I'm just screwed and I can't use arrays?

mpen
  • 272,448
  • 266
  • 850
  • 1,236

4 Answers4

32

I just solved this same problem.

If you have more than one group of radio buttons, you can still use them in arrays:

<input type="radio" name="radiobutton[0]" value="a"><br>
<input type="radio" name="radiobutton[0]" value="b"><br>
<input type="radio" name="radiobutton[0]" value="c"><br>
<br>
<input type="radio" name="radiobutton[1]" value="x"><br>
<input type="radio" name="radiobutton[1]" value="y"><br>
<input type="radio" name="radiobutton[1]" value="z">

for example.

When you submit that form, and assuming you pick "a" and "x", you will have an array "radiobutton" that looks like

radiobutton[0] = "a";
radiobutton[1] = "x";

It works because each group has a unique name, but still uses the array syntax.

Austin Hyde
  • 26,347
  • 28
  • 96
  • 129
  • 1
    Arghh...it's so simple >.< Well.. it's still a pain because you have to modify the array index in the name via JS, but... oh well. – mpen May 12 '10 at 02:00
  • why it is not working when you just put [] instead of [0],[1]. Just putting [] works fine with text inputs but doesnt work with radio buttons. arrgggg – Ataman Apr 25 '15 at 07:13
  • 2
    @Ataman: because if you just have `name="radiobutton[]"`, then the browser can't distinguish between two different groups, and instead think they're all part of one group literally named "radiobutton[]". You need the array indexes to uniquely identify the different groups of radio buttons – Austin Hyde Apr 29 '15 at 23:52
  • This just saved me. Hours of searching but I found what I needed in this post. +1 – wordman Jul 01 '15 at 22:10
3

Yeah. From the perspective of HTTP, both radio buttons and checkbox sets are pretty much the same thing (except that selecting a radio button deselects all others in the group).

You might be able to have a submit handler which takes the inputs from the radio button sets and converts them into a bunch of standard inputs that turn into an array, but this is quite hacky. Just put in some more code on the server to build your own array if that's what you need.

Yuliy
  • 17,381
  • 6
  • 41
  • 47
  • *sigh* Yeah... guess I'll have to do that. I spent hours making everything else work the other way, and then tried adding one little yes/no radio button to my form and the whole thing explodes catastrophically. – mpen Apr 11 '10 at 23:58
  • If it's just yes-no: why is it a radio button? Just make it a checkbox – Yuliy Apr 12 '10 at 00:00
  • @Yulify: I thought about that, but it still doesn't solve the problem. The browsers don't send the value at all if it isn't checked. Therefore, there's no way of associating which form the checked boxes correspond to. – mpen Apr 12 '10 at 00:16
  • Use the value of the checkbox to identify the form. – Yuliy Apr 12 '10 at 01:05
  • Eh? How can I do that? The values are exactly the same from form to form? – mpen Apr 12 '10 at 07:08
  • So make them different when you're cloning the checkboxes. – Yuliy Apr 12 '10 at 07:23
  • That's just as much work but more hacky than the non-array solution! – mpen Apr 15 '10 at 07:01
  • A bit late to the game, but another workaround is to replace radio buttons with a dropdown select. Then you can keep the same name and the array notation. – avioing Apr 12 '12 at 06:41
0

There is a caveat to using arrays in CSS3 and HTML5

<input type="radio" name="radiobutton[0]" value="a"><br>
<input type="radio" name="radiobutton[0]" value="b"><br>
<input type="radio" name="radiobutton[0]" value="c"><br>
<br>
<input type="radio" name="radiobutton[1]" value="x"><br>
<input type="radio" name="radiobutton[1]" value="y"><br>
<input type="radio" name="radiobutton[1]" value="z">

But to use the label tag and for="" properly to get clickable labels and for psuedo classes to work the array keys have to be unique and associative rather than numerical. So do this

<label for="a">text</label>
<input type="radio" name="radiobutton[a]" id="a" value="a"><br>
<label for="b">text</label>
<input type="radio" name="radiobutton[b]" id="b" value="b"><br>
<label for="c">text</label>
<input type="radio" name="radiobutton[c]" id="c" value="c"><br>
<br>
<input type="radio" name="radiobutton[x]" id="x" value="x"><br>
<input type="radio" name="radiobutton[y]" id="y" value="y"><br>
<input type="radio" name="radiobutton[z]" id="z" value="z">

Otherwise wrapping the element with the label still works but the above is cleaner and make it easier to do. An example CSS using labels to mark the elements without wrapping.

/* SQUARED Four */
.squaredFour {
height: 30px;
margin: 10px auto;
position: relative;

}

.squaredFour input
{
top: -28px;
left: 0px;
position: relative;
border: 1px solid #999;

}

.squaredFour .element-description
{
display: block;
margin: 0;
position: absolute;
}

.squaredFour label {
cursor: pointer;
position: absolute;
width: 33px;
height: 30px;
top: -40px;
background-color: rgb(200, 242, 163);/*background-color: #c8f2a3;*/
display: block;
color:#111;


}

.squaredFour label span.a{
position: absolute;
height: 4px;
top: 18px;
left: 7px;
background-color: #111;
display: block;
color:#111;
-moz-transform: rotate(40deg);
-ms-transform: rotate(40deg);
-o-transform: rotate(40deg);
transform: rotate(40deg);
width: 10px;

}
.squaredFour label span.b{
position: absolute;
width: 18px;
height: 4px;
top: 14px;
left: 10px;
background-color: #111;
display: block;
color:#111;
-webkit-transform: rotate(128deg);
-moz-transform: rotate(128deg);
-ms-transform: rotate(128deg);
-o-transform: rotate(128deg);
transform: rotate(128deg);

}
.squaredFour label span.c{
position: absolute;
right: 12px;
top:3px;
display: block;
color:#111;
text-wrap: none;

}

.squaredFour input:checked ~ label {
display:block;
background-color: #f16870;
}

.squaredFour input:checked ~ label span.a{
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
width: 21px;
top: 13px;
left: 6px;
}
.squaredFour input:checked ~ label span.b{
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
top: 13px;
left: 6px;
width: 21px;

}   
Carl McDade
  • 634
  • 9
  • 14
  • That doesn't make sense. HTML doesn't care about square brackets, only PHP interprets those as "arrays". http://jsfiddle.net/mnpenner/vcysubch/ Works fine with numeric, repeating names. Labels "for" attribute corresponds with the input's ID, not name. – mpen May 21 '15 at 17:51
  • this is specific to the use of pseudo classes and capturing the click event using CSS3 – Carl McDade May 21 '15 at 21:38
  • Can you update your example to include the relevant CSS? – mpen May 21 '15 at 22:28
0

name="choice[1][]" name="choice[2][]"

Seems to work, so if you're adding dynamically and it's things associated with an ID (or you could just increment something each time maybe) then you can do:

var el = '<input type="radio" name="choice[' + myID + '][] />';

Just tried this on some dynamically-generated radiobuttons and PHP $_POST contains this for the 'mandatory' radio buttons for ThingIDs 6, 10, 8:

[mandatory] => Array
    (
        [6] => Array
            (
                [0] => 1
            )

        [10] => Array
            (
                [0] => 1
            )

        [8] => Array
            (
                [0] => 0
            )
    )