Wednesday, May 4, 2016

Foreach is picking the first checkbox only if checked

Leave a Comment

I am working on the following code in order to pick checkboxes from a form. If i check the first checkbox everything works great. If i check another checkbox i get the "Undefined index" error. Keep in mind that i am getting the checkboxes with post method and the submit button is above the checkboxes due to the complexity of the location of the form and the fields. What i need essentially is to pick multiple checkboxes and add certain values to the database.

<?php    session_start();   if($_SESSION['admin_logged_in'] != true){     header("Location:login.html");     exit();   }   include 'db.php';    $from = mysql_real_escape_string($_GET['from']);   $room = mysql_real_escape_string($_POST['room']);    if(!empty($_POST['id'])) {     foreach($_POST['id'] as $check) {       $id = $check;        $sel = mysql_query("select * from $from where id = '$id' limit 1 ") or die(mysql_error());        while($row = mysql_fetch_array($sel)){         $preview = $row['preview'];         $text = $row['text'];         $title = $row['title'];         $images = $row['images'];       }        $ins = mysql_query("insert into $room (id, preview, text, title, images) values (' ', '$preview', '$text', '$title', '$images') ") or die(mysql_error());      }      header("Location:admin.php");   }  ?> 

The code of the form can be found below:

<form class="form-inline" name="bulkcopy" method="post" action="bulkcopy.php?from=sights"> <b>Bulk Copy:</b>      <select name='room' class="form-control">         <option>Select...</option>         <option value="Orhan">Orhan</option>         <option value="Deniz">Deniz</option>         <option value="Irini">Irini</option>         <option value="Katina">Katina</option>         <option value="Gulbin">Gulbin</option>         <option value="Mihalis">Mihalis</option>     </select>     <input class="btn btn-primary" type="submit" name="submit" value="Go"><br /><br /> </div> <table class="table table-bordered table-striped">     <th>Entry Name</th>     <th>Display Order</th>     <th>Copy to...</th>     <th>Status</th>     <th>Image</th>     <th>Edit</th>     <th>Delete</th>     <th>Duplicate</th>      <?php while($row = mysql_fetch_array($sel)) { ?>     <tr>         <td>             <input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>">             </form>             <?php echo $row['title']; ?>         </td>         <td>             <form name="order" method="post" action="sightorder.php?id=<?php echo htmlspecialchars($row['id']); ?>">                 <div class="col-md-4">                     <input class="form-control" type="number" name="order" value="<?php echo htmlspecialchars($row['ordernum']); ?>">                 </div>                 <div class="col-sm-3">                     <input type="submit" name="submit" value="Set Order" class="btn btn-primary">                 </div>             </form>         </td>         <td>              <form name="copyto" method="post" action="copyto.php?from=sights&id=<?php echo htmlspecialchars($row['id']); ?>">                 <input type="checkbox" name="room[]" value="Orhan"> O -                 <input type="checkbox" name="room[]" value="Deniz"> D -                 <input type="checkbox" name="room[]" value="Irini"> I -                 <input type="checkbox" name="room[]" value="Katina"> K -                 <input type="checkbox" name="room[]" value="Gulbin"> G -                 <input type="checkbox" name="room[]" value="Mihalis"> M                  <input type="submit" name="submit" value="Copy" class="btn btn-primary">             </form>          </td>         <td>             <a href="sightstatus.php?id=<?php echo htmlspecialchars($row['id']); ?>&status=<?php echo $row['status']; ?>"><?php if($row['status'] == 1){ ?><i class="fa fa-check fa-lg"></i><?php }else{ ?><i class="fa fa-times fa-lg"></i><?php } ?></a>         </td>         <td>             <a href="sightimages.php?id=<?php echo $row['id']; ?>"><i class="fa fa-image fa-lg"></i></a>         </td>         <td>             <a href="editsight.php?id=<?php echo htmlspecialchars($row['id']); ?>"><i class="fa fa-edit fa-lg"></i></a>         </td>         <td>             <a onclick="return confirmDelete()" href="delsight.php?id=<?php echo htmlspecialchars($row['id']); ?>"><i class="fa fa-trash fa-lg"></i></a>         </td>         <td>             <a href="duplicatesight.php?id=<?php echo htmlspecialchars($row['id']); ?>"><i class="fa fa-copy fa-lg"></i></a>         </td>     </tr>     <?php } ?> </table> 

Any help would be greatly appreciated. Thanks.

8 Answers

Answers 1

You have a problem here

<?php     while($row = mysql_fetch_array($sel)){ ?>         <tr><td><input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>"> <?php echo $row['title']; ?></td></form> 

There is no closing bracket for the while loop, and the form is closed after the first checkbox is added. So if that checkbox is not checked, then the input is not posted, thus the undefined index. Make sure you do not close the form until after all the rows have been added, like this

<?php     while($row = mysql_fetch_array($sel)){ ?>         <tr><td><input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>"> <?php echo $row['title']; ?></td></tr> <?php } ?>   </table> </form> 

Answers 2

After reviewing the raw HTML of the complete page you provided, it is clear that the problem is you're trying to nest multiple forms which is invalid HTML. Please refer to this answer for more information. This answer does link to a workaround, but it's an ugly hack and should probably be avoided.

I believe the appropriate, valid HTML solution in your case is to use a single form. Currently you have multiple nested forms submitting to the following locations:

  1. bulkcopy.php?from=sights
  2. sightorder.php?id=1
  3. copyto.php?from=sights&id=1
  4. copyto.php?from=sights&id=46
  5. etc...

What you can do is have a single form that determines which action to take based on which submit button was clicked. For example:

switch ($_POST['submit']) {     case 'Go':         // process bulkcopy         break;      case 'Set Order':         // process siteorder         break;      // etc... } 

Answers 3

if you the variable checkbox is a table $_POST['id'] the when you do this

foreach($_POST['id'] as $check) {   $id = $check;   ... } 

if you don't check the first input the first variable

$check = $_POST['id']['0'];  // is empty 

you can do another condition in the foreach

if(!empty($_POST['id'])) {   foreach($_POST['id'] as $k=>$v) {      if(!empty($v)){              $id = $v;         $sel = mysql_query("select * from $from where id = '$id' limit 1 ") or die(mysql_error());         while($row = mysql_fetch_array($sel)){            $preview = $row['preview'];            $text = $row['text'];            $title = $row['title'];            $images = $row['images'];        }         $ins = mysql_query("insert into $room (id, preview, text, title, images) values (' ', '$preview', '$text', '$title', '$images') ") or die(mysql_error());        }   }  header("Location:admin.php"); } 

Answers 4

You should use mysql_num_rows() to check if u actually have result before trying to access them and use them for insertion to database.The problem with your code is that the variables inside

 while($row = mysql_fetch_array($sel)){    ....    } 

are never defined in case the result set is empty.But although they are never defined you try to use them in an insert query later.So just check if you have results first:

 <?php session_start();  if($_SESSION['admin_logged_in'] != true){   header("Location:login.html");   exit(); }  include 'db.php';  $from = mysql_real_escape_string($_GET['from']); $room = mysql_real_escape_string($_POST['room']);  if(isset($_POST['id'])&&!empty($_POST['id'])) { foreach($_POST['id'] as $check) {   if(empty($check)) continue;   $id = $check;    $sel = mysql_query("select * from $from where id = '$id' limit 1 ") or die(mysql_error());  if(mysql_num_rows($sel)>0){   while($row = mysql_fetch_array($sel)){     $preview = $row['preview'];     $text = $row['text'];     $title = $row['title'];     $images = $row['images'];  }    $ins = mysql_query("insert into $room (id, preview, text, title, images) values (' ', '$preview', '$text', '$title', '$images') ") or die(mysql_error());   }  }  header("Location:admin.php"); }  ?> 

EDIT:

Also it seems there is a problem with your generated html code.You dont seem to close properly your tags.Try this:

         <?php          while($row = mysql_fetch_array($sel)){ ?>         <tr><td><input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>"> <?php echo $row['title']; ?></td></tr><?php }?></table></form> 

But since i do know the value of $sel I cannot help you more if you do not post your generated html.

Answers 5

Your form does not POST an input with the name 'room'. Therefore, when you try and check it with this line $room = mysql_real_escape_string($_POST['room']);, there is no item in the $_POST array with the index 'room', hence the undefined index error.

To debug this kind of thing, it's helpful to analyse the request/response headers of your form submission. If you use Chrome, press Ctrl+Shift+I to bring up the developer console, select the Network tab, and when you submit your form, view the details of the entry that pops up. You will be able to see here the names and values of the things being sent and will give you an idea of where things are going wrong. Other browsers are available, and each have their own respectable versions of this.

Also, before accessing any variables you didn't define yourself, or can't rely on (such as form submissions), you should use isset() to make sure the variable exists before using it - that will stop the error you are getting and also allow you to catch where it's going wrong more easily:

if (!isset($_POST['room'])) {   print('Please select something'); } else {   $room = $_POST['room']; // technically not needed tho :p   //... } 

Answers 6

which is tha page you are callling, sightorder.php or copyto.php? by which submit button, set order or copy?

in both cases you are sending the id by GET not by POST.

which is the line which produces the error?

Luca

Answers 7

  <form bulkcopy>   ....    <table>   <?php while: ?>       // </form> it must be deleted       ...       <div sightorder>          ...          <input submit onclick="return send_sightorder(this);">       </div>        ...       <div copyto action="copyto.php?from=sights&id=<?php echo htmlspecialchars($row['id']); ?>">           ...           <input submit onclick="return send_copy(this);">       </div>    <?php end while ?>   </table>   </form> // bulkcopy's close tag    <script>      /// Function send_sightorder is same.      function send_copy(clicked_element) {          var form = clicked_element.parent;          var inputs = form.getElementsByTagName("input");          var data = inputs[0].name + "=" + inputs[0],checked + "&";          var URL = window.location.host + form.getAttribute("action");                for (i=1; i<inputs.length-1; ++i) {              data = "&" + inputs[i].name + "=" + inputs[i].checked + "&";          }           xmlhttp = new XMLHttpRequest();          xmlhttp.onreadystatechange = function() {             if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {                // redirect to new page or something else ...                window.location = URL;             }          }          xmlhttp.open("POST", URL,true);          xmlhttp.send(data);           return false;      }   </script> 

Answers 8

the trick is to give your checkboxes fixed names with the value of the IDs

<input type="checkbox" name="id[<?php echo $row['id']; ?>]" value="1"> 

in your php code do like:

if (is_array($_POST['id'])) {      foreach ($_POST['id'] as $id => $val) {          // should always be 1 as most browsers don't send unchecked checkboxes...         // better to check it. also check for "on" because some browsers always send it as value for checked checkboxes         if (1 == $val || 'on' == $val) {               echo "Checkbox with ID ". $id . " was checked";         }     } } 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment