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

PHPMySQL Server

Avatar of undefined
Last Comment
jonofat

8/22/2022 - Mon
SOLUTION
Dave Baldwin

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
SOLUTION
Julian Hansen

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
ASKER CERTIFIED SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Julian Hansen

@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.
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?
Ray Paseur

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.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
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

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. table after entering data
Ray Paseur

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
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Ray Paseur

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?
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
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.Form
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
Julian Hansen

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);
Ray Paseur

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

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!
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.