Table of checkboxes and radio buttons

Hi,
I am trying to send two values from a checkbox form to the database using PDO.

The form below sends the value for $learner[‘id’], but how do I send another value such as a ‘1’ for absence?

<!DOCTYPE html>
<html lang="en">
  <head>
  <style>
table,th,td
{
border-collapse:collapse;
}
th, td
{
padding:6px;
}
        td { text-align: center; width: 40px; overflow: hidden;  white-space: nowrap;}
</style>
    <meta charset="utf-8">
    <title>Manage Daily Notes</title>
  </head>
  <body>
      <p><a href="..">physCMS home</a></p>
      <?php include $_SERVER['DOCUMENT_ROOT'] . '/artgibney/includes/logout.inc.html.php'; ?>
    <h1>Manage Daily Notes</h1>
    <p><a href="?addcourseform">Add Course</a>  &#8658;  
    <? if(countRows('courses')): ?>
     <a href="?addlearnerform">Add Student</a>
    <? endif; ?>  
    <? if(countRows('learners')): ?>
       &#8658;  <a href="?courses">Manage Courses and Students</a></p>
    <? endif; ?>
                 <form action="?addnotes" method="post">
            <table>
            <tr>
            <th>Course</th>
            <th>Student</th>
            <th>Absence</th>
            </tr>
            <?php foreach (array_reverse($courses) as $course): 
            foreach (array_reverse($learners) as $learner): ?>
                     <tr>
                          <?php if($course['id']==$learner['courseid']): ?>
                      <td> 
                            <?php htmlout($course['course']) ?>
                      </td>
                        <td>           
                            <?php htmlout($learner['learner']);?> 
                        </td>
                        <td>
                           <input type="checkbox" name="absence[]" id="<?php htmlout($learner['id']);?> " value="<?php htmlout($learner['id']);?> ">
                        </td>
                             <?php endif; ?>   
                        </tr>
                <?php endforeach; ?>    
        <?php endforeach; ?>
        </table>
        <input type="submit" value="Submit"> 
        </form>
  </body>
</html>

The index.php file (excerpt) is as follows,

if (isset($_GET['addnotes']))
{
  include $_SERVER['DOCUMENT_ROOT'] . '/artgibney/includes/db.inc.php';

  try
  {
    $sql = 'INSERT INTO notes SET
        userid = :userid,
        date = CURDATE(),
        absence = :id';
    $s = $pdo->prepare($sql);
    foreach($_POST['absence'] as $absence)
    { 
    $s->bindValue(':userid', $absence);
    $s->bindValue(':id', '1');
    $s->execute();
    }
  }
  catch (PDOException $e)
  {
    $error = 'Error adding submitted daily notes data. Click the back button to continue.';
    include 'error.html.php';
    exit();
  }

  header('Location: .');
  exit();
}

Here I set the ‘absence’ value to ‘1’ in index.php. But I would like to set the value in the form.

Any help would be greatly appreciated,
Thanks,
Shane

Am not entirely sure I get your question. I am going to guess you trying to have some "default/filler"value for a checkbox that isn’t checked.

When a checkbox element is not checked no variable is sent at all, so technically you can’t. HOWEVER, if you know you ALWAYS want to have some default value for your checkbox you could check AFTER SUBMIT if it was passed at all, and add the default value if it wasn’t.

eg.:
if ($submited) {if (!isset ($learner['id'])) {$learner['id']=1;} }

hope that helps

Hi,
Thanks for the reply. Sorry for not being clear.
When the checkbox is ticked I want a new row in the table with a ‘1’ in the ‘absence’ column and the learner’s id in the userid column.
So only want to send a value if the checkbox is ticked.

I didn’t know this was possible and it might be useful.
So then is it not possible that using a checkbox, both the value ‘1’ and the learner’s id are sent to POST?
Thanks,
Shane

the DB table or the table you are using to lay out your form?

either way the best method would be as I mentioned earlier and check for the existence of the variable after the form is submitted

IF , on the other hand what you want to happen is that as soon as the checkbox is ticked, the user sees a new the row appear in the form, you will need to use AJAX (or at least .js) to insert the element.

