How to work with checkboxes in relation to database? - php

Hi I am trying to build a form with checkboxes and upon submitting the form, I want to see which checkboxes were checked and update the database accordingly. How is this done? I've tried so many different code and none of them worked. The closest I've gotten was to update only the checked ones. I also need to update the database if they are unchecked as well like a toggle.
So far my code is like this for the form
<form action="" method="post">
<input type=checkbox" value="<?php echo member['id']; ?>" name="member[]" />
<input type="submit" name="update" value="Update" />
</form>
And for the PHP loop I have (excerpt)
foreach ((array)$_POST['test'] as $member) :
$sql = "UPDATE `sp_members` SET `allow_test` = '1' WHERE `id` = '$member'";
Since I think the loop only picks up the checkboxes that are checked, it doesn't pick up the ones that were orignally checked and now unchecked...
Any help appreciated!

Simply update everything instead of trying to figure out what changed - if you programmed it yourself, you would have to make your code a lot more complicated, and as the database is already optimized for speed, it's better to just stuff it in the DB and let it handle it.

You could use a ternary operator to set the correct value.
$sql = "UPDATE `sp_members` SET `allow_test` = '"
. ( $_REQUEST['checkbox'] ? 1 : 0 )
. "' WHERE `id` = '" . mysql_real_escape_string( $member ) . "'";
It checks $_REQUEST['checkbox'] for a non-null, non-zero string and if true, returns 1, if false, returns 0.

(($_post['member']) ?$allow_test = 1 : $allow_test = 0;
$sql = "UPDATE `sp_members` SET `allow_test` = $allow_test WHERE `id` = '$member'";

The reason why this hasn't been working (and won't in the already provided answers) is because checkboxes that are not checked won't exist in the $_POST/$_REQUEST arrays. The other side of that is if they do exist, they must be true.
When you're doing the check to see what the value is, you are causing an error because the key to the array doesn't exist.
Instead, you need to know the available checkboxes and then check if each isset() in the array.
Webform:
<form action="foo.php" method="post">
<input type="checkbox" value="<?php echo $value1; ?>" name="checkbox1" />
<input type="checkbox" value="<?php echo $value2; ?>" name="checkbox2" />
<input type="submit" name="update" value="Update" />
</form>
PHP:
$checkboxes = array(
'column1' => 'checkbox1',
'column2' => 'checkbox2',
);
foreach ($checkboxes as $column => $checkbox)
{
$value = (isset($_POST[$checkbox]) ? 1 : 0);
$sql = "UPDATE `table` SET `$column` = '$value' WHERE `id` = '$member'";
}

When confronted with this, I usually punt and rely on a transaction to update this stuff for me. As you've discovered, unchecked checkboxes won't get submitted with the form, so you'd have to do tedious comparisons to figure out what's changed each time and build up an appropriate update and/or delete query sequence.
Instead, I fire up a transaction, delete all the old checkbox values stored in the DB, and then insert the new ones submitted with this request. Unless you've got the checkboxes acting as foreign keys and/or triggers set on them at the DB level, this is a relatively lightweight option and saves you the trouble of having to compare the old and new lists for changes.

Related

Information not updating to database after deselecting a checkbox

