20

I am trying to submit multiple arrays with a checkbox form but I am only able to submit one array at the moment, here is what I have so far

In this example I am submitting an array of numbers with the delete[] array, this array gets processed properly, I also want to submit the array condition[] this does not get processed properly, what is the best way to solve this issue?

php code

$catalog = $database->getInventory();

if($catalog){   
   $numRows = sizeof($catalog);//count
   echo "<b>Book Count:</b> ".$numRows."<br>";

   echo "<form method='post' action='inventory.php'>";
   echo "<table id='example' class='tablesorter' border='0' cellpadding='0' cellspacing='1'>";
   echo "
      <thead>
         <tr>
           <th>ISBN</th>        
           <th>Title&nbsp;&nbsp;&nbsp;</th>
           <th>Rank&nbsp;&nbsp;</th>
           <th>Condition&nbsp;&nbsp;</th>   
           <th><input type='checkbox' name='delete' value='all' /></th>
         </tr>
      </thead>\n";


   foreach($catalog as $elem){
      echo "
         <tr>
            <td>".$elem["isbn"]."</td>
            <td>".$elem["title"]."</td>
            <td>".$elem["rank"]."</td>
            <td>".$elem["condition"]."</td>
            <td> 
               <input type='checkbox' name='add[]' 
                  value='".$elem['isbn']."_".$elem['condition']."_"."' />
            </td>
         </tr>";    
   }

   echo "</table>";
   echo "</form>";
}

example html markup

<form method='post' action='inventory.php'>
   <table>
      <tr>
         <td>
            <input type='hidden' name='addInventoryBook' value='1'>
            <input type='submit' value='Add' />
         </td>
      </tr>

      <tr>
         <td>
            <input type='checkbox' name='add[]' value='100001_used' />
         </td>
      </tr>

      <tr>
         <td>
            <input type='checkbox' name='add[]' value='100001_new' />
         </td>
      </tr>

      <tr>
         <td>
            <input type='checkbox' name='add[]' value='100003_new' />
         </td>
      </tr>

   </table>
</form>

php function

