2

I'm building a form with the possibility to add more group of fields, to process them i read out the array in a for loop

the script:

<?php
foreach ($_POST as $key => $value) {
  $$key = $value;
}
$count = count($name);
for ($i=0; $i<$count; $i++){
?>
  <strong><?php echo $name[$i]; ?></strong>  (<?php echo $check[$i]; ?>)<br /><?php echo $select[$i]; ?><br /><br />
<?php
}
?>
<form method="post">
<div class="group">
 <input type="text" name="name[]" /><br />
 <input type="checkbox" name="check[]" value="true" /><br />
 <select name="select[]"><option>1</option><option>2</option><option>3</option></select>
</div>
<div class="group">
 <input type="text" name="name[]" /><br />
 <input type="checkbox" name="check[]" value="true" /><br />
 <select name="select[]"><option>1</option><option>2</option><option>3</option></select>
</div>
<div class="group">
 <input type="text" name="name[]" /><br />
 <input type="checkbox" name="check[]" value="true" /><br />
 <select name="select[]"><option>1</option><option>2</option><option>3</option></select>
</div>
<button>Add another group</button>
<input type="submit" />
</form>

If all checkboxes are checked there is no problem but if only the last one is checked it counts only one checkbox in the array, name[0] is then combined with check[0] but check[0] is really check[2]. English is not my native language so i don't know the right words.

Gijs
  • 2,064
  • 16
  • 21
  • 1
    This is caused because an unchecked checkbox does not register. Consider giving your fields names like `name1` and `check1` – Dutchie432 Mar 31 '11 at 15:27
  • they are dynamically added and randomly ordered so i'm searching for another solution – Gijs Mar 31 '11 at 15:31
  • Good luck. No such workaround exists. You'll need to use either `name1` or `name[1]` - or use something other than checkboxes. You might be able to add a hidden input called `checkValue` (set by default to 0 or 1, depending on the checkboxes state. Then when you click the checkbox, change the hidden field's value as well. This way you will always have the same number of `checkValue` items as you do `name` items – Dutchie432 Mar 31 '11 at 15:32

4 Answers4

7

Actually, there is a decent workaround for this as proposed by Sam in this answer on Stack Overflow:

Post the checkboxes that are unchecked

It worked for me, and I suspect you and I had a similar problem (mine being that I had/have upwards of 300 input fields in similar(ish) groups and didn't want to write validation rules for every one of those individual fields, just rules targetted at each family of input types e.g. the email addresses, or the postcodes. In brief, the technique is that you place a hidden input field, with the same name, before your checkbox field. Setting the value of the hidden field (type='hidden') to '0' will ensure that at least one key/value appears in your POST array, with the '0' being superceded by a later '1' only if the box is checked. I needed the '0' value to allow people to 'unset' an option they had previously 'set', for example that they were willing to show their contact data. This technique allows me to present the user with much the same form for an update as they would get at at first registration. Thanks to Sam!

Community
  • 1
  • 1
Geoff Kendall
  • 1,307
  • 12
  • 13
2

That's normal PHP behaviour, when a checkbox is not checked it does not includes it in $_POST variable ...

yent
  • 1,303
  • 1
  • 8
  • 10
1

Yes. That's how it is. There is no workaround for this. Using field[] identifiers is only applicable for unstructured input fields. If you depend on the ordering and relation, then unset fields will prevent this from working.

You have no other option but to set explicit indexes. You should bite into the sour apple and do so for name[0], check[1] and select[2]. Use a PHP loop to simplify it:

foreach (range(0,2) as $i)
echo <<< END
<div class="group">
 <input type="text" name="name[$i]" /><br />
 <input type="checkbox" name="check[$i]" value="true" /><br />
 <select name="select[$i]"><option>1</option><option>2</option><option>3</option></select>
</div>
END
mario
  • 144,265
  • 20
  • 237
  • 291
0

I was having the same exact problem with some parts of a form that can be add on user's wish. I came to this really simple workaround using basic javascript:

Add a hidden type input just after your checkbox, assign its value to the state of the checkbox and it's this hidden input that will be reported in your $_POST, will be true or false.

<input type="checkbox" onchange="this.nextSibling.value = this.checked">
<input type="hidden" name="state[]" value="false">

Just change value to true if your checkbox is checked="checked" by default.

Zou
  • 3
  • 2