So what variable should I check for, since POST only sends the value of the ‘absence’ array which has the value of the learner’s id?

The table is,

the form,

As you can see from the other columns in the table, I will want to add to the form a column of other checkboxes to fill the other columns in the table. But that is the next stage!

(NB The course called ‘computing’ is just an example, I do not teach computing, clearly!!!)

Thanks,
Shane

Ok, so in index.php I am trying to do something like this,

if (isset ($learner[‘id’])) {
then insert learner[‘id’] into DB;
and on the same row add 1 to the absence column.
}

But that is actually what the code does already. This wont allow me send the value ‘1’ and the learner[‘id’] when a box is ticked.

What about a two dimensional array?

What I really want is a form that looks like this,

to fill a table. But the user’s id or learner’s id needs to be in the last column of the table.

Thanks,
Shane

Well you don’t really need to pass 1 if the student is absence, just their id. However I believe you will also need the course id otherwise how will you know what class they were absent from? I would suggest putting the course id as the KEY for absence and the student id as the value for the check box. Then a simple foreach loop can grab those values for DB insert. Here’s a rough sample.

    <?php 
    $courses = array(
        1 => array("id" => "1", "course" => "Course 1"),
        2 => array("id" => "2", "course" => "Course 2"),
        3 => array("id" => "3", "course" => "Course 3"),
        4 => array("id" => "4", "course" => "Course 4"),
        5 => array("id" => "5", "course" => "Course 5"),
        6 => array("id" => "6", "course" => "Course 6"),
        7 => array("id" => "7", "course" => "Course 7")
        );
    $learners = array(
        1 => array("id" => "1", "learner" => "Learner 1"),
        2 => array("id" => "2", "learner" => "Learner 2"),
        3 => array("id" => "3", "learner" => "Learner 3"),
        4 => array("id" => "4", "learner" => "Learner 4"),
        5 => array("id" => "5", "learner" => "Learner 5"),
        6 => array("id" => "6", "learner" => "Learner 6"),
        7 => array("id" => "7", "learner" => "Learner 7")
        );
    
    if(isset($_POST['submit'])):
        
        if(isset($_POST['absence'])):
            foreach($_POST['absence'] as $courseID => $studentID):
                $absence = "1";
                // INSERT INTO DB here.  Echo for test
                echo "courseID:".$courseID."studentID:".$studentID."absence:".$absence."<br />";
            endforeach;
        endif;
    
    endif;
    ?>

<!DOCTYPE html>
<html lang="en">
<body>
<form action="" method="post">
    <table>
        <tr>
            <th>Student</th>
        <?php foreach ($courses as $course): ?>
            <th><?php htmlout($course['course']) ?></th>
        <?php endforeach; ?>
        </tr>
        
        <?php foreach ($learners as $learner): ?>
        <tr>
            <td><?php htmlout($learner['learner']);?></td>
            
            <?php foreach ($courses as $course): ?>
                <td align="center">
                    <input type="checkbox" name="absence[<?php htmlout($course['id'])?>]" value="<?php htmlout($learner['id']);?>" />
                </td>
            <?php endforeach; ?>
            
        </tr>
        <?php endforeach; ?>
    
    </table>
<input type="submit" name="submit" value="Submit"> 
</form>
</body>
</html>

It’s very strange how this forum broke my code apart. Don’t see code tags and part of the code I posted is missing.

Edited aforementioned post by wrapping code example in three backticks as per

Hi,
Thanks for your reply. You are correct I should also pass the student’s id and their course id.
Thanks for the sample code. Setting up an array like that means knowing the size of the array but the array length may change as courses and students are added and deleted.
I will try to get your suggestion working.
Thanks,
Shane

“Knowing the size” is really not a factor if you are building the “Arrays” with DB results. I just made those arrays for the sample.

so… is the data begin stored in the DB table a counter or is it boolean?

In other words, will checking 'absence ’ the next time the page is viewed make absence on the DB table go from 1 to 2?

In an case, the issue my be coordination rather passing two values at once.

you could think of your HTML form as rows on a table and add a at in the name of each input