I am having issues when I untick a checkbox and leave it blank and update my PHP / MySQL form, the data is not saved in the database. Updates text / date fields are working fine.
Code
$learning_opportunities = isset($_POST['learning_opportunities']) ? $_POST['learning_opportunities'] : $contact['learning_opportunities'];
$stmt = $pdo->prepare('UPDATE contacts SET current_living_situation=?, personal_strengths=?, skills_training=?, currently_spend_time=?,personal_goals=?,housing_situation_transport_childcare=?,
learning_actual_end_date=?, partcipant_complete_course=?, withdrawal_reason=?,participant_intended_learning=?,pcp_education=?,
coursestart_date=?,education_provider_name=?,course_title=?,course_level=?,planned_glh=?,in_paid_employment=?,in_paid_employment_start_date=?,
in_paid_employer_name_address=?,in_paid_job_title=?,in_paid_contracted_hour=?,not_in_paid_employment=?,pcp_gap_year=?,
pcp_others=?,pcp_voluntary_work=?,destination_progression_date=?,destination_progression_collection_date=?,project_officer_name=?,
project_officer_signature=?,project_officer_date=?,participant__name=?,participant__signature=?,participant__date=?,
final_assessment_progress_you_made=?,final_assessment_progress_your_goal=?,final_assessment_progress_your_reach_goal=?,
final_assessment_progress_overall=?,final_assessment_participat_name=?,final_assessment_participat_signature=?,
final_assessment_participat_date=?,final_assessment_project_worker_name=?,final_assessment_project_worker_signature=?,
final_assessment_project_worker_date=?,learning_opportunities=?,contact_for_other_purposes=?,empowering_communities=?,empowering_communities_name=?,empowering_communities_sign=?,empowering_communities_date=?,
participant_enrolled_onto=?,participant_moved_another_provider=?,participant_eligible_free_school=?,british_passport=?,
eec_passport=?,euss_via_home=?,preferred_evidence=?,provide_preferred_evidence=?,option_adoption_vertificate=?,option_driving_licence=?,
option_non_eu_passport=?,option_biometric_immigration=?,option_current_immigration=?,option_marriage_civil_partnership=?,
option_other_evidence=?,option_nine=?,details_evidence_provided=?,dwp_job_centre_letter=?,confirmation_relevant_organisation=?,self_certification_evidence=?,
partcipant_told_support=?,participant_file_completed_remotly=?,declaration_name_please_print=?,declaration_job_title=?,declaration_organisation=?,
declaration_signature_date=?,declaration_signature=? where id = ?');
$result = $stmt->execute([$current_living_situation,$personal_strengths,$skills_training,$currently_spend_time,$personal_goals,
$housing_situation_transport_childcare,$learning_actual_end_date,$partcipant_complete_course,$withdrawal_reason,$participant_intended_learning,$pcp_education,
$coursestart_date,$education_provider_name,$course_title,$course_level,$planned_glh,$in_paid_employment,$in_paid_employment_start_date,
$in_paid_employer_name_address,$in_paid_job_title,$in_paid_contracted_hour,$not_in_paid_employment,$pcp_gap_year,$pcp_others,
$pcp_voluntary_work,$destination_progression_date,$destination_progression_collection_date,$project_officer_name,$project_officer_signature,
$project_officer_date,$participant__name,$participant__signature,$participant__date,$final_assessment_progress_you_made,
$final_assessment_progress_your_goal,$final_assessment_progress_your_reach_goal,$final_assessment_progress_overall,$final_assessment_participat_name,
$final_assessment_participat_signature,$final_assessment_participat_date,$final_assessment_project_worker_name,$final_assessment_project_worker_signature,
$final_assessment_project_worker_date,$learning_opportunities,$contact_for_other_purposes,$empowering_communities,$empowering_communities_name,$empowering_communities_sign,$empowering_communities_date,
$participant_enrolled_onto,$participant_moved_another_provider,$participant_eligible_free_school,$british_passport,
$eec_passport,$euss_via_home,$preferred_evidence,$provide_preferred_evidence,$option_adoption_vertificate,$option_driving_licence,
$option_non_eu_passport,$option_biometric_immigration,$option_current_immigration,$option_marriage_civil_partnership,$option_other_evidence,$option_nine,
$details_evidence_provided,$dwp_job_centre_letter,$confirmation_relevant_organisation,$self_certification_evidence,$partcipant_told_support,
$participant_file_completed_remotly,$declaration_name_please_print,$declaration_job_title,$declaration_organisation,$declaration_signature_date,
$declaration_signature, $_POST['id']]);
if($result == true){
$details = "<b>All Data Updated</b>";
// Insert new record into the contacts table
$stmt = $pdo->prepare('INSERT IGNORE INTO client_activity (id,client_id,date,time,details,username) VALUES (?,?,?,?,?,?)');
$client_activity = $stmt->execute([ null,$_POST['id'],date("Y/m/d"),date("H:i:s"),$details,$_SESSION['name'] ]);
if($client_activity == true){
$msg = 'Updated Successfully!';
Form code
<input type="checkbox" name="learning_opportunities" value="learning_opportunities" <?php if($contact['learning_opportunities']=="Yes"){ echo 'checked'; } ?>> About courses or learning opportunities.<br>
I have read countless articles and tutorials and can't get it to update the data.
The assignment of the variable $learning_opportunities does not make any sense at all.
Only checked checkboxes are sent to the server.
The following snippet will just force the checkbox to be set back to true if the old value $contact['learning_opportunities'] was already true, making it impossible to uncheck the checkbox
$learning_opportunities = isset($_POST['learning_opportunities']) ? $_POST['learning_opportunities'] : $contact['learning_opportunities'];
If you want to be able to update that field you just need this assignment:
$learning_opportunities = isset($_POST['learning_opportunities']) ? 1 : 0;
After sending the form with the checkboxes keep in mind, that there are 2 scenarios possible:
if you checkbox was checked you will get "on" in $_POST['learning_opportunities'].
if your checkbox wasn't checked you will not get 'learning_opportunities' index in the $_POST array at all
Check this demo:
index.php
<?php
$contact['learning_opportunities'] = isset($_POST['learning_opportunities']) ? "yes" : "no";
?>
<form action="index.php" method="POST">
<input type="checkbox" name="learning_opportunities" <?= $contact['learning_opportunities'] === "yes" ? 'checked' : "" ?>>
About courses or learning opportunities.
<br>
<input type="submit" value="Submit">
</form>

POST checkbox name even if its not checked

Is it possible to POST checkbox name even if its not checked?
<input type='checkbox' class='tinyField' name='alert_by_email' value="1" <?PHP echo $alert_by_emailChecked ?> />
foreach ($_POST AS $field => $value)
$sql[] = $field." = '". $value."'";
$sql = implode(' , ',$sql);
$query = "UPDATE user_setup SET ".$sql." WHERE (userID = ".$userID.") " ;
$res = mysql_query($query);
So when I PRINT_R the POST i will get the field, but it will be empty
Array ( [alert_by_email] => '' )
Add this before your checkbox.
<input type='hidden' name='alert_by_email' value="" />
The straight forward answer is no.
The HTML form wont send the checkbox if it's not checked.
However, there are some workarounds:
use js to Generate a hidden input for each checkbox you have, set the value to 0 or '', and whenever you check them, remove the hidden input.
you could simply test if the key exist in the post like so:
if (isset($_POST['alert_by_email']))
In Short, No this is not possible if you are posting FORM without using any Javascript.
Also, Your code may be injected easily as you are relying on user provided column names without validating those. I am posting alternative way to do that. Hope that helps:
Suppose you have this HTML Form:
<form method="POST">
First name:<br />
<input type="text" name="firstname" />
<br />
Last name:<br />
<input type="text" name="lastname" /><br />
<input type="submit" />
</form>
Now, if you want to update values using PHP, your code should be:
<?php
$columnArray = array('firstname' => NULL, 'lastname' => NULL); // This is list of columns which can be updated using form input values (NULL is default value here)
$submittedValues = array_intersect_key($_POST, $columnArray);
// Above code will produce an array like `array('firstname' => 'anyname', 'lastname' => 'anylastname')
//--> Now you can generate your SQL using `$submittedValues`
$sql = array();
foreach ($submittedValues as $field => $value)
{
$sql[] = $field." = '". $value."'";
}
$sqlString = implode(' , ',$sql);
Using this way, hacker will not be able to add extra columns which shouldn't be updated by user i.e. last_login_date or something.

PHP foreach Construct Confusion

I am having a hard time wrapping my head around the foreach construct. I have found numerous examples of course, but I never seem to be able to adapt them to my needs.
Please consider this working example I have:
I am collecting two dates in an HTML form:
<form method="post">
<legend>Minutes and Records</legend>
<label for="FirstAGMDate">First AGM Date (only if known)</label>
<input type="text" name="FirstAGMDate" value="2014-01-01" />
<label for="MinutesInspectedFromDate">Minutes Inspected From Date</label>
<input type="text" name="MinutesInspectedFromDate" value="2014-01-02" />
<input type="submit" name="submit" />
</form>
On submit the values are being pushed to the mysql database with a PDO prepared statement:
if (isset($_POST['submit'])) {
$sql = "UPDATE jobsinglevalues SET Date = :FirstAGMDate WHERE FormId = 0;
UPDATE jobsinglevalues SET Date = :MinutesInspectedFromDate WHERE FormId = 1;";
$sth = $db->prepare($sql);
$sth->execute(array(':FirstAGMDate'=>($_POST['FirstAGMDate']), ':MinutesInspectedFromDate'=>($_POST['MinutesInspectedFromDate'])));
}
This works no problem, but it's not very clever when I need to repeat this for a dozen inputs. What I want to do is achieve this with only one line of sql; looping for each <input type="text" name="Value" />.
How can I place this into a foreach loop?
In my head it works like this:
On submit each input updates the value in the database based on FormId, which increments by 1 each loop starting at 0. FormId is not a primary key, it simply mirrors the order in which the form elements are displayed.
Update - working example
if (isset($_POST['submit'])) {
$FormId = 0;
foreach($_POST['Value'] as $avalue){
$sql = "UPDATE jobsinglevalues SET Date = :Value WHERE FormId = :FormId";
$sth = $db->prepare($sql);
$sth->execute(array(':Value'=>($avalue), ':FormId'=>($FormId)));
++$FormId;
}
}
This seems to logically work to me! Is the correct solution similar? Please let me know if I need to clarify anything.
Thankyou,
Sam
Let's start by making sure all our values are in an array after posted; if you don't care about the keys you can just use name="Values[]", but I'll use name="Value[FirstAGMDate]" etc so we know what key a value belongs to.
<form method="post">
<legend>Minutes and Records</legend>
<label for="FirstAGMDate">First AGM Date (only if known)</label>
<input type="text" id="FirstAGMDate" name="Value[FirstAGMDate]" value="2014-01-01" />
<label for="MinutesInspectedFromDate">Minutes Inspected From Date</label>
<input type="text" id="MinutesInspectedFromDate" name="Value[MinutesInspectedFromDate]" value="2014-01-02" />
<input type="submit" name="submit" />
</form>
Now we can process the posted array of values. If we want to do something with the key, we can use foreach($_POST['Value'] as $akey => $avalue), if we are only interested in the values then foreach($_POST['Value'] as $avalue) suffices.
$sql = "UPDATE jobsinglevalues SET Date = :Value WHERE FormId = :FormId;";
$sth = $db->prepare($sql);
foreach($_POST['Value'] as $akey => $avalue) {
$sth->execute(array(':Value' => $avalue, ':FormId'=> $FormId ));
++$FormId;
}
[edit] As per edit-suggestion by #AravindKishore, creating the prepared statement is better done before the loop. Prepare once, enjoy forever.

Create update query for dynamic database

I am trying to update a row in a mysql database. To do this, I would use a simple query like this:
"UPDATE `contactinfo` SET `Company` = 'Google', WHERE `id` = '1';"
The problem is that the database is dynamic and users can add columns at any time. So I do not know the names of the columns. To find the names and create a form to post to the page that will actually do the mysql work uses this code:
<?php
$result = mysql_query("select * from contactinfo WHERE `id` = '".$rid."';");
if (!$result) {
die('Query failed: ' . mysql_error());
}
$i = 0;
while ($i < mysql_num_fields($result)) {
$meta = mysql_fetch_field($result, $i);
if (!$meta) {
echo "ERROR";
}
$name = $meta->name;
$r = mysql_fetch_array(mysql_query("select * from contactinfo WHERE `id` = '".$rid."';"));
$content = $r[$name];
if($name != 'id') {
echo "<tr><td align='center'><div align='left'>Edit ".$name."</div></td></tr>";
echo "<tr><td align='center'><input type='text' value='" . $content . "' /></td></tr>";
}
$i++;
}
mysql_free_result($result);
?>
This creates a nice little table with input boxes that allow the user to edit the content of the row that has been selected. The row id number($rid) is used to identify which row needs to be changed.
My question is, how can I get the new content for the row from the posted form and create a query to update it? I can't seem to figure out how to dynamically get the names of the form as well as the new content to the write the query.
If any clarification is needed just let me know and all help is appreciated.
Thanks.
The easiest way is to name the fields in the form exactly how the name of the fields in the database are.
Lets say you have this form
<form action="">
<input name="field[firstname]">
<input name="field[lastname]">
<input name="field[address]">
</form>
You should probably be able to create the form based on the fields names too, you are probably already doing this.
In the file that processes the response you can do something like this:
foreach($_POST['field'] as $field_name => $field_value) {
$sql_str[] = "{$field_name} = '{$field_value}'";
}
This just goes through the 'field' array that comes from post and puts the proper update text into another array.
Then just do a
mysql_query("UPDATE contactinfo SET ".implode(',', $sql_str)." WHERE `id` = '".$rid."';")
To put it into the database.
What you can do is add a column in the database with a bit flag and if the user is new or old, the flag will reflect it.
that way you can update the user to say if it is new or old.
hope this helps.
You might do well to investigate whether there is an ORM framework that you could use.
Anyway, the simplest way to do what you want is to pass the name of the field in the INPUT field.
$content = AddSlashes($content); // You may need HTMLEntities() here
$field = <<<FIELD
<input type="text" value="$content" />
FIELD;
Also, another useful trick to employ is to either supply an array of "protected" fields, or specify a prefix that makes the field unchangeable. For example, you almost certainly do not want a user to be able to change the primary keys.
So you could generate the form with
if ('id' == $meta->name or 'pk' == $meta->name or (0 === strpos($meta->name, 'pk_')))
{
// This is a primary key field
$html .= <<<PKFIELD
<input type="hidden" name="{$meta->name}" value="{$contents}" />
PKFIELD;
continue;
}
if (0 === strpos($meta->name, 'hf_'))
{
// hidden field, ignored (can't be changed)
continue;
}
if (0 === strpos($meta->name, 'ro_'))
{
// read-only field, shown but without even the name
$html .= <<<ROFIELD
<input type="text" readonly="readonly" class="readonly" value="{$contents}" />
ROFIELD;
continue;
}
Or you could use a fixed-size prefix and an array of templates:
$fieldtpls = array(
'pk_' => '<input type="hidden" name="{NAME}" value="{VALUE}" />',
'ta_' => '<textarea name="{NAME}">{VALUE}</textarea>',
'ro_' => '<input type="text" value="{VALUE}" readonly="readonly" />',
);
then you analyze each field and apply a default unless a known prefix is used.
Your users would then have to name the fields accordingly. Another possibility is to allow for a "meta-table" to hold the type and handling of each table and field, but in that case you would need to complicate a bit the user interface by creating a sort of "admin editor" for the Meta table:
table field type rw parameters
users name text yes
users id hidden no
users role text no
users notes area yes class:"widearea"
...and that way be dragons ORM frameworks.

Multiple Checkbox Update Query

I have an application with multiple values from a database table that I generate alongside individual checkboxes. The checkboxes are given a value associated from the database of course.
Now what I am wanting to do is on submit update the database given the values checked or unchecked. This would be simple if I had hardcoded the values in HTML, but since the values are database driven I am not sure how I would go about doing this.
Quite simply: I want to update database given checkbox values are checked or not.
The title of your question says "radio" buttons, but your question asks about "checkboxes". They are very different things. Here's an example.
<input type="radio" name="fish" value="one"> One Fish
<input type="radio" name="fish" value="two"> Two Fish
<input type="radio" name="fish" value="red"> Red Fish
<input type="radio" name="fish" value="blue"> Blue Fish
The above is an example of a radio button input array. It contains one field name ("fish") and four possible values ("one", "two", "red", "blue").
Since it's a radio button, only one of those choices can be valid at any given time. That means that you either get "one" OR "two" OR "red" OR "blue", but it's not possible to select both "one" and "red" at the same time, unless the field names are different ("number", "color", for example).
Checkboxes are binary, like a light switch. They are either on or off. Each checkbox represents its own field name.
<input type="checkbox" name="light"> On
<input type="checkbox" name="status"> Single?
<input type="checkbox" name="featured"> Featured
You may check as many of these as you wish, given that each has its own individual field name that can either be true or false (on or off).
Since I don't know which one you're talking about, I'll give quick examples with each.
First, the radio example:
<? $types = array("one","two","three","four"); ?>
<? foreach ($types as $type): ?>
<input type="radio" name="fish" value="<?= $type ?>"/> <?= ucwords($type) ?> Fish
<? endforeach ?>
When the form is submitted, you will wind up with a response similar to this:
Array
(
[fish] => "one"
)
Assuming "one" was selected in the radio button array.
Now, the checkbox example:
<? $fields = array("light", "status", "featured"); ?>
<? foreach ($fields as $field): ?>
<input type="checkbox" name="<?= $field ?>"/> <?= ucwords($field) ?>
<? endforeach ?>
This provides the same HTML input as my HTML-based example above. If you check a field and submit the form, the result would look like this:
Array
(
[light] => "on"
[status] =>
[featured] => "on"
)
Where "on" is if the checkbox is checked and blank (or possibly "off") if the checkbox was not checked.
Depending on which one, you will need to insert these values into the database by taking these responses and parsing them, then creating a SQL query.
With the radio button, the variable would be simple:
$fish = $_POST['fish'];
$sql = 'INSERT INTO fishes (fish) VALUES ('.mysql_real_escape_string($fish).')';
mysql_query($sql);
With the checkbox, it would be a little more difficult:
$light = $_POST['light'] == 'on' ? 1 : 0;
$status = $_POST['status'] == 'on' ? 1 : 0;
$featured = $_POST['status'] == 'on' ? 1 : 0;
$sql = "INSERT INTO checkboxes (light, status, featured) VALUES ($light, $status, $featured)";
mysql_query($sql);
As you mentioned, your question was rather vague. I hope my answer provides enough information to get you started in the direction you need to go. This is a super basic example, of course, and you would likely want to generate the SQL statements dynamically so that you don't have to hard code every field or apply this to a more generic function to handle multiple types of forms.
Anyway, good luck. Hope this helps.
For those who are wondering how I accomplished this, here is my code:
$publish = $_POST['publish'];
while (list ($key,$val) = #each ($publish))
{
$temp=mysql_query("SELECT * FROM temp WHERE id = '$val'");
while($row = mysql_fetch_array($temp))
{
$id = $row['id'];
$title = $row['title'];
$maintext = $row['maintext'];
$order = $row['order'];
$pageID = $row['pageID'];
$sql = "INSERT INTO content (id, title, maintext, order, pageID) VALUES ({$row['id']}, {$row['title']}, {$row['maintext']}, {$row['order']}, {$row['pageID']})";
$sql2 = "UPDATE content SET `title` = '$title', `maintext` = '$maintext', `order` = '$order', `pageID` = '$pageID' WHERE `id` = '$id'";
$sql3 = "DELETE FROM temp WHERE id = '$id'";
mysql_query($sql);
mysql_query($sql2);
mysql_query($sql3);
}
}
?>

Categories