Hi everyone and thanks for reading!
I use JavaScript to create sets of text boxes on the fly. I also have a hidden counter in a text box on the form which I also post to my PHP script. This hidden counter is how I tell PHP how many text boxes there are upon post (as PHP would have no idea if the user generated one more set, or ten more sets!).
if (isset($_POST["submit"])) {
// Bind the value of the counter to a variable.
$counter = $_POST["counter"];
echo "<p>There are <strong>" . $counter . "</strong> sets of text boxes.</p>\r\n";
}
These text boxes are named reference1, quantity1, details1 .... reference2, quantity2, details2 and so on. So by using something like the following, I can make PHP pick up the values:
for ($i=0; $i <= $counter; $i++) {
echo "<ul>\r\n";
echo "<li>";
echo $_POST["reference$i"] . " ";
echo $_POST["quantity$i"] . " ";
echo $_POST["details$i"] . " ";
echo "</li>\r\n";
echo "</ul>\r\n";
}
Is there any way I can bind these to variables? What I'm wanting to do is put each of these text boxes through some validation checks i.e. is it empty and so on, then return the form with the same amount of text boxes to the user and tell them what was wrong. Hope that makes sense!
Thanks,
Anthony
Yes, you could use a foreach statement to do this:
foreach($_POST as $key => $value) {
// Process here using $value for the content of the field.
}
Is that what you're looking for?
To be honest I'm not entirely sure, I have all these post variables and a counter which can tell php how many there are.
I need to somehow bind them to variables, or perhaps even an array, then run them through an error checking function.
Any Ideas?
So are you looking to put $_POST['reference1'] into $reference1 and $_POST['reference2'] into $reference2 etc. ?
If this is the case, use something lie:
foreach($_POST as $key => $value) {
$$key = $value;
}
Note the double $ in there.
This effetively does the same as enabling register_globals although only with the $_POST array so ensure that the data is cleaned and validated before any processing is done on it.
So are you looking to put $_POST['reference1'] into $reference1 and $_POST['reference2'] into $reference2 etc. ?
If this is the case, use something lie:
foreach($_POST as $key => $value) { $$key = $value; }Note the double $ in there.
This effetively does the same as enabling register_globals although only with the $_POST array so ensure that the data is cleaned and validated before any processing is done on it.
Never knew about that double dollar sign! So if I went through it like that, and assigned them all to variables surely I could set up functions to clean them, then make a loop which will push everyone one of them through the functions. To catch errors I could add the error to an array then outside of the loop (afterwards) check to see if the array is empty or not, right?
Yes, The $$key means create a variable with the name of $key. so running the foreach statement will mean that every single field on the form will be assigned to a variable named after the forms name (if you want to look into these, they are called variabe variables).
For basic cleaning you could do this in the foreach loop:
$$key = addslashes(trim($value)); To help protect against problems with certain characters and to also remove any spaces from the ends of the strings.
Providing all the fields are going to be validated in the same way, you could add the validation into the foreach loop and as you said have an array for the errors.
Hi Xan,
Firstly let me thank you for all the help so far, you're a real inspiration to the other posters!
I'll tell you where I'm tripping up, I did as you said about the foreach loop including $$key statements. Now that the loop has run, I now have all my variables and their values stored like $reference1, $reference2 etc..
Now that I have those variables floating around, I'm trying to make some more loops for them to hop through. One is for checking if the post data is empty and another that only applies specifically to the $quantity variable as I want to check it's numeric. Now I know how to make those checks (by using empty() and the is_numeric() functions), but I'm not sure how I make those variables run through them.
Do I make something like this?
$errorArray = array();
// Create a loop to go through all the post variables.
for ($i=1; $i <= $counter; $i++) {
$name = '$reference' . $i;
if ( empty($name) ) { $errorArray[] = "$name is empty"; }
$name = '$quantity' . $i;
if ( empty($name) ) { $errorArray[] = "$name is empty"; }
// etc.. etc..
}
if (empty($errorArray)) {
//do stuff
} else {
// print errors and redisplay the form with values pasted back into boxes.
}
Do you see where I'm coming from? I'm unsure how to make these loops go through all the post items, and just unsure about the set-up of the loop.
Thanks again for any help and guidance!
Anthony
No problems :)
The way I would do this:
$errorArray = array();
foreach($_POST as $key => $value) {
$$key = addslashes(trim($value));
if ( empty($value) ) { $errorArray[] = "$key is empty"; }
}
I am unsure of what you mean for the $quantity variables, but if I understand correctly, use the substr function in an if statement within the foreach to check if the field being checked has the correct name and if it does run the validation if that makes sense..
Hi everyone and thanks for reading!
I use JavaScript to create sets of text boxes on the fly. I also have a hidden counter in a text box on the form which I also post to my PHP script. This hidden counter is how I tell PHP how many text boxes there are upon post (as PHP would have no idea if the user generated one more set, or ten more sets!).
if (isset($_POST["submit"])) { // Bind the value of the counter to a variable. $counter = $_POST["counter"]; echo "<p>There are <strong>" . $counter . "</strong> sets of text boxes.</p>\r\n"; }These text boxes are named reference1, quantity1, details1 .... reference2, quantity2, details2 and so on. So by using something like the following, I can make PHP pick up the values:
for ($i=0; $i <= $counter; $i++) { echo "<ul>\r\n"; echo "<li>"; echo $_POST["reference$i"] . " "; echo $_POST["quantity$i"] . " "; echo $_POST["details$i"] . " "; echo "</li>\r\n"; echo "</ul>\r\n"; }Is there any way I can bind these to variables? What I'm wanting to do is put each of these text boxes through some validation checks i.e. is it empty and so on, then return the form with the same amount of text boxes to the user and tell them what was wrong. Hope that makes sense!
Thanks, Anthony
You can also get rid of that counter by following some type of naming scheme. You can, while you are looping, check the field name
<?
$txtcounter = 0; //number of textboxes being submitted
foreach($_POST as $key=>$value)
{
if(strtolower(substr($key, 0, 3)) == "txt"/*or whatever naming scheme best suits you*/)
{
$txtcounter++;
}
}
?>Hey R0bb0b,
Thats a really clever idea but I don't think it'd work for me. The counter is counting rows rather than individual text boxes. It's for a purchase order form you see, so one row consists of a reference number textbox, a quantity textbox and a details textbox. The idea is that when it comes to echoing out the form again if there are errors, PHP will know how many rows of boxes will need echo'ed, something like this:
for ($i=0; $i < counter; $i++) {
echo "<input type=\"text\" id=\"$reference.$i\" value=\"$reference.$i\">";
echo "<input type=\"text\" id=\"$quantity.$i\" value=\"$reference.$i\">";
echo "<input type=\"text\" id=\"$details.$i\" value=\"$reference.$i\">";
}
The only thing I'm trying to figure out is how to combine the textual words reference, quantity and details, with the number of the count, to make it the variable $reference1, $details3 and so on.. Any ideas?
Xan, Hey!
What I meant was that the post variables called quantity1, quantity2 etc.. need to have a different check on them, they need to be checked for being empty, but also need to be checked to make sure they're numeric, and if not then flag up an error. Would this then be:
$errorArray = array();
foreach ($_POST as $key => $value) {
$$key = addslashes(trim($value));
if ( empty($value) ) { $errorArray[] = "$key is empty"; }
if(strtolower(substr($key, 0, 3)) == "qua") {
if (!is_numeric($value) { $errorArray[] = "$key is not a valid number"; }
}
Something like that?
Thanks to both of you, you've no idea how much of lifesavers you are. I'm fairly ok with code but never done a project where the form is dynamic in that the user can have as many items as they please!
Anthony
That is the what you would be looking for, give it a spin and let us know if there are any other problems
Hey! I've been hard at work and I've definitely made progress! This is what I came up with:
foreach ($_POST as $key => $value) {
$$key = addslashes(trim($value));
if (empty($value)) {
if (strtolower(substr($key, 0, 1)) == "r") {
$stripped = substr($key, 9);
$errorArray[] = "Item $stripped: You have left the reference field empty. Please fill it in.";
}
if (strtolower(substr($key, 0, 1)) == "q") {
$stripped = substr($key, 8);
$errorArray[] = "Item $stripped: You have left the quantity field empty. Please fill it in.";
}
if (strtolower(substr($key, 0, 1)) == "d") {
$stripped = substr($key, 7);
$errorArray[] = "Item $stripped: You have left the details field empty. Please fill it in.";
}
}
if (strtolower(substr($key, 0, 1)) == "q") {
if (!is_numeric($value)) {
$stripped = substr($key, 8);
$errorArray[] = "Item $stripped: The value in the quantity field is not a valid number. Please try again.";
}
}
}
Now this picks up all the errors perfectly, and writes to the array correctly, but instead of having all that code there, I was going to wrap it up in a function in an include, but the array never gets anything written to it. This is an example:
emptyValue($key, $value);
//and in functions.php
function emptyValue($key, $value) {
if (empty($value)) {
if (strtolower(substr($key, 0, 1)) == "r") {
$stripped = substr($key, 9);
$errorArray[] = "Item $stripped: You have left the reference field empty. Please fill it in.";
}
if (strtolower(substr($key, 0, 1)) == "q") {
$stripped = substr($key, 8);
$errorArray[] = "Item $stripped: You have left the quantity field empty. Please fill it in.";
}
if (strtolower(substr($key, 0, 1)) == "d") {
$stripped = substr($key, 7);
$errorArray[] = "Item $stripped: You have left the details field empty. Please fill it in.";
}
}
if (strtolower(substr($key, 0, 1)) == "q") {
if (!is_numeric($value)) {
$stripped = substr($key, 8);
$errorArray[] = "Item $stripped: The value in the quantity field is not a valid number. Please try again.";
}
}
}
I think the issue is something to do with scope but I'm not sure. the require_once line to include the functions is ABOVE the $errorArray = Array(); line, does that matter?
Thanks Again,
Anthony
So long as the array is defined before the first call the the function emptyValue is made this should be fine.
So, your file should look like this now (basically)
require_once ("path_to_function.php");
$errorArray = Array();
foreach ($_POST as $key => $value) {
$$key = addslashes(trim($value));
emptyValue($key, $value)
}
Then the file with the function in would look like this:
function emptyValue($key, $value) {
if (empty($value)) {
if (strtolower(substr($key, 0, 1)) == "r") {
$stripped = substr($key, 9);
$errorArray[] = "Item $stripped: You have left the reference field empty. Please fill it in.";
}
if (strtolower(substr($key, 0, 1)) == "q") {
$stripped = substr($key, 8);
$errorArray[] = "Item $stripped: You have left the quantity field empty. Please fill it in.";
}
if (strtolower(substr($key, 0, 1)) == "d") {
$stripped = substr($key, 7);
$errorArray[] = "Item $stripped: You have left the details field empty. Please fill it in.";
}
}
if (strtolower(substr($key, 0, 1)) == "q") {
if (!is_numeric($value)) {
$stripped = substr($key, 8);
$errorArray[] = "Item $stripped: The value in the quantity field is not a valid number. Please try again.";
}
}
}Hey Xan, proud of me for that big function?! haha.
Yeah I looked at your advice there, I'm getting no response into this array, it remains blank. I've attached my code so you can see if it's something silly and obvious.
//index.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Form Test</title>
<script type="text/javascript" src="includes/items.js"></script>
<?php require_once("includes/functions.php"); ?>
</head>
<body>
<?
if (isset($_POST["submit"])) {
$errorArray = array();
// This selects the key and value of each post item. The $$ is a global only used for $_POST data. It takes the $_POST name as the new variable name and assigns the $_POST's value as the variable's value.
foreach ($_POST as $key => $value) {
$$key = addslashes(trim($value));
emptyValue($key, $value);
}
// Echo out the variables within $errorArray.
echo "<p>The error array looks as follows: ";
print_r($errorArray);
echo "</p>\r\n\r\n";
// Echo out how many sets of textboxes the script finds.
echo "<p>There are <strong>" . $counter . "</strong> sets of text boxes.</p>\r\n";
}
?>
<p><a href="javascript:addItem();">Click Me To Add</a></p>
<p><a href="javascript:removeItem();">Click Me To Delete</a></p>
<div id="formDiv">
<form id="purchaseOrder" name="purchaseOrder" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<div id="test" style="width: 650px;">
<label for="reference1" id="reference1lbl" name="reference1lbl">Reference</label>
<input id="reference1" name="reference1" type="text" value="" />
<label for="quantity1" id="quantity1lbl" name="quantity1lbl">Quantity</label>
<input id="quantity1" name="quantity1" type="text" value="" />
<label for="details1" id="details1lbl" name="details1lbl">Details</label>
<input id="details1" name="details1" type="text" value="" />
</div>
<input name="counter" id="counter" type="text" value="1" />
<input name="submit" id="submit" type="submit" />
</form>
</div>
</body>
</html>
//functions.php
<?
function emptyValue($key, $value) {
if (empty($value)) {
if (strtolower(substr($key, 0, 1)) == "r") {
$stripped = substr($key, 9);
$errorArray[] = "Item $stripped: You have left the reference field empty. Please fill it in.";
}
if (strtolower(substr($key, 0, 1)) == "q") {
$stripped = substr($key, 8);
$errorArray[] = "Item $stripped: You have left the quantity field empty. Please fill it in.";
}
if (strtolower(substr($key, 0, 1)) == "d") {
$stripped = substr($key, 7);
$errorArray[] = "Item $stripped: You have left the details field empty. Please fill it in.";
}
}
if (strtolower(substr($key, 0, 1)) == "q") {
if (!is_numeric($value)) {
$stripped = substr($key, 8);
$errorArray[] = "Item $stripped: The value in the quantity field is not a valid number. Please try again.";
}
}
}
?>
If I copy and paste the code from inside the function, into the foreach loop, it works fine, but if I call the function from inside that foreach, it wont work... very odd, any ideas?
Thanks man,
Anthony
If I copy and paste the code from inside the function, into the foreach loop, it works fine, but if I call the function from inside that foreach,
Does the script work if you comment the require_once line and put the function into the main page?
I may have overlooked something but I can't see any problems in there..
Does the script work if you comment the require_once line and put the function into the main page? I may have overlooked something but I can't see any problems in there..
Just tried to comment the require_once, and then put the function onto the page. Still doesn't work. Is it because the $key => $value variables are only accessible from inside the foreach loop, and can't be passed outside of the loop? I'm just spit balling here!
Shouldn't be, they will be passed as plain text to the function, try re-naming the variables in the function rather than calling them $key and $value.
Ok I took the script apart and passed the key and value variables, and simple echo'ed them out, which works. I'm going to add an if statement at a time and see where it breaks!
It's like playing with Lego :)
It's the lines about the array, it doesn't like the line where I'm updating the array, how odd that it works on page but not from an include!! Do I need to pass the array also or something?