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.
Related
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"}
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.
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.
I want to store an array of checklist into a string in a database. Below this is the code in the interface which display a list of room with a dropdown checklist for each room.
while($rows = mysql_fetch_array($query)){
<!-- Apply dropdown check list to the selected items -->
<script type="text/javascript">
$(document).ready(function(){$("#<?php echo $bnum; ?>").dropdownchecklist( { width: 300 } );});
</script>
<!-- This is the JQuery Dropdown checklist !-->
<select id="<?php print $bnum;?>" multiple="multiple" name="dietdata[]" >
<option value="0"></option>
<?php
//query drop-down list
$sqlakh="select diet_id,diet_name from bmsdb.diettypes";
$resultakh=mysql_query($sqlakh);
while($rowsakh= mysql_fetch_array($resultakh)) { ?>
<option value='<?php echo $rowsakh['diet_id'].'|'.$bnum; ?>'><?php echo $rowsakh['diet_name']; ?>
</option>
<?php }
}//end while ?>
</select>`
When I submit this form in the server side, this is what I do to extract the data from the array of the dropdown checklist:
$data2 = $_POST['data2']; //total no of data
$dietdata= $_POST['dietdata']; //diet data
$roomlist= $_POST['data3']; //patient room number
for($k=0; $k<=sizeof($data3); $k++){
$dietarray= $dietdata[$k];
$separatediet= (explode('|',$dietarray));
$output_array[]=array("diet"=>$separatediet['0'],"room"=>$separatediet['1']);
for($j=0; $j<=sizeof($data3); $j++){
if($output_array[$k][room]== $roomlist[$j]){
$rekod[$output_array[$k][room]]= $output_array[$k][diet];
}
}
}print_r($rekod);
The print_r output when I submitting the form is like this:
Array ( [501] => 3 [502] => 4 [] => )
Then I extract the array using implode to separate the room and the diet type.
Array ( [0] => 2|501 [1] => 3|501
[2] => 3|502 [3] => 4|502 )
What I want is for the array to be like this. Is there any way for me to make the array to be like this, or a better structure to use?
Array ( [501] => 2,3) //2,3 is the diet type group together after being extracted from the array above
[502] => 3,4 )
Assuming you're keeping all the code up to the point where you're imploding to generate your final array:
Array ( [0] => 2|501 [1] => 3|501
[2] => 3|502 [3] => 4|502 )
You could create the array you're asking for like this:
$out = array(); // The final output array
foreach ($your_array as $item) {
$vals = explode('|', $item);
if (!isset($out[$item[1]])) $out[$item[1]] = array();
$out[$item[1]][] = $item[0];
}
foreach ($out as &$item) {
$item = implode(',', $item);
}
This is my final code. Which generata output like this
Array ( [501] => 2,3,4 [502] => 3,4 [503] => 5,6 )
Thanks to Hibiscus for your help.
$out = array(); // The final output array
foreach ($status as $item) {
$vals = explode('|', $item);
if (!isset($out[$vals[1]])) $out[$vals[1]] = array();
$out[$vals[1]][] = $item[0];
}
$item=array();
foreach ($out as &$item)
{
$item = implode(',', $item);
}
$diet = array();
$data3 = $_POST['data3'];
for($h=0; $h<=$data2; $h++)
{
$data3 = $_POST['data3']; //patient bnum
$data3 = $data3[$h];//bnum
if(!empty($out[$data3]))
{
$diet[$data3] = $out[$data3];
}
} print_r($diet);
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;
}