0

I require the values of unchecked checkboxes to be '0' so I can determine which values have been checked and for all values (checked + unchecked) to be posted ($_POST['chk]). I am using a for loop to create the checkboxes and I am generating a hidden field with a value of '0' (as has been suggested elsewhere on stackoverflow).

There are 4 checkboxes ((count($result)-1) = 4) and when checkbox 1 & 3 are checked while checkbox 2 & 4 are unchecked, the $_POST['chk'] array ends up like this:

Array
(
    [chk] => Array
        (
            [0] => 0
            [1] => 180.00
            [2] => 0
            [3] => 0
            [4] => 100.00
            [5] => 0
        )

I want it to look like this:

Array
(
    [chk] => Array
        (
            [0] => 180.00
            [1] => 0
            [2] => 100.00
            [3] => 0
        )

What am I doing wrong? Is this even possible using a for loop and the hidden checkbox fields?

Javascript:

<script type="text/javascript">
function calculate() {
var el, i = 0;
var subtotal = 0;
while(el = document.getElementsByName("chk[]")[i++]) {
    if(el.checked) { subtotal = subtotal + Number(el.value);}
        }
        var node = document.getElementById("subtotal");
        node.innerHTML = "$" + subtotal + ".00";
        var node = document.getElementById("total");
        node.innerHTML = "$" + (subtotal*<?=$no_nights?>) + ".00";
        }   
</script>

HTML/PHP:

<form id="booking_step2" name="booking_step2" method="POST" action="index.php?p=bookings?s=3">
                <? for ($x=0; $x<=(count($result)-1); $x++) { ?>
                            <input type="hidden" name="chk[]" value="0">
                            <input type="checkbox" name="chk[]" value="<?=$result[$x]['r_rate'];?>" onclick="calculate()">
                   <? } ?>
Community
  • 1
  • 1
Accolade
  • 149
  • 3
  • 15

1 Answers1

1

You are incorrectly using chk[] as the name of the controls. This will give you one element inside $_POST for each unchecked box, but two for each checked one. And the extra elements might be present anywhere inside the array, so you won't be able to make sense of it.

Instead of this, explicitly specify the same index for each pair of hidden input and checkbox:

<? for ($x=0; $x<=(count($result)-1); $x++): ?>
    <input type="hidden" name="chk[<?=$x?>]" value="0">
    <input type="checkbox" name="chk[<?=$x?>]" value="<?=$result[$x]['r_rate'];?>">
<? endfor; ?>

After doing this a checked box will have exactly the same name chk[N] as the hidden input that precedes it, so it will simply trump that value instead of adding another one at the end of the array.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • What do I do with the Javascript? while(el = document.getElementsByName("chk[]")[i++]) { – Accolade Sep 02 '14 at 22:53
  • @Accolade: You replace it with something else that is appropriate. For example, you can give all the input elements a specific class and use `document.getElementsByClassName` or use `document.querySelectorAll("#booking_step2 > input")`, if this is your actual HTML. – Jon Sep 02 '14 at 22:55
  • Adding a class name to the inputs `` and using `while(el = document.getElementsByClassName("blah")[i++]) {` doesn't seem to work? – Accolade Sep 02 '14 at 23:16
  • @Accolade: That's a quite bad way to use `getElementsByClassName`, but it should work anyway. If you have trouble debugging it, put a concrete example on JSfiddle. – Jon Sep 02 '14 at 23:24