function Inventory(){   
   if(isset($_POST['addInventoryBook'])){
      if(isset($_POST['add']) && is_array($_POST['add'])){
     $arr = array();
         foreach($_POST['add'] as $checkbox){
            $temp = explode("_", $checkbox);

            $arr[] = array(
               "isbn"       => $temp[0],
               "condition"      => $temp[1],
               "sub_condition"  => $temp[2]
            );
         }              
     $this->addInventoryBook($arr); 
      }

      else{
         echo "No values have been set";
      }
 }


function addInventoryBook($arr){
   foreach($arr as $elem){
      //if used get sub-category
      if($elem['condition']=='used'){
         echo $elem['isbn']."-".ucfirst($elem['condition'])
            .ucfirst($elem['sub_condition'])."<br>";
      }

      else if($elem['condition']=='new'){
         echo $elem['isbn']."-".ucfirst($elem['condition'])."<br>";
      }

   }
}

All I want is to basically be able to pass two arrays to my php script

current output

100001
100002
100003

desired output

100001   good
100002   new
100003   new
mk_89
  • 2,692
  • 7
  • 44
  • 62
  • I'm confused what you're asking. I don't see `$_POST['condition']` anywhere in your code, so I'm not sure what you're asking about. – David Aug 05 '12 at 22:34
  • 1
    I'm not sure [] trick applies to hidden fields either.. – favoretti Aug 05 '12 at 22:35
  • @David im trying to get the ['condition'] to work e.g. `foreach($_POST['condition'] as $checkbox) echo $checkbox."
    ";` but that does not work
    – mk_89 Aug 05 '12 at 22:36
  • 1
    You need to explain your question with more detail, and reword it, as it can be very confusing to read and fully understand what you want... – DMor Aug 05 '12 at 22:36
  • @favoretti do you know a way which works – mk_89 Aug 05 '12 at 22:36

3 Answers3

38

The problem that you are having, I suspect, is that only the checkboxes that are checked will be passed back to the server, whereas all the hidden fields will always be passed so the lengths of the arrays will differ and the keys wont correspond.

The solution to this is actually relatively simple - you just need to specify the keys for the condition array so you can match the values up again. Something like this:

HTML:

  <tr>
     <td>
        <input type='hidden' name='condition[100001]' value='good' />
        <input type='checkbox' name='delete[]' value='100001' />
     </td>
  </tr>

  <tr>
     <td>
        <input type='hidden' name='condition[100002]' value='new' />
        <input type='checkbox' name='delete[]' value='100002' />
     </td>
  </tr>

PHP:

foreach ($_POST['delete'] as $delete) {
  $condition = $_POST['condition'][$delete];
  // Do stuff
}

This ties the values in the $_POST['condition'] array back up with the $_POST['delete'] array so everything will match up again.

EDIT

The way the keys are being created above is not great and in retrospect it is the wrong way to do it.

To demonstrate the right way to do it, let's imagine we have the following array, nice and simple:

$books = array(
  10001 => 'good',
  10002 => 'new',
  10003 => 'new',
  10004 => 'good'
);

What we need to do is tie up the two inputs that are associated with each book, which means we need a set of key/value pairs that can be matched up. That sounds like an array to me. But unlike the example above, the keys should be irrelevant to the data - they don't need to mean anything, because all we want is the data.

What we need to do is specify every single key explicitly (no stack-style array pushes) and make the keys agnostic of the data they relate to.

We can do this:

$i = 0;
foreach ($books as $isbn => $condition) {
  echo "
    <tr>
      <td>
        <input type='hidden' name='condition[$i]' value='$condition' />
        <input type='checkbox' name='delete[$i]' value='$isbn' />
      </td>
    </tr>
  ";
  $i++;
}

...and then, when the form is submitted, we can do this:

// We still base our code on $_POST['delete'] - because this is the array that
// depends on the user input. This time, though, we'll look at the keys as well
foreach ($_POST['delete'] as $key => $isbn) {
  $condition = $_POST['condition'][$key];
  // Do stuff
}
DaveRandom
  • 87,921
  • 11
  • 154
  • 174
  • this looks interesting, i'll give it a shot – mk_89 Aug 05 '12 at 22:47
  • I have run into a problem with your solution, what do I do if there are 2 books with the same ISBN but different conditions, I've been getting a few inconsistent results. – mk_89 Aug 06 '12 at 21:38
  • 1
    @mk_89 D'you know, I woke up this morning and regretted recommending you do it this way. You need to separate the key and value logic, this sort of combines them into one and it's not a great way to do it. What you should do is maintain a counter in the loop while generating the HTML and use *that* as the keys. If you edit the question with your current PHP code that generates the HTML I'll provide sample code. – DaveRandom Aug 06 '12 at 21:45
  • ok I've actually used a different method, but the method im using feels like a duck tape solution, I'll change the question and example – mk_89 Aug 06 '12 at 21:49
  • 1
    @mk_89 The basic principle of what I did here is sound, it's just one of the finer points that needs adjustment. See edit above. – DaveRandom Aug 06 '12 at 22:00
  • I understand what you saying, the pointer can be a random key, such as 0,1,2,3 – mk_89 Aug 06 '12 at 22:04
  • @mk_89 The array syntax in HTML is identical to PHP - the *only* difference is that string keys are not quoted (so in HTML you do `array[key]` instead of `array['key']`). When you do `array[]` with no key identifier, it's identical to `$array[] = 'value'` in PHP where you just push an item onto the stack. I seem to remember reading that it was a bad idea to create arrays on an HTML form that were more than 3 dimensional (so `array[l1][l2][l3]` is the depth limit). Also be aware this is not "standard" behaviour but it *is* reliable in PHP. – DaveRandom Aug 06 '12 at 22:08
  • OK do you think I should stick with my current solution where I send all information as a string and use explode() to break up the string or go with this new amendment ` ` – mk_89 Aug 06 '12 at 22:10
  • @mk_89 If there is any danger of repetition then yes, you need an explicit counter. If you are pulling data from a database table, using the primary key of that database table for the keys is always good because it allows you to easily located the record in the database while looping the data. – DaveRandom Aug 06 '12 at 22:16
  • This is a great solution! I used your edited answer in order to send a lot of hidden values along with one checkbox. – Paintoshi Nov 02 '16 at 14:19
4

I'm a little confused about what you are asking, but I think I can simplify this for you. I don't know how you are generating the values for the hidden fields, are they hard coded? Regardless, this system would work much better if it were simplified.

Try this out....

This will combine the info for the numbers and condition, then it will split them on the backend for handling. This way the information is passed at the same time.

<tr>
         <td>
            <input type='checkbox' name='delete[]' value='100001-good' />
         </td>
      </tr>

      <tr>
         <td>
            <input type='checkbox' name='delete[]' value='100002-new' />
         </td>
      </tr>

      <tr>
         <td>
            <input type='checkbox' name='delete[]' value='100003-new' />
         </td>
      </tr>

    <?php


       if(isset($_POST['deleteInventoryBook'])){
          if(isset($_POST['delete']) && is_array($_POST['delete'])){
             foreach($_POST['delete'] as $checkbox){
               $checkbox = explode('-', $checkbox);
               echo $checkbox[1];
               echo '<br />';
               echo $checkbox[0];
               echo '<br />';
             }
          }else{
             echo "No values have been set";
          }
       }


    ?>

Again, I don't know if this is helpful or not because I was a little misunderstood about what exactly you were trying to achieve, but I hope it was helpful.

Tabetha Moe
  • 116
  • 1
  • 6
1

You're going to have to find a creative way to pass multiple hidden fields as an array to the PHP handler, or change how that data is collected. A "serialized" array seems to be the best bet.

This StackOverflow answer really outlines what you can do, and should still match your script's behavior. Good luck!

Community
  • 1
  • 1
David
  • 3,831
  • 2
  • 28
  • 38