MORE Php help for the array-challenged

Previous chapter here

OK here’s the scenario: previous php page was showing a list of items like so:

ItemName… Image of Item

where the is a checkbox input type of the Item ID.

Next page receives the array of Item IDs and does a for each {} and assembles a delimited list of ItemIDs as a single string. (Never mind why; just assume that’s the end goal for now).


 $ccount = 0;
    $ResList = '';
 for ($i = 0; $i< $ccount; $i++) { 
 
$ResList = $ResList . '::' . $ItemID[$i];
}
$ResList = $ResList . '::';

Works fine, and all is well with the world.

Well, now it would be useful to have a separate value per each line item for QUANTITY.

OK, I thinks to myself, easy enough, input type is text, value is 1 by default. Then on the next page I wrap my for each {} thingie in an IF that says If $ItemID[$i] > 0, so that it only deals with the ItemID and the Quantity for that line item if there is indeed a check in the checkbox for ItemID, thus ignoring all those default Quantity=1 values for the items NOT checked, right?


 $ccount = 0;
    $ResList = '';
    $QtyList = '';
 for ($i = 0; $i< $ccount; $i++) { 
 
 If ($ItemID[$i] > 0) {
$ResList = $ResList . '::' . $ItemID[$i];
$QtyList = $QtyList . '::' . $qquantity[$i];
}
}
$ResList = $ResList . '::';
$QtyList = $QtyList . '::';

WRONG. When ItemIDs 1, 2, and 4 were checked off (skipping item 3) and quantities input were 2, 1, 1, and 5 for ItemIDS 1, 2, 3, and 4, I first ended up my two result strings looking like this:

$ResList: ::1::2::4::
$QtyList: ::2::1::1::

I tried removing the default value 1 from item 3 and ran it and got this:

$ResList: ::1::2::4::
$QtyList: ::2::1::::

I don’t suppose there’s any standard HTML for “If not empty, <input type=text name=qquantity” perchance?

I’ve thought about ditching the checkbox fields altogether, setting input type to hidden, but then everything gets ordered. Or if I removed default value for quantity and used If to only append quantities when quantity > 0, it seems like that would work EXCEPT that that’s the same logic that’s not working right above for only accepting quantities when ItemID isn’t empty ?!??

I’ve tried concatenating the values of $ItemID[$i] and $qquantity[$i] with a second delimiter and assembling a single string but ended up with a single-string version of the same problem (when it skips over the empty value for ItemID it doesn’t also skip over the quantity so they’re still misaligned).

The problem is that the http request only contains those items that are explicitly checked while text boxes will send to the server anything that has a value in it. What I would do is have some javascript code triggered when you click submit that will go through your reslist and set the corresponding quantity to blank before submitting your form.

Althernatively (after reviewing your code), is to use the reslist value as the index to qtylist. So instead of $qquantity($i), you could use $qquantity($ItemID[$i])

This looks intriguing. I’ll try it and get back to you!

Can’t make that work.

And even when the quantity field is DEAD EMPTY it is still generates a ‘line’ in the php array, unlike the checkbox-formatted ItemID which only adds a ‘line’ for each CHECKED item. Here’s what it shows when I tell it to echo it all on the destination screen (using a “for each” echo statement):

Item ordered: 5
Item ordered: 7
Item ordered: 8
order quantity: 2
order quantity: 1
order quantity:
order quantity: 5

I’m using a very klunky routine that essentially “slides up” the order quantity and assumes that the item ordered that a given quantity goes with must be the previous one, ordinally, if the previous position of the order quantity within the order-quantity queue was blank.

The reason the qty field always generates a line is that the name/value pairs for text boxes are always returned to the server whereas checkboxes (and radio buttons if nothing is selected) are only returned when the user actually checks the box.

I assumed the item id was an index (bad assumption on my part). Let’s try something else. When I’ve had to solve this in the past, what I did was the following:

  1. Create a hidden array equal to the number of items displayed (let’s say 10 items) in your form somewhere.
  2. Add an “onchange(x)” javascript call to each quantity textbox tag where x=the corresponding itemid index.
  3. Your onchange(x) function will look something like:
    javascript
    onchange(x)
    {
    document.formname.itemarray.value=document.formname.qtytextboxname.value;
    }
  4. Reference itemarray in your php as above.

As long as your itemid can be used as an index, the code above will work. So if you had 10 items:

null,null,3,null,4,5,6,null,null,9

then your quantity array will look like:
null,null,1,null,10,3,6,null,null,1

The only downside is that you’ll want to default your quantities to blank or 0 to force the user to change the value to trigger the javascript.

Hope that helps.

The edit window passed before I could finish my edits. Let me get you the correct javascript references for the javascript.

Sorry about the confusion. I had to refresh my memory on what I did.

Name each qty text box the same (like <input name=“qquantity” …)

If your itemid is an index, then the php code above will work except you’ll have to subtract 1 (ie itemid is really index 0) assuming you start itemid at 1.

Your values should then look like (using your example):
Item ordered: 5
Item ordered: 7
Item ordered: 8
order quantity[0]:blank or 1 or whatever the default is
order quantity[1]:default
order quantity[2]:default
order quantity[3]:default
order quantity[4]:2
order quantity[5]:default
order quantity[6]:1
order quantity[7]:5

I appreciate the advice. It may take me 6 months of study to understand what you just said, but I will hold out hope for no more than a couple weeks of intensive studying and head-scratching.

