update multidimensional array - php

I have a multidimensional array containing character names from the Simpsons (homver, Marge and bart) and I have echoed the keys and values in a foreach loop. I want to have two input boxes next to each character name, that updates the id and size of each specific name.
I have the code bellow. The values are showing inside the input box but they are not updating :(
Thanks in advance for all the help
CODE
//
<?php
session_start();
$array=array(
'Homer' => Array
(
'id' => 111,
'size' => 54
),
'Marge' => Array
(
'id' => 222,
'size' => 12
),
'Bart' => Array
(
'id' => 333,
'size' => 3
)
);
////////////////////////////////////
if (isset($_POST["submit"])) {
for ($i = 0; $i < count($_POST['names']); $i++) {
$names = $_POST['names'][$i];
$ids = $_POST['ids'][$i];
$sizes = $_POST['sizes'][$i];
}
}
////////////////////////////////////
echo "<form method='post' action=''>";
// put the array in a session variable
if(!isset($_SESSION['simpsons']))
$_SESSION['simpsons']=$array;
// getting each array in a foreach loop
foreach( $_SESSION['simpsons'] as $character => $info) {
echo $character.': id is '.$info['id'].', size is '.$info['size'];
//add and update input box for each ' id ' and ' size '
?>
<input type="text" name="names[]" value="<?php echo $character;?>" />
<input type="text" name="ids[]" value="<?php echo $info['id'];?>" />
<input type="text" name="sizes[]" value="<?php echo $info['size'];?>" />
<?php
echo"<br/>";
}
?>
<!-- submit button for the form -->
<input class="inputbox" type="submit" value="Update value of key" name="submit"/>
</form>

The Issue
Let's take a look at what your code does when a user submits the form...
if (isset($_POST["submit"])) {
for ($i = 0; $i < count($_POST['names']); $i++) {
$names = $_POST['names'][$i];
$ids = $_POST['ids'][$i];
$sizes = $_POST['sizes'][$i];
}
}
Great. You take the form data, and loop through each character in your simpsons array, and for each character set $names,$ids, and $sizes.
There are two issues that I see.
The three variables you set that I named above, are not arrays, but hold single values for the specific character at that iteration in the loop.
Nothing is done with the variables. The values are set for one character, and then overwritten for the next. Nothing is done with the data.
One Possible Solution
So let's do something with the data from the form. Here is my solution.
if (isset($_POST["submit"])) {
$newArray = [];
for ($i = 0; $i < count($_POST['names']); $i++) {
$newArray[$_POST['names'][$i]] = [
'id' => $_POST['ids'][$i],
'size' => $_POST['sizes'][$i]
];
}
$_SESSION['simpsons'] = $newArray;
}
If the form is submitted, we make a new temporary array. We then add new sub arrays for each character with their set id and size. Then we put that array into the session.

Related

PHP Form keep input values together to create JSON list

I have a JSON list with conditions(items) and a color associated to every condition. I'm building a form to try to update the conditions, then return to the JSON format.
Example:
<?php
?>
$JSON_list = {
"FULL":"green",
"Half-Full":"amber",
"Quarter-Full":"amber",
"Empty":"red"
}
I json_decode() this list to turn it into a php array. Then iterate through it and display the values as inputs which can be edited.
<form action="updatedata.php" method="post">
<?php
foreach($JSON_list as $condition) {
foreach($condition as $item => $color){
?>
<input type="text" name="item[]" value="<?=$item;?>">
<select name="color[]">
<option selected="selected"><?=$color;?></option>
<option>green</option>
<option>amber</option>
<option>red</option>
</select>
<br>
<?php
};
};
};
?>
<input type="submit" value="Submit Conditions">
</form>
On submission of the form, the "items" & "colors" are stored in 2 different arrays separate from each other. I iterate through each of these arrays to obtain the new values, and then concatenate them into a JSON list again.
updatedata.php:
<?php
$num = count($_POST['item']);
$i = 1;
$subs = [];
foreach($_POST["item"] as $item){
$subs["item".$i] = $item;
$i++;
};
$c = 1;
foreach($_POST["color"] as $item){
$subs["color".$c] = $item;
$c++;
};
$submit_string = "";
$a = 1;
$comma = ",";
for($x = 0; $x < $num; $x++){
if($a == $num){
$comma = "";
};
$submit_string .= "\"".$subs["item".$a]."\":"."\"".$subs["color".$a]."\"".$comma;
$a++;
};
echo "{" . $submit_string . "}";
//Prints the JSON string "FULL":"green","Half-Full":"amber","Quarter-Full":"amber","Empty":"red"
?>
My problem occurs when the "item" input is submitted with nothing, if an item has a value of "" then I don't want this entry in the JSON list. I need to delete this entry, but also the "color" associated to that item.
Is there a way to link the "items" & "numbers" from the form so I can delete both entries??
I think there is maybe a bit more to your code you are not showing us, for example with the given structure of $JSON_list the 2 nested foreach loops you have to generate the HTML would not work. Here's what I did to get your code working:
$JSON_list needs quotes and a trailing semi-colon:
$JSON_list = '{
"FULL":"green",
"Half-Full":"amber",
"Quarter-Full":"amber",
"Empty":"red"
}';
Convert it to an array:
$array = json_decode($JSON_list, true);
Generate the HTML:
<?php foreach ($array as $item => $color) { ?>
<input type="text" name="item[]" value="<?php echo $item; ?>">
<select name="color[]">
<option selected="selected"><?php echo $color; ?></option>
<option>green</option>
<option>amber</option>
<option>red</option>
</select>
<br>
<?php } ?>
Next, if you dump out what you're getting back from a form submission, it gives you an idea of how to process it. Here's the output of print_r($_POST); after the form was submitted with the "HALF-FULL" text input blank:
Array
(
[item] => Array
(
[0] => FULL
[1] =>
[2] => Quarter-Full
[3] => Empty
)
[color] => Array
(
[0] => green
[1] => amber
[2] => amber
[3] => red
)
)
So now the relation between the 2 arrays is clear, and you can see we can use the array keys to map the elements of one to the other.
// We'll store our results in this new array
$submitted = [];
// Iterate over the first array elements
foreach ($_POST['item'] as $key => $value) {
// We only want to include item/colors that were non-blank,
// so check if we got an item here
if ($value) {
// OK it wasn't blank, so let's save the result, using
// the corresponding element from the color array
$submitted[$value] = $_POST['color'][$key];
}
}
// Now we have an array of our submitted data
// print_r($submitted);
// Array
// (
// [FULL] => green
// [Quarter-Full] => amber
// [Empty] => red
// )
// You should never try to construct a JSON string manually, just
// let PHP do it for you:
$newList = json_encode($submitted);
// echo $newList;
// {"FULL":"green","Quarter-Full":"amber","Empty":"red"}

