Link to home
Start Free TrialLog in
Avatar of jonofat
jonofat

asked on

php mysql multiple checkbox insert

Hi, I have 2 fields where the user can choose from a-d via checkboxes. Some jobs require all, some don't, etc. What would be the best way to capture this data in a database bearing in mind that it needs to be evaluated at a later stage by job per field. So, if I choose A and B which would be a better way of capturing the data? Either one row with a field showing something like A,B or have two rows added because 2 choices were made? I find it pretty confusing. Anyway, here is the form code.

<form id="form1" name="form1" method="post" action="">
  <p>Job no: 
    <label for="textfield"></label>
  <input type="text" name="textfield" id="textfield" />
  </p>
  <p>Weld : A
    <input type="checkbox" name="checkbox" id="checkbox" />
    <label for="checkbox"></label>
  B
  <input type="checkbox" name="checkbox2" id="checkbox2" />
  <label for="checkbox2"></label> 
  C
  <input type="checkbox" name="checkbox3" id="checkbox3" />
  <label for="checkbox3"></label>
  D
  <input type="checkbox" name="checkbox4" id="checkbox4" />
  <label for="checkbox4"></label>
  <br />
  </p>
  <p>Seal: A
    <input type="checkbox" name="checkbox5" id="checkbox5" />
    <label for="checkbox5"></label>
    B 
    <input type="checkbox" name="checkbox6" id="checkbox6" />
    <label for="checkbox6"></label>
  C
  <input type="checkbox" name="checkbox7" id="checkbox7" />
  <label for="checkbox7"></label>
  D 
  <input type="checkbox" name="checkbox8" id="checkbox8" />
  <label for="checkbox8"></label>
  </p>
  <p>
    <input type="submit" name="button" id="button" value="Submit" />
  </p>
</form>

Open in new window

SOLUTION
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@Ray - the problem with a single column per checkbox is that if you need more columns it is a database structural change that is required - whereas bitmapped fields do not require a change to the database structure.

Searching is also a lot easier

select * from table where mask & searchmask = searchmask

will allow you to quickly find records that have a given number of checkboxes checked as opposed to

select * from table where col1=1 and col5=1 and col6=1 etc.

Creating child tables to manage checkboxes in my view is overkill and will over complicate the means of accessing and storing the data. I agree space is not a consideration my preference is from ease of coding (accessing and storing data) and adding a join into the mix to me results in more complicated code.

However, both methods will work and it is a matter of preference - I prefer the bit mapped approach in this case.
Avatar of jonofat
jonofat

ASKER

Thanks for the comments guys. Ray, I am using MYSQL and when I create a new database I usually just choose the default as I haven't had to store so much data before. which should I choose for large storage, ie. Myisam etc?
What do you define as "large" storage?  How many tables, rows, bytes, etc?  What kind of query profile (mostly INSERT vs mostly SELECT)?  I just kind of use INNODB reflexively, but there may be a better choice if we can know the details.
Avatar of jonofat

ASKER

Hmm. Not sure how many bytes. Maybe 50 rows a day?

I have another question related to this. Can I ask in this thread or must I ask a new question? Basically, I changed the code as I want to pull from a database. However, only the first line repeats horizontally, the second doesn't show anything.

<form id="form1" name="form1" method="post" action="">
  <table width="45%" border="0" cellspacing="0" cellpadding="0">
    <tr>
      <td>Job number:</td>
      <td><label for="textfield"></label>
      <input type="text" name="textfield" id="textfield" /></td>
    </tr>
    <tr>
      <td>Runs</td>
      <td><label for="runs[]">
        <table >
          <tr>
            <?php