<input name='course[1]' type="hidden" value="computing">
<input name='student[1]'  type="hidden"  *value="student1">
<input name='abs[1]' type checkbox>
<!--->
<input name='course[2]' type="hidden" value="course2">
<input name='student[2]'  type="hidden"  *value="student1">
<input name='abs[2]' type checkbox>

ITS IMPERATIVE TO PUT THE KEY in your variable name, this way you can iterate through each row, and still check whether corresponding checkboxes are set or not.

I used the format like dresden_phoenix described when I made a similar attendance script where I had multiple checkboxes for “Late”, “Absent”, “Excused” etc and passed course and student id’s with hidden field with forced KEYs. It all depends upon your needs.

Hi,
I am sorry I have not replied. Drummin I was rwading your script and realised I don’t really get arrays so I had to go off and play with them for a while. I now understand what you did in your script.
What I am looking for is a table of checkboxes which corresponds with the table, almost exactly in the DB. So if a student is absent a row in the DB is created and with a 1 for the absence and the student’s id and course id. All this info goes on one row of the DB.
dresden_phoenix I am not really lookimg to simply increase the absence value by one each time, because that way i won’t be able to tell on what day a student was absent.
If I can get this to work I would like to then add another column to the checkbox form of say for example ‘equipment’ and ticking this box would add this info to the same row as the previous information.
If that succeeds it shouldn’t be difficult to add any number of columns to the table of checkboxes.
I have been thinking about the idea mentioned above of using type=‘hidden’ to get variables from the for to index.php for putting in to the DB.
I will have to read up on what is meant by a ‘forced’ KEY. I have only just figured out how the key => value works for arrays!!!
Thank you all for your replies,
Shane

If you are planning on adding other checkboxes then you should switch to using hidden fields and forced KEYs. All I really mean by that is setting a variable before the foreach loop, then incrementing as you iterate through the different loops so each set of form inputs has a unique key. Processing would need to be handled differently. Here’s an example with forced keys.

<?php 
$courses = array(
    1 => array("id" => "1", "course" => "Course 1"),
    2 => array("id" => "2", "course" => "Course 2"),
    3 => array("id" => "3", "course" => "Course 3"),
    4 => array("id" => "4", "course" => "Course 4"),
    5 => array("id" => "5", "course" => "Course 5"),
    6 => array("id" => "6", "course" => "Course 6"),
    7 => array("id" => "7", "course" => "Course 7")
    );
$learners = array(
    1 => array("id" => "1", "learner" => "Learner 1"),
    2 => array("id" => "2", "learner" => "Learner 2"),
    3 => array("id" => "3", "learner" => "Learner 3"),
    4 => array("id" => "4", "learner" => "Learner 4"),
    5 => array("id" => "5", "learner" => "Learner 5"),
    6 => array("id" => "6", "learner" => "Learner 6"),
    7 => array("id" => "7", "learner" => "Learner 7")
    );
$attend = array("P" => "present","A" => "absence","T" => "tardy","E" => "excused");
?>
<!DOCTYPE html>
<html lang="en">
<body>
<form action="" method="post">
    <table>
        <tr>
            <th></th>
        <?php foreach ($courses as $course): ?>
            <th colspan="4"><?php htmlout($course['course']) ?></th>
        <?php endforeach; ?>
        </tr>
        
        <tr>
            <th>Student</th>
            <?php foreach ($courses as $course): ?>
                <?php foreach ($attend as $att_letter => $att_name): ?>
                    <td align="center"><?php echo $att_letter; ?></td>
                <?php endforeach; ?>
            <?php endforeach; ?>
         
        </tr>
        <?php $x = 1;?>
        <?php foreach ($learners as $learner): ?>
        <tr>
            <td><?php htmlout($learner['learner']);?></td>
            
            <?php foreach ($courses as $course): ?>
                <?php foreach ($attend as $att_letter => $att_name): ?>
                <td align="center">
                    <input type="hidden" name='course[<?php echo $x; ?>]' value="<?php htmlout($course['id'])?>">
                    <input type="hidden" name='student[<?php echo $x; ?>]' value="<?php htmlout($learner['id']);?>">
                    <input type="checkbox" name="<?php echo $att_name; ?>[<?php echo $x; ?>]" value="1" />
                </td>  
                <?php $x++;?>
                <?php endforeach; ?>
            <?php endforeach; ?>
            
        </tr>
        <?php endforeach; ?>
    
    </table>
