vsapountzis
vsapountzis

Reputation: 618

Foreach is picking the first checkbox only if checked

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 when sending bulkcopy form. 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 //bulkcopy.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.

Upvotes: 8

Views: 4095

Answers (8)

George Pant
George Pant

Reputation: 2117

In your last generated html the inputs you want to submit are not inside bulkcopy form. As others pointed out you should change your html markup.One fast way to make this work without altering your markup is to use javascript.Just add this to the bottom of your html.It will take the inputs you want to be submitted and append them to the bulkcopy form.

    <script>
    $(document).ready(function(){
     $('form[name="bulkcopy"]').submit(function( event ) {
     $('input[name="id[]"]').clone().hide().appendTo($(this) );
   });
   });
    </script>

Also 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");
}

?>

Upvotes: 0

yergo
yergo

Reputation: 4970

You made you a problem by yourself.

What i understand, you have troubles sending multiple checkboxes of column "Entry name" with button of "bulk copy".

It is how it should work. It's because you are closing your form in "display order" column, what essentially makes it cointain only first checkbox in it. If you want to post all checked checkboxes to "bulkcopy" script, you will have to either declare it as separate form for all checkboxes, or use JS, eg. with your included jQuery:

// how to collect checked ids of checkboxes.
var ids = [];
var boxes = $('input[name="id[]"]');
for(var i in boxes) {
  if(boxes[i].checked) {
    ids.push(boxes[i]);
  }
}

to hook something like above with eg. on('click') of your sumbit button. Here on SO there are pletny of examples how to prepare and send form using JS.

Edit:

there is even easier way. You have to add id to your form:

<form class="form-inline" name="bulkcopy" id="bulkcopy" method="post" action="bulkcopy.php?from=sights">

and than set your checkboxes to be owned by it:

<input type="checkbox" name="id[]" value="1"  form="bulkcopy">
<input type="checkbox" name="id[]" value="46"  form="bulkcopy">

that should easily fix your issue.

Dont forget to remove excess form closing tags:

// -----------------------------------------------------------v
<input type="checkbox" name="id[]" value="1" form="bulkcopy"></form>

they may easily corrupt your solution later. Just close immediately after your submit button:

    <input class="btn btn-primary" type="submit" name="submit" value="Go"><br /><br />
</form>

Upvotes: 0

  <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>

Upvotes: 0

luca3003
luca3003

Reputation: 109

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

Upvotes: 0

mister martin
mister martin

Reputation: 6252

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...
}

Upvotes: 1

Arleigh Hix
Arleigh Hix

Reputation: 10877

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>

Upvotes: 2

Alfie
Alfie

Reputation: 2350

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
  //...
}

Upvotes: 0

Fahmi B.
Fahmi B.

Reputation: 798

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");
}

Upvotes: 0

Related Questions