$Recordset1_endRow = 0;
$Recordset1_columns = 3; // number of columns
$Recordset1_hloopRow1 = 0; // first row flag
do {
    if($Recordset1_endRow == 0  && $Recordset1_hloopRow1++ != 0) echo "<tr>";
   ?>
            <td><?php echo $row_Recordset1['defectcode']; ?>
              <input name="runs[]" type="checkbox" id="runs[]" /></td>
            <?php  $Recordset1_endRow++;
if($Recordset1_endRow >= $Recordset1_columns) {
  ?>
          </tr>
          <?php
 $Recordset1_endRow = 0;
  }
} while ($row_Recordset1 = mysql_fetch_assoc($Recordset1));
if($Recordset1_endRow != 0) {
while ($Recordset1_endRow < $Recordset1_columns) {
    echo("<td>&nbsp;</td>");
    $Recordset1_endRow++;
}
echo("</tr>");
}?>
        </table>
      </label></td>
    </tr>
    <tr>
      <td>Misses</td>
      <td><table >
        <tr>
          <?php
$Recordset1_endRow = 0;
$Recordset1_columns = 3; // number of columns
$Recordset1_hloopRow1 = 0; // first row flag
do {
    if($Recordset1_endRow == 0  && $Recordset1_hloopRow1++ != 0) echo "<tr>";
   ?>
          <td><?php echo $row_Recordset1['defectcode']; ?>
            <input name="misses[]" type="checkbox" id="misses[]" /></td>
          <?php  $Recordset1_endRow++;
if($Recordset1_endRow >= $Recordset1_columns) {
  ?>
        </tr>
        <?php
 $Recordset1_endRow = 0;
  }
} while ($row_Recordset1 = mysql_fetch_assoc($Recordset1));
if($Recordset1_endRow != 0) {
while ($Recordset1_endRow < $Recordset1_columns) {
    echo("<td>&nbsp;</td>");
    $Recordset1_endRow++;
}
echo("</tr>");
}?>
      </table></td>
    </tr>
    </table>
</form>

Open in new window

Avatar of jonofat

ASKER

This is what I wanted to achieve initially but not sure if it is the most practical or easiest to draw info from. User generated image
In data base terms, 50 of anything is no big deal.  It would not matter which engine you chose.

I cannot understand the code posted in the most recent snippet.  I could not find the query, so I do not know what might be in the results set.  All the back-and-forth between PHP and HTML is confusing, there are no comments, and the control structures are not lined up.  It almost looks like the programmer was trying to learn PHP by copying DreamWeaver code.  DreamWeaver produces some of the most horribly written PHP that I have ever seen, and it's not really usable as a learning tool or a starting platform for developing a data base driven web site.  

A better learning tool would be this book.  Very readable, with structured explanations and great examples -- very much worth investing a couple of weeks immersed in the learning process.
http://www.sitepoint.com/books/phpmysql5/

Best of luck with your project, ~Ray
Regarding the table after entering data What are the rules that would put A,B,C in the RUNS column and C,F,G in the MISSES column?  Is C supposed to be in both columns?  Would D and E be in play?  If not what rules would we have to tell us that?
Avatar of jonofat

ASKER

Sorry Ray, I am poor at explaining. Here is a simple view of the tables. Maybe this will shed some light as to what I am actually trying to do!

Table : defect_areas

AreaID       Area                  Description
   1                A              left hand under-side
   2                B               left hand top side
   3                C               right hand under-side

Table : defects

DefectID     DefectName
    1                    Runs
    2                    Misses
    3                    Sag

Table : Audit

AuditID       Date           Job no.     DefectID      DefectArea
    1          2012-01-01      8351           1                    A,B,C
    2          2012-01-01      8351           2                    A,C

OR should it be?

AuditID       Date           Job no.     DefectID      DefectArea
    1          2012-01-01      8351           1                    A
    2          2012-01-01      8351           1                    B
    3          2012-01-01      8351           1                    C
Avatar of jonofat

ASKER

And then I would like the form to look like this pic. But how to insert that data is the seriously confusing part.User generated image
This is where I think bit fields would help.

If you defined your form variables as

<input type="text" name="data[date]" />
<input type="text" name="data[jobno]" />
<input type="text" name ="runs[]" value="1" />
<input type="text" name ="runs[]" value="2" />
<input type="text" name ="runs[]" value="4" />
<input type="text" name ="misses[]" value="1" />
<input type="text" name ="runs[]" value="2" />
<input type="text" name ="runs[]" value="4" />

In your code you could then do as follows

$data = $_REQUEST['data']; // For simplicity; normally don't access request arrays directly
$runs = $_REQUEST['runs'];
$misses = $_REQUEST['misses'];

$data['runs'] = 0;
foreach($runs as $r) $data['runs'] |= $r;

$data['misses'] = 0;
foreach($misses as $m) $data['misses'] |= $m;

$data now holds all the fields you want to insert into your database

Define your table like so

CREATE TABLE __whatever (
  id int(11) NOT NULL auto_increment,
  date date default NULL,
  jobno int(11) default NULL,
  runs bit(8) default NULL,
  misses bit(8) default NULL,
  PRIMARY KEY  (id)
)

$fields = $values = '';
foreach($data as $k => $v) {
      $fields .= (empty($fields)?'':',') . $k;
      $values .= (empty($values)?'':',') . "'$v'";
}
$query = sprintf("INSERT INTO __whatever (%s) VALUES (%s)", $fields, $values);
mysql_query($query);
Regarding the post at ID: 38014853, I think I like the second setup for the Audit table.

See if this makes any sense... In real life you would want some additional sanity checks on the input data. but hopefully the design will stimulate some creative thinking ;-)

<?php // RAY_temp_jonofat.php
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
date_default_timezone_set('America/Chicago');

// IF THERE IS A POST REQUEST
if (!empty($_POST))
{
    // VISUALIZE THE POST REQUEST
    echo "<pre>";
    var_dump($_POST);

    // SET DEFAULT VALUES FOR POTENTIALLY EMPTY FIELDS
    $myRuns = (isset($_POST['myRuns']) && is_array($_POST['myRuns'])) ? $_POST['myRuns'] : array();
    $myMiss = (isset($_POST['myMiss']) && is_array($_POST['myMiss'])) ? $_POST['myMiss'] : array();

    // CONVERT THE DATE
    $myDate = date('c', strtotime($_POST['myDate']));

    // DO NOT USE THIS, USE THE FOLLOWING ESCAPE SEQUENCE INSTEAD
    $myJobn = $_POST['myJobn'];
    // $myJobn = mysql_real_escape_string($_POST['myJobn']);

    // CONSTRUCT THE INSERT QUERIES FOR RUNS
    foreach ($myRuns as $myRun)
    {
        $sql = "INSERT INTO Audit (myDate, myJobn, myRuns) VALUES ('$myDate', '$myJobn', '$myRun')";
        echo PHP_EOL . $sql;
    }

    // CONSTRUCT THE INSERT QUERIES FOR MISSES
    foreach ($myMiss as $myMis)
    {
        $sql = "INSERT INTO Audit (myDate, myJobn, myMiss) VALUES ('$myDate', '$myJobn', '$myMis')";
        echo PHP_EOL . $sql;
    }

    // RETURN TO NORMAL FORMATTING
    echo "</pre>";
}

// CREATE THE FORM
$form = <<<ENDFORM
<form method="post">
DATE: <input name="myDate" /><br/>
JOB#: <input name="myJobn" /><br/>
RUNS:
<input type="checkbox" name="myRuns[]" value="A" />A &nbsp;
<input type="checkbox" name="myRuns[]" value="B" />B &nbsp;
<input type="checkbox" name="myRuns[]" value="C" />C &nbsp;
<br/>
MISS:
<input type="checkbox" name="myMiss[]" value="A" />A &nbsp;
<input type="checkbox" name="myMiss[]" value="B" />B &nbsp;
<input type="checkbox" name="myMiss[]" value="C" />C &nbsp;
<br/>
<input type="submit" />
</form>
ENDFORM;

echo $form;

Open in new window

Avatar of jonofat

ASKER

Thanks guys, I am going to give you both equal points for your earlier posts with suggestions on how to do it. I have gone with Ray's way simply because I am able to wrap my head around that where I am not at all familiar with bit fields. Thanks for the help, hopefully I have this figured out now, now that I have physically drawn out the database structure and I know exactly what I want to happen. Thanks!