<input type="submit" name="submit" value="Submit"> 
</form>
</body>
</html>

Hi,
I did try to get this method to work but I can’t figure out how to get it in this form into the database.
So I have gone back to my original form. I have two column of checkboxes which produce two arrays absence and late. And am trying to match the nth element of the first array to the nth element of the second array. When there is a match, if($i==$j) one row of data should be sent to the database.
$i is the nth element of the $absence array and
$j is the nth element of the $late array.
Here are the html form and an excerpt form the index.php

<form action="?addnotes" method="post">
           <table>
            <tr>
            <th>Course</th>
            <th>Student</th>
            <th>Absence</th>
            <th>Late</th>
            </tr>
            <?php foreach (array_reverse($courses) as $course): 
            foreach (array_reverse($learners) as $learner): ?>
                     <tr>
                          <?php if($course['id']==$learner['courseid']): ?>
                      <td> 
                            <?php htmlout($course['course']) ?>
                      </td>
                        <td>           
                            <?php htmlout($learner['learner']);?> 
                        </td>
                        <td>
                           <input type="checkbox" name="absence[]" value="1"> 
                        </td> 
                        <td>
                           <input type="checkbox" name="late[]" value="1"> 
                        </td>
                        </tr>
                        <?php endif; ?>
                <?php endforeach; ?>    
        <?php endforeach; ?>
        </table>
        <input type="submit" value="Submit"> 
        </form>

The index.php file

if (isset($_GET['addnotes']))
{
  include $_SERVER['DOCUMENT_ROOT'] . '/artgibney/includes/db.inc.php';
  try
  {
    $sql = 'INSERT INTO notes SET
        date = CURDATE(),
        late = :tardy,
        absence = :id';
    $s = $pdo->prepare($sql);
    $i = 0;
    $j = 0;
    foreach($_POST['absence'] as $absence)
    { 
    $j=0;//reset $j
    foreach($_POST['late'] as $late)
        {    
    if($i==$j){//condition for the same nth element from each array
    $s->bindValue(':id', $absence);
    $s->bindValue(':tardy', $late);
    $s->execute();//should input one row of database
              }
    $j++;
        }
    $i++;
    }
  }
  catch (PDOException $e)
  {
    $error = 'Error adding submitted daily notes data. Click the back button to continue.';
    include 'error.html.php';
    exit();
  }
  header('Location: .');
  exit();
}

I can put in the student and course id later.
But it only works if both the late and absence checkboxes are ticked.
Thanks,
Shane

Well, if you will please forgive me for making the assumption based on your previous posts, you do wish to have courses listed across the top, students names down the left side and attendance under each class column. I believe you also need to add the student and class id’s to your “notes” table at the time of processing or it will be very hard after the fact to update these records with the correct student and class id’s. I’ve made another sample, which hopefully will work for you that includes processing code. This is untested and table field names might need to be modified. Hopefully you can add your $courses and $learners array building queries to this and make it work.

<?php    
$attend = array("A" => "Absence","L" => "Late");

if(isset($_POST['submit'])):
    //echo "<pre>";
    //print_r($_POST);
    //echo "</pre>"; 
    
    if(isset($_POST['Absence']) || isset($_POST['Late'])):
        include $_SERVER['DOCUMENT_ROOT'] . '/artgibney/includes/db.inc.php';
        try
        {
        foreach($_POST['student'] as $key => $studentID):
        
            if(array_key_exists($key,$_POST['Absence']) || array_key_exists($key,$_POST['Late'])):
            
                $studentid = $_POST['student'][$key];
                $courseid  = $_POST['course'][$key];
                $absence   = (array_key_exists($key,$_POST['Absence']) ? $_POST['Absence'][$key] : '0');
                $late      = (array_key_exists($key,$_POST['Late']) ? $_POST['Late'][$key] : '0');
                
                $sql = 'INSERT INTO notes SET
                  userid = :studentid
                , courseid = :courseid
                , date = CURDATE()
                , late = :late
                , absence = :absence';
                $s = $pdo->prepare($sql);
                
                $s->bindParam(':studentid', $studentid);
                $s->bindParam(':courseid', $courseid);
                $s->bindParam(':absence', $absence);
                $s->bindParam(':late', $late);
                $s->execute();
                 
            endif;
            
        endforeach;
        }
        catch (PDOException $e)
        {
            $error = 'Error adding submitted daily notes data. Click the back button to continue.';
            include 'error.html.php';
            exit();
        }
        header('Location: .');
        exit();
        
    endif;
    