PHP - Get all values that has been checked in checkbox and combine it in one array

I had no problem on getting the values from HTML form but my problem is how to combine all values that I got in one array?
Example:
Quantity[] is separated from CheckBox[]. If the checkbox has been checked, only all values of it (Pizza ID, Name, Price and Quantity) should be transfer into one array.
Snippet Code:
<tbody>
<?php
$Row = 0;
while ($Row = mysqli_fetch_array($Retrieval_Query, MYSQLI_ASSOC)){
$pizzaID = $Row['pizzaID'];
$pizzaName = $Row['pizzaName'];
$pizzaPrice = $Row['pizzaPrice'];
?>
<tr>
<td><?php echo $pizzaID; ?></td>
<td><?php echo $pizzaName; ?> </td>
<td><?php echo $pizzaPrice; ?> </td>
<td><input type = "number" name = "Quantities[]" placeholder = "0"/></td>
<td><input type = "checkbox" name = "CheckBox[]" value="<?=$pizzaID?>,<?=$pizzaName?>,<?=$pizzaPrice?>" placeholder = "0"/></td>
</tr>
<?php } ?>
</tbody>
</table>
</form>
<button type="submit" form="form1" value="Atc" name="atc" class="btn btn-warning">Add to Cart</button>
Back end:
<?php
$values = array();
$quantities = array();
if(isset($_POST['atc'])){
//Operation to retrieve all values from HTML CheckBox[] and Quantities[] since they are separated inputs
//And push all values that has been retrieved into same array
foreach($_POST['CheckBox'] as $key => $value){
array_push($values, $value);
}
foreach($_POST['Quantities'] as $key => $value){
array_push($values, $value);
}
Current Output:
Desired Output:
How to achieve the desired output? Is my technique on getting the values from HTML
(2 Separated arrays) is right? How to make all values to be combine in
just one array?
You'll get a better understanding of what is happening if you view the POSTed data as PHP sees it in your script. At the top of your PHP add:
print_r($_POST);
die();
And you'll see:
Array
(
[Quantities] => Array
(
[0] => 23
[1] =>
[2] => 33
)
[CheckBox] => Array
(
[0] => 1,Hawaiian,150
[1] => 3,Four Cheese,300
)
Next, array_push simply appends elements to the end of an array. So you're just joining those 2 arrays one after the other, without preserving the fact that the elements relate to each other.
The next problem is that checkboxes don't appear in the POSTed data at all if they are not checked. You can see that there are only 2 elements in the Checkbox array, even though you have 5 pizzas in the form. That means you can't connect elements from the Quantities array and the CheckBox array using the key. Key 1 in Quantities corresponds to Bacon and Cheese, but key 1 in CheckBox corresponds to Four Cheese.
I don't see an easy way to solve this using your current approach.
But take a step back - do you really want to POST the price to your handling code? What if I edit the form in my browser and set the price to "1", or "0"? You should never trust data coming from the browser, and you have this data in your database already.
Do you really care about a pizza in the order if the quantity is 0? You can get rid of the checkbox, since entering a number in the quantity field controls whether or not they're getting that pizza.
Here's an alternative approach:
<?php while ($Row = mysqli_fetch_array($Retrieval_Query, MYSQLI_ASSOC)) { ?>
<tr>
<td><?php echo $Row['pizzaID']; ?></td>
<td><?php echo $Row['pizzaName']; ?></td>
<td><?php echo $Row['pizzaPrice']; ?></td>
<td>
<!-- include the ids, we can refer to those for each quantity -->
<input type="hidden" name="ids[]" value="<?php echo $Row['pizzaID']; ?>"/>
<input type="number" name="Quantities[]" placeholder = "0"/>
</td>
</tr>
<?php } ?>
Now on your back end, you can do something like:
foreach ($_POST['Quantities'] as $key => $value) {
if (empty($value) || $value == 0) {
// wasn't ordered! Skip to the next.
continue;
}
$id = $_POST['ids'][$key];
// Now you know they want $value of pizza id $id. You can look
// up the price, name, etc, from your DB, same as you did to
// display them on the form in the first place.
}
Side note - it might just be copy-paste issues between your real code and your question here on SO, but the submit button should be inside the </form> tag.
You could use the "associative array" style of naming your form inputs, as described in the PHP docs:
http://www.php.net/manual/en/faq.html.php#faq.html.arrays
Use your unique pizzaID as the key for both input arrays:
(Include a string element (I've used id_ here) to ensure that it will be a string key that we will be working with later as the array functions work differently for numerically indexed arrays)
while ($Row = mysqli_fetch_array($Retrieval_Query, MYSQLI_ASSOC))
{?>
<input type = "number" name = "Quantities[id_<?=$pizzaID?>]" id="qty<?php echo $cnt?>" placeholder = "0"/>
<input type = "checkbox" name = "CheckBox[id_<?=$pizzaID?>]" data-cnt="<?php echo $cnt?>" value="<?=$pizzaID?>,<?=$pizzaName?>,<?=$pizzaPrice?>" placeholder = "0"/>
<?php }
When you read the POST values in, each named array will be in the format of key => [id => value].
You can then use the id key strings to unify the values in the 2 arrays using array_merge_recursive.
$q = $_POST['Quantities'] ?? [];
$c = $_POST['CheckBox'] ?? [];
$merged = array_merge_recursive($q, $c);
This will combine all of the values associated with each pizzaId key. The resulting array looks like this:
Array
(
[id_1] => Array
(
[0] => 1,Hawaiian,150
[1] => 23
)
[id_3] => Array
(
[0] => 3,Four Cheese,300
[1] => 33
)
)
Now you can squash these merged arrays to produce a single comma delimited list for each pizzaId:
$squashed = array_map(function($v){
return is_array($v)
? implode(',', $v)
: $v;
}, $merged);
The $squashed array will now contain:
Array
(
[id_1] => 1,Hawaiian,150,23
[id_3] => 3,Four Cheese,300,33
)
The id_ prefix can then be stripped out of the keys if required.
One caveat would be that if the user has only submitted values for one of the 2 input fields, then the resulting array will only contain that single value and it would take further analysis to determine whether this was the Quantity or Checkbox value (e.g. checking against is_int() could determine whether the value belonged to Quantity).
$values = array();
$quantities = array();
foreach($_POST['CheckBox'] as $key => $value){
array_push($values, $value);
}
$quantities = $_POST['Quantities'];
$i=0;
foreach ($quantities as $q){
if($q){
$values[$i] = $values[$i].','.$q;
$i++;
}
}
below is my output
Array
(
[0] => 1,Hawa,150,23
[1] => 3,Four,300,33
)
Here your check box array indexing is different from quantity indexing so bcz of that you have to change the way of code:
on click check box you have to con-cat quantity with check box value like:
$(document).on('click','input[name=checkBoxName]',function()
{
if($(this).is(":checked")) //check if checkbox checked
{
var key = $(this).attr('data-cnt');
var qty = $("#qty"+key).val(); //return qty id value like qty1
$(this).val($(this).val()+','+qty);
}
else //check box not checked then remove last qty value
{
var text = $(this).val();
var resArray = text.split(",");
var poppedItem = resArray.pop();
var result = resArray.toString();
$(this).val(result);
}
});
before while loop declare cnt=0;
while()
{?>
<input type = "number" name = "Quantities[]" id="qty<?php echo $cnt?>" placeholder = "0"/>
<input type = "checkbox" name = "CheckBox[]" data-cnt="<?php echo $cnt?>" value="<?=$pizzaID?>,<?=$pizzaName?>,<?=$pizzaPrice?>" placeholder = "0"/>
<?php }
when you post data then you will get :
foreach($_POST['CheckBox'] as $key => $value){
array_push($values, $value);
}
var_dump($values);
you will get expected output.

Skip Array value if null

I have a form that is taking user input and placing it into an array. Each form item has a label. The text in the labels corresponds to the items in the array $items.
if(isset($_POST['submit'])){
$items = array('Apple', 'Banana', 'Oranges', 'Grapes');
$amount = array();
foreach($_POST['item'] as $value){
$amount[]=($value);
}
$total =array_combine($items, $amount);
}
?>
<form method="post" action"">
<label>Apple</label><input type="text" name=item[]>
<label>Banana</label><input type="text" name=item[]>
<label>Orange</label><input type="text" name=item[]>
<label>Grapes</label><input type="text" name=item[]>
<input type="submit" name="submit" value="submit">
</form>
<?php
print_r($total);
?>
I combine both arrays and get the output as the numbers represent the amount of items.
Array ( [Apple] => 12 [Banana] => 14 [Oranges] => 7 [Grapes] => 2 )
I want to be able to skip an item in the array if one of the forms is not filled in for example if oranges is missed out. I would like the array to output
Array ( [Apple] => 12 [Banana] => 14 [Grapes] => 2 )
I also tried imploding $total to output the array items
echo implode(",", $total);
However I only go the values from the $amount array and not both $items and $amount.
If the code structure should stay same and you need to add some lines of code, you could just add the counter and if statement in foreach loop like this:
if(isset($_POST['submit'])){
$items = array('Apple', 'Banana', 'Oranges', 'Grapes');
$amount = array();
$counter=0;
foreach($_POST['item'] as $value){
if(strlen($value) != 0) {
$amount[]=($value);
}
else{
unset($items[$counter]);
}
$counter++;
}
$total =array_combine($items, $amount);
}
This will keep the count of items you have in $items array and if there is no value in the passed data, the if statement will filter that item out from $items array.
In this case you also should check if the passed data from the form is not empty, otherwise PHP will throw you an error.

Count posts with iterator

can i count how many POST's are submitted as Field_Amount_1, Field_Amount_2, Field_Amount_3, etc... like this ?
$Counting = count($_POST['Field_Amount_']);
Thanks for any suggestion
Well the easiest way would be to correct your form like:
<input name="Field_Amount[]" type="text" />
<input name="Field_Amount[]" type="text" />
<input name="Field_Amount[]" type="text" />
This makes it post an array so $_POST would contain:
Array (
'Field_Amount' => Array (
0 => 'amount'
1 => 'amount'
2 => 'amount'
)
)
Then you can just do count($_POST['Field_Amount'])
The other way would be to manually count all the all the elements:
$keys = array_keys($_POST);
$counted = count(preg_grep('/^Field_Amount_\d+$/', $keys));
If you also need to make sure you only track fields that are not empty then you could do supply an empty string as the second param to array_keys:
$keys = array_keys($_POST, '');
$counted = count(preg_grep('/^Field_Amount_\d+$/', $keys));
If you need to do more validation than that then you will need to manually loop.
if($_POST['Submit']) {
$count=0;
foreach( $_POST as $post ) {
if( strstr($post, "field_amount_")) {
$count++;
}
}
echo $count;
}

I need help making a PHP form parse code lighter

I have a PHP form which allows users to enter up 99 items if they do so desire. I was hoping that PHP doesn't need me to parse each individule item and it can handle doing a loop or something for when there are many items enter.
currently my php looks like this
$item1 = $_POST['Item1'] ;
$item2 = $_POST['Item2'] ;
$item3 = $_POST['Item3'] ;
$item4 = $_POST['Item4'] ;
$item5 = $_POST['Item5'] ;
// etc, etc
But I don't want 99 lines of code if only 5% of people enter more than one item in the form.
Have all the inputs named items[] (note the []). You can then access them all in an array called $_POST['items']. You can then iterate through all the values:
foreach($_POST['items'] as $item)
{
// ...
}
change the input-names like this:
<input type="text" name="items[]"/>
<input type="text" name="items[]"/>
<input type="text" name="items[]"/>
and you'll get an array:
$items = $_POST['items'] ;
foreach($items as $item){
// walk throug items and do something
}
You need to name your input elements like this:
<input type="text" name="Item[]" value="A" />
<input type="text" name="Item[]" value="B" />
<input type="text" name="Item[]" value="C" />
And then in PHP you will see this in $_POST as an
array(
0 => 'A',
1 => 'B',
2 => 'C'
)
This is a standard PHP trick, and you can use it to get any elements automatically inside the same array when reading them from $_POST and $_GET.
Another alternative :
foreach($_POST as $index => $value) {
$item[$index] = $value;
}
for ($i = 1;$i<100;$i++)
{
${"item".$i} = $_POST['Item'.$i];
}
//or you can use variables directly
//echo ($_POST['Item1']);
or you can change Item1, Item2, .... in form to Items[] and then call it like
$items = $_POST['Items'];
print_r($items);
/*
array
(
[0] => "some"
[1] => "text"
[2] => "another"
[3] => "text"
)
*/
foreach ($_POST as $key=>$value) {
if (substr($key, 0, 4)=="Item") {
$item[substr($key, 4)]=$value;
}
}

Categories