Your challenge with using JavaScript to remove the values is that is JavaScript is disabled, you’re somewhat hosed.

<?php

echo "<pre>";
print_r($_POST);
echo "</pre>";

if ( $_POST ) {
	foreach ( $_POST["file"] as $key => $var ) {
		echo "The key ". $key. " the text " . $_POST["text"][$key]."<br>";
	}
}
echo "<h2>Array Test</h2>
";
echo "<form method='post'>
";
for ($i=0; $i<20; $i++) {
	$value = $i + 100;
	echo "<div>
";
	echo "<input type='checkbox' name='file[$i]' value='check'>
";
	echo "<input type='text' name='text[$i]' value='".$value."'>
";
	echo "</div>
";
}
echo "<input name='button' type='submit' value='Submit'>
";
echo "</form>
";
	
?>

This is a simple form.

You need to be able to associate the checkbox with the value when it gets returned in the $_POST array.

You have learnt that will build a “next” value when you create your form. The trouble is that as has been pointed out, only the checked boxes will be returned whereas the values (regardless of value) will be returned.

You NEED to associate them together, so you will need to unlearn the in this case.

You will see that I have created a form that has $i as the index. This ensures that [1] for the checkbox can be associated with [1] for the value returned.

So if you run this code, firstly you will see
Array
(
)
followed by the form.

The blank array being displayed is because there are not $_POST values yet.

Tick a boxes 1, 2 and 4 and hit submit.

You should see something like this:


Array
(
    [file] => Array
        (
            [0] => check
            [1] => check
            [3] => check
        )

    [text] => Array
        (
            [0] => 100
            [1] => 101
            [2] => 102
            [3] => 103
            [4] => 104
            [5] => 105
            [6] => 106
            [7] => 107
            [8] => 108
            [9] => 109
            [10] => 110
            [11] => 111
            [12] => 112
            [13] => 113
            [14] => 114
            [15] => 115
            [16] => 116
            [17] => 117
            [18] => 118
            [19] => 119
        )

    [button] => Submit
)

The key 0 the text 100
The key 1 the text 101
The key 3 the text 103



Tick boxes 0, 1 and 3 are returned along with values 100 through 119. (Remember I started $i at 0 so 0 is the first tick box, 1 is the second, etc). I added 100 to $i to make it clear which was the index and which was the value for the text.

Now it is easy to see which boxes were checked and therefore you can use the value.

if ( $_POST ) {
	foreach ( $_POST["file"] as $key => $var ) {
		echo "The key ". $key. " the text " . $_POST["text"][$key]."<br>";
	}
}

This says if the $_POST variable is set, then for each of the files, extract the key and the value. Output the key and the value of the corresponding text.

If you want to make sure a value is set for a particular checkbox, add some validation like if $_POST[“text”][$key] > 0 then do something.

The code should work (it works on my machine), so you should be able to see exactly what is going on.

As bad as my knowledge of php and HTML is, my Javascript chops are pathetically worse. I would have to look at an example or open a manual to even know how to write the opening tag, something like <script language=javascript> I think?

Caught@work’s solution above looks promising but even there I’ve got a learning curve to climb. ( <pre>? never seen it, never used it, hmm fascinating!)

I woke up thinking “what if I totally get rid of the checkbox, switching to input type = hidden for the Item ID, and set the default for quantity to ZERO?”

They’ll all come over, I should have equal length strings for Item ID and quantity, and then I ignore the spots where quantity still equals zero. Any obvious reason that wouldn’t work?

But I’m going to play with that <pre> tag and get a sense of what it does. That looks promising.

The <pre> tag just removes all formatting, and allows for a monospaced font ouptut. Kind of like if you use the PHP or CODE tags in this and other forums.

You may look into using sessions to keep track of data you want to carry from page to page.
http://us3.php.net/manual/en/book.session.php

I’ve done something similar in the past with the ID=hidden, and it suited my purposed well. I didn’t like the idea of javascript error checking for forms that I was using, and used php in the back end to error check.

I’m remembering more and more lately that I miss messing around with PHP.
Though I have learned that I strongly dislike VB.

PS.
one of the more useful things I use <pre> for is to unformat the print_r command. I make a small little function that I use for this task, below. It has come in quite useful when I needed to debug multiple variables.


function mpr($data, $head=null) { //print_r replacement head=variable name.
  echo "<pre>";
  echo $head."<br>";
  print_r ($data);
  echo "</pre>";

If you have an item ID then, use it as the key in the form.

$tickbox[$itemid]
$value[$itemid]

Then in the post variable, for any $tickbox[$itemid] you get you can still extract the key and use it on the $value.

The foreach in my example show how to do that.

$i was handy.
$itemid is clearer.

This was effortless to set up and gets me off the hook. I’m still going to cycle back to the other suggestions when I get some free time, because I will learn from implementing them and situations I find myself in the future may not lend themselves to the solution I went with.

But “just kill the checkboxes” totally worked. I end up with equal-length ItemID and Quantity strings. Ditch the array positions where quantity “not > 0”. Done.

You now have a solution for your problem.
Of course, learning what has gone on in this thread will mean that at some point in the future, when you DO need a checkbox and value, you will be a little closer to understanding what you need to do.
Well done.

Yeah, that’s what I figured. Still worth my time to work my way through the tutorial. Checkboxes can be useful and I don’t want to be defeated by them.