endif; 
?>

<form action="" method="post">
    <table>
        <tr>
            <th></th>
        <?php foreach ($courses as $course): ?>
            <th colspan="2"><?php htmlout($course['course']) ?></th>
        <?php endforeach; ?>
        </tr>
        
        <tr>
            <th>Student</th>
            <?php foreach ($courses as $course): ?>
                <?php foreach ($attend as $att_name): ?>
                    <td align="center"><?php echo $att_name; ?></td>
                <?php endforeach; ?>
            <?php endforeach; ?>
         
        </tr>
        <?php $x = 1;?>
        <?php foreach ($learners as $learner): ?>
        <tr>
            <td><?php htmlout($learner['learner']);?></td>
            
            <?php foreach ($courses as $course): ?>
                <?php foreach ($attend as $att_name): ?>
                <td align="center">
                    <input type="hidden" name='course[<?php echo $x; ?>]' value="<?php htmlout($course['id'])?>">
                    <input type="hidden" name='student[<?php echo $x; ?>]' value="<?php htmlout($learner['id']);?>">
                    <input type="checkbox" name="<?php echo $att_name; ?>[<?php echo $x; ?>]" value="1" />
                </td>
                <?php endforeach; ?>  
                <?php $x++;?>
            <?php endforeach; ?>
            
        </tr>
        <?php endforeach; ?>
    
    </table>
<input type="submit" name="submit" value="Submit"> 
</form>

Here’s a sample image of the table layout of above form.

Hi Drummin,
Thanks. I am looking at your code and will try to get it to work for me. (it will take me some time :frowning: )
Sorry, I should have included all of my html table.
Included is a screenshot,

The courses are to the left. I would prefer if the table did not repeat the course name in the first column.
Basically I’d like to have each row of the html table copy as a new row in the table. With a “1” or empty as the check box data.
Each student only does one course.
I thought I would be able to just put in hidden type values in the form to send the course and student ids.
Maybe like this,

<table>
            <tr>
            <th>Course</th>
            <th>Student</th>
            <th>Absence</th>
            <th>Late</th>
            </tr>
            <?php foreach (array_reverse($courses) as $course): 
            foreach (array_reverse($learners) as $learner): ?>
                     <tr>
                          <?php if($course['id']==$learner['courseid']): ?>
                      <td> 
                            <?php htmlout($course['course']) ?>
                             <input type="hidden" name='courseid[]' value="<?php htmlout($course['id'])?>">
                             <input type="hidden" name='learnerid[]' value="<?php htmlout($learner['id'])?>">
                      </td>
                        <td>           
                            <?php htmlout($learner['learner']);?> 
                        </td>
                        <td>
                           <input type="checkbox" name="absence[]" value="1"> 
                        </td> 
                        <td>
                           <input type="checkbox" name="late[]" value="1"> 
                        </td>
                        </tr>
                        <?php endif; ?>
                <?php endforeach; ?>    
        <?php endforeach; ?>
        </table>
        <input type="submit" value="Submit"> 
        </form>
    <form action="?addnotesTWO" method="post">

Thanks for your patience particularly. Unfortunately I can’t consistently work on this.
Shane

Can you post a sample of the arrays you are using? print_r($courses) etc. From the look of the screen shot it would seem that you would use a single array of data to build this table. Maybe show the query and array building process as well.

In order to get input fields to match, you will need to use a forced KEY like I did on my version.