3

So, my webpage has a html-table which displays rows with one item pr. row including various data regarding that item in the columns.

The table is populated using mysqli call to db. So far so good.

Excerpts of the table look like this (I've tried to only show the "important" parts of the code to avoid cluttering - there 8 more text fields similar to "nytAntalGangeUdfoert" for each item)

<td><input type="text" name="nytAntalGangeUdfoert[]" value="<?php echo $antalGangeUdfoert ?>"></td>

<?php if ($aktivStatus == 1) { ?>
    <td><input type="checkbox" name="nyAktivStatus[]" value="<?php echo $aktivStatus ?>" checked="checked"/></td>
<?php } else { ?>
    <td><input type="checkbox" name="nyAktivStatus[]" value="<?php echo $aktivStatus ?>" /></td>

The text field(s) works fine in all aspects.

For the checkbox, the if-else part decides whether the checkbox should be displayed as checked (active or not) dependent on the value in my db-table (1 or 0) This works fine.

I then have 'duplicate' hidden fields to log the original status of the checkbox for later comparison after posting:

<td><input type="hidden" name="antalGangeUdfoert[]" value="<?php echo $antalGangeUdfoert ?>"></td>
<td><input type="hidden" name="aktivStatus[]" value="<?php echo $aktivStatus ?>"></td>

All of this is posted to another page where it is handled as follows (again, only excerpts of the full table). 'aktivstatus' is the old status from db, and 'nyaktivstatus' is the one posted (i.e. the one selected by the user via the checkboxes - can of course be the same as original state)

if(isset($_POST['submit']))
{
    $antalGangeUdfoert = $_POST["antalGangeUdfoert"];
    $nytAntalGangeUdfoert = $_POST["nytAntalGangeUdfoert"];
    $aktivStatus = $_POST["aktivStatus"];

    foreach( $navn as $n => $n )
    {
        if(isset($_POST["nyAktivStatus"][$n])) {
            $nyAktivStatus[$n] = 1;
        } else {
            $nyAktivStatus[$n] = 0;
        }
        if( $antalGangeUdfoert[$n] <> $nytantalGangeUdfoert[$n] || $aktivStatus[$n] <> $nyAktivStatus[$n]) {
//run function to update items where a change has been made by the user)

As stated earlier, the above approach works fine for all the text fields, but in some cases, the new state of a checkbox is saved for the wrong item, apparently (changes to the text fields are correctly saved in db regardless)

Examples below:

Row---status when fetched---user input---saved as

Row1: 1-->0-->1 ERROR
Row2: 1-->1-->1 OK
Row3: 1-->1-->0 ERROR


Row1: 1-->1-->1 OK
Row2: 1-->1-->1 OK
Row3: 0-->1-->1 OK


Row1: 1-->0-->0 OK
Row2: 1-->0-->0 OK
Row3: 1-->0-->0 OK


Row1: 0-->1-->1 OK
Row2: 0-->1-->1 OK
Row3: 0-->1-->1 OK


Row1: 1-->0-->1 ERROR
Row2: 1-->0-->0 OK
Row3: 1-->1-->0 ERROR

FYI at one point, I changed the checkbox into a textfield and manually entered 1 or 0, and this worked fine...not ideal solution, though...

So, I guess there's something going wrong when posting/assigning the "nyaktivstatus' (user entered status)

Can anyone spot the issue in my code? Or spot a pattern that I'm not seeing?

Thanks!

Berriel
  • 12,659
  • 4
  • 43
  • 67
  • 1
    its because only the values of the checked check boxes are sent. read the answer here. http://stackoverflow.com/questions/11424037/does-input-type-checkbox-only-post-data-if-its-checked it might help you to understand the concept – aimme Aug 22 '15 at 19:13

2 Answers2

1

$aktivStatus may not be set at all if the checkbox was not ticked.

Right where you have $aktivStatus = $_POST["aktivStatus"]; try replacing it with:

if (!array_key_exists('aktivStatus',$_POST))
    $aktivStatus = 0;
else
    $aktivStatus = $_POST["aktivStatus"];

This way if the checkbox was not set and the browser did not POST it at all, your variable will assume 0, otherwise it'll assume the value POSTed by browser.

DeDee
  • 1,972
  • 21
  • 30
  • Hi Dedee - thanks for the input. Unfortunately it yielded the same results as my own approach to this if(isset($_POST["nyAktivStatus"][$n])) { $nyAktivStatus[$n] = 1; } else { $nyAktivStatus[$n] = 0; I get all the nyaktivstatus and aktivstatus variabels (I don't get 'null''missing', but for some reason the aktivstatus/nyaktivstatus get assigned to the wrong row... – Erik Lassen Aug 23 '15 at 17:34
  • I see you edited the code, but partially. Where is `$navn` initiated? Also multiple comparisons should be separated, you did a few of them within same brackets, to give you an idea: `if (($x <> $y) || ($a <> $b)) {}`. Also, just do `foreach($navn as $n)`. – DeDee Aug 23 '15 at 19:31
  • this wont work the way we want it to work. As again if the user uncheck and try to send data, the result would be same. as the array would be shifted without the unchecked check boxes' values.so we wouldn't know what check boxes are actually checked or not, as post array was created only with the checked check boxes considered. – aimme Aug 23 '15 at 20:40
  • @DeDee, $navn is initiated just before the $antalGangeUdfoert =...part (not shown above) Actually, I realized that I copied the wrong code to my comment. I did in fact do exactly as you suggested, but got same result as with my own isset-approach. I would believe that my own approach or your approach should giver proper results. But it doesn't :( – Erik Lassen Aug 24 '15 at 17:53
  • @aimme, are you suggesting that the reason that I'm getting weird results is that e.g. if array 1 has active=unchecked, that value is replaced by something else and not left null/empty? – Erik Lassen Aug 24 '15 at 17:53
  • @ErikLassen in case of checkbox post, Ya thats what i am trying to say. If it is a text input (so i used hidden text field) field array value will be assigned with null if empty also.but in case of checkbox as it doesn't exist in the submited form its being ignored and omitted by array while assigning.. So it would be fine for textbox if the value is null. Just uncomment and see my code print_r() function and experiment it. There is no other way to achieve this except my way. I am very sure of it :) – aimme Aug 24 '15 at 20:20
0

As the unchecked checkboxes are not carried on post,in this case we might use a little javascript to take the value of checkboxes to a corresponding hidden text box on the on change event of the checkbox. here's a sample javascript to keep on the same page as my form below. This code is a demonstration on how to achieve the questioners target. Could be possible other ways to achieve this. Sessions could also be used on some parts.

<script type="text/javascript">
function changed(id){
    var checkBoxValue=document.getElementById(id).value;
    id=id.replace('checkbox','');
    hTextBoxid='hidden['+id+']';
    var hiddenTextBox=document.getElementById(hTextBoxid);
    hiddenTextBox.value=checkBoxValue;
}
</script>

Here's the form

<?php
//uncomment for debugging
//if(isset($_POST)){
//for debugging could use this to see the variables that were passed on form submit
//echo '<pre>'; print_r($_POST); echo'</pre>';
//on post of data remember to sanitize and do the checks here server side.
//as we used javascript on the form for checkboxes and hidden text box should varify those post data on server side here.for example whether the check box array count and value matches..
//;}
?>
<form action="" method="post" enctype="application/x-www-form-urlencoded">
<table>
<tr>
<?php
//sample data as if it came from db
$antalGangeUdfoert=array('a','b','c','d','x','y','z');
//sample data as if it came from db
$aktivStatus=array(0,0,1,0,1,1,0);
?>
<?php
$i=0;
//could use a for loop after counting the fetched rows,
//could use other than $aktivStatus, i used $aktivStatus here 
foreach($aktivStatus as $aktivStatus){
echo  '<td><input type="text" name="nytAntalGangeUdfoert['.$i.']" value="'.$antalGangeUdfoert[$i].'"></td><td>';
//check whether its checked depending on activeStatus 
$aktivStatus[$i] == 1? $check='1':$check="0";
//and according to check draw a check box and a hidden text for each
echo '<input type="hidden" id="hidden['.$i.']" name="nyAktivStatus['.$i.']" value="'.$check.'"/>
<input type="checkbox" id="checkbox'.$i.'" value="'.$aktivStatus[$i].'" checked="'.$check.'" onChange="changed(this.id);"/>';
$i++;
};
?>
</td></tr></table>
<input type="submit" name="sub" value="sub"/>
</form>
aimme
  • 6,385
  • 7
  • 48
  • 65
  • Thanks for the input - still a php novice, though, so I wanna get a bit better at that before diving into javascript :) – Erik Lassen Aug 23 '15 at 17:33
  • i don't find it possible with just only php, without using javascript(including libraries or not) as you want to send data that actually considered doesn't exist in html.i mean check boxes unchecked are not considered while posting.if any way to do this myself too would appreciate to know. :) – aimme Aug 23 '15 at 20:47