Using a PHP foreach loop within another foreach loop - php

I am trying to populate a table with rows from a database. However, one of the columns is a dropdown that needs to be populated with more than one value, therefore needing to use fetchAll. However, I am having trouble since I am using a foreach construct inside another foreach construct.
I'm guessing this isn't possible, or am I just doing something wrong? How can I find a workaround so that I can populate the entire table while also populating the dropdown with more than just one value, but still having it default to the value that it is in the database?
<?php
$sql = "SELECT TOP 100 *
FROM Table_OS_List
ORDER BY [CURRENT_SKU] ASC";
$drops = "SELECT [Purchasing_Group]
FROM Table_OS_List
GROUP BY [Purchasing_Group]";
$drop = $dbh->query($drops);
?>
<?php
/* Foreach loop that brings in information to populate table */
foreach ($dbh->query($sql) as $rows) {
?>
<tr class="row">
<td class="old_sku" id="old_sku"><?php echo intval ($rows['OLD_SKU'])?></td>
<td class="current_sku" id="current_sku"><?php echo intval ($rows['CURRENT_SKU'])?></td>
<td class="id" id="id" style="display: none;"><?php echo intval ($rows['ID'])?></td>
<td class="dropdown-select" id="purchgroup">
<select id="selected_group" class="selected_group" disabled>
<?php foreach($drop->fetchAll() as $dropdown) { ?>
<option class="choice" value="Purchasing Group"><?php echo $dropdown['Purchasing_Group'];?></option>
<?php } ?>
</select>
</td>
<td><input type="button" class="edit" name="edit" value="Edit"></td>
<td><input type="button" class="delete" name="delete" id="<?php echo intval ($rows['ID'])?>" value="Delete"></td>
</tr>
<?php
}
?>
NOTE
This code correctly populates the entire table, however the dropdown list only has the value that is in each row and is not populated with the other value options if I need to select something different:
<?php
/* Foreach loop that brings in information to populate table */
foreach ($dbh->query($sql) as $rows) {
?>
<tr class="row">
<td class="old_sku" id="old_sku"><?php echo intval ($rows['OLD_SKU'])?></td>
<td class="current_sku" id="current_sku"><?php echo intval ($rows['CURRENT_SKU'])?></td>
<td class="id" id="id" style="display: none;"><?php echo intval ($rows['ID'])?></td>
<td class="dropdown-select" id="purchgroup">
<select id="selected_group" class="selected_group" disabled>
<option class="choice" value="Purchasing Group"><?php echo $rows['Purchasing_Group'];?></option>
</select>
</td>
<td><input type="button" class="edit" name="edit" value="Edit"></td>
<td><input type="button" class="delete" name="delete" id="<?php echo intval ($rows['ID'])?>" value="Delete"></td>
</tr>
<?php
}
?>
EDIT:
Each dropdown is automatically defaulting to Bowling Green even if that row should not be Bowling Green. Most rows are either Southeast or Michigan but regardless of what it should be, it is defaulting to Bowling Green for some reason

Yes, doing it wrong, you are consuming the second resultset on completion of the first iteration of the outer foreach so instead retrieve the dropdown contents into an array so you can reuse it many times
<?php
$sql = "SELECT TOP 100 *
FROM Table_OS_List
ORDER BY [CURRENT_SKU] ASC";
$drops = "SELECT [Purchasing_Group]
FROM Table_OS_List
GROUP BY [Purchasing_Group]";
$drop = $dbh->query($drops);
$allDrops = $drop->fetchAll();
?>
<?php
/* Foreach loop that brings in information to populate table */
foreach ($dbh->query($sql) as $rows) {
?>
<tr class="row">
<td class="old_sku" id="old_sku"><?php echo intval ($rows['OLD_SKU'])?></td>
<td class="current_sku" id="current_sku"><?php echo intval ($rows['CURRENT_SKU'])?></td>
<td class="id" id="id" style="display: none;"><?php echo intval ($rows['ID'])?></td>
<td class="dropdown-select" id="purchgroup">
<select id="selected_group" class="selected_group" disabled>
<?php
foreach($allDrops as $dropdown) {
//--------------^^^^^^^^^
// Also changed the way you fill the option tag below
?>
<option class="choice"
value="<?php echo $dropdown['Purchasing_Group'];?>">
<?php echo $dropdown['Purchasing_Group'];?>
</option>
<?php } ?>
</select>
</td>
<td><input type="button" class="edit" name="edit" value="Edit"></td>
<td><input type="button" class="delete" name="delete" id="<?php echo intval ($rows['ID'])?>" value="Delete"></td>
</tr>
<?php
}
?>

Related

PHP Mysql PDO code efficiency - Foreach loop within a foreach loop

Hello to all!
I am new to coding and will be studding in class in next September. Looking forward to that....:-)
I am making a modification page for my data base. It's composed of inputs and a drop down list to modify the content of the DB. At least for now...till I learn more.
I am coding for my self and was wondering if the following was the correct way to do this? In my mind it's not, because the inner query gets executed every time the outer loop goes through...But it work!?!?
It's the only way I could find to make the inner FOREACH loop ($familylist) work with the Mysql query. If the query for the inner loop is outside the outer loop ($plantList)...it does not work. The first drop down list gets populated with the content but the following rows do not, at least only with the first option, it does not get populated with the content from the query.
Any help is welcome and appreciated!
<?php //more code here....
$plantQuery = "SELECT id, genre, espece, famille FROM plante ORDER BY genre";
$plantList = $dbconnect->query ($plantQuery);
?>
<table>
<thead>
<tr>
<th>ID</th>
<th>GENRE</th>
<th>ESPÈCE</th>
<th>FAMILLE</th>
</tr>
</thead>
<tbody>
<?php foreach ($plantList->fetchAll(PDO::FETCH_ASSOC) as $plant) : ?>
<form method="post">
<tr>
<td><input name="id" value="<?php echo $plant["id"] ;?>" readonly></td>
<td><input name="genre" value="<?php echo $plant["genre"] ;?>"></td>
<td><input name="espece" value="<?php echo $plant["espece"] ;?>"></td>
<td><select name="familleList" >
<option value="0" >Choisir une famille</option>
<?php
$familyQuery = "SELECT id, famille FROM famille ORDER BY id ASC";
$familyList = $dbconnect->query ($familyQuery);
?>
<?php foreach ($familyList->fetchAll(PDO::FETCH_ASSOC) as $family):?>
<option value="<?php echo $family["id"] ;?>" <?php if ($plant["famille"] <> 0 && $plant["famille"] == $family["id"] ) {echo "selected"; }?>><?php echo $family["id"] . " - " . $family["famille"] ;?></option>
<?php endforeach ;?>
</select>
</td>
<td><button name="modifier" type="submit">Modifier</button></td>
<td><button name="supprimer" type="submit">Supprimer</button></td>
</tr>
</form>
<?php endforeach ;?>
</tbody>
</table>
Instead of calling the database multiple times, for the same data inside the loop. A simple solution would be to call it once. At the top of the file do something like this.
$families = $familyList->fetchAll(PDO::FETCH_ASSOC);
And then you can chance your foreach loop to.
foreach ($families as $family)
This will make the query execute once, and therefor avoid multiple queries to the database. And loop over the already fetched data in the loops.
You were right. What you are doing is very inefficient. Database queries tend to be something that really create a bottleneck, so minimizing them is generally the best thing to do.
Since you are not passing any values into the second query, just take it out of the loop:
<?php //more code here....
$plantQuery = "SELECT id, genre, espece, famille FROM plante ORDER BY genre";
$plantList = $dbconnect->query ($plantQuery);
$familyQuery = "SELECT id, famille FROM famille ORDER BY id ASC";
$familyList = $dbconnect->query ($familyQuery);
?>
<table>
<thead>
<tr>
<th>ID</th>
<th>GENRE</th>
<th>ESPÈCE</th>
<th>FAMILLE</th>
</tr>
</thead>
<tbody>
<?php foreach ($plantList->fetchAll(PDO::FETCH_ASSOC) as $plant) : ?>
<form method="post">
<tr>
<td><input name="id" value="<?php echo $plant["id"] ;?>" readonly></td>
<td><input name="genre" value="<?php echo $plant["genre"] ;?>"></td>
<td><input name="espece" value="<?php echo $plant["espece"] ;?>"></td>
<td><select name="familleList" >
<option value="0" >Choisir une famille</option>
<?php
?>
<?php foreach ($familyList as $family):?>
<option value="<?php echo $family["id"] ;?>" <?php if ($plant["famille"] <> 0 && $plant["famille"] == $family["id"] ) {echo "selected"; }?>><?php echo $family["id"] . " - " . $family["famille"] ;?></option>
<?php endforeach ;?>
</select>
</td>
<td><button name="modifier" type="submit">Modifier</button></td>
<td><button name="supprimer" type="submit">Supprimer</button></td>
</tr>
</form>
<?php endforeach ;?>
</tbody>
</table>
Even though this is not the case here, whenever you are executing the same query multiple times only changing the variables, you can use prepared statements:
$familyQuery = $dbconnect->prepare("SELECT * FROM famille
WHERE something = :s
AND somethingelse = :se ORDER BY id ASC");
foreach ($values as $val) {
$familyQuery->bindValue('s', $val);
$familyQuery->bindValue('se', somefunction($val));
$familyQuery->execute();
$results = $familyQuery->fetchAll();
// Do something with the results
}
This way the query is first sent to the DB server and the values are all sent separately.

Display <select> in each table row by using the same database table data

I'm going to construct a table to let my user enter their SPM result then my system will filter and show them which course is eligible to apply.
I've tried to make 10 rows in a table and each row consisted of 2 <select>, one is SPM subject and another one is the grade they obtained. The options of Subject and Grade were fetch from my database.
Here is my coding for my table:
<?php
$result = mysql_query("SELECT * FROM spm_subject");
$result2 = mysql_query("SELECT * FROM spm_grade");
?>
<table class="p1" bgcolor="#FFFFCC" bordercolor="#000000" align="center" width="771" border="2">
<tr>
<td><div align="center"><strong>No.</strong></div></td>
<td><div align="center"><strong>Subject Name</strong></div></td>
<td><div align="center"><strong>Grade</strong></div></td>
</tr>
<form action="checkresult2.php">
<?php
for($i=1; $i<=10; $i++)
{?>
<tr>
<td width="44"><div align="center"><?php echo $i; ?></div></td>
<td width="601">
<select>
<option value="">--- Please choose a subject ---</option>
<?php
while($s = mysql_fetch_assoc($result))
{?>
<option name="subj"><?php echo $s["name"]; ?></option>
<?php } ?>
</select>
</td>
<td width="104"><div align="center">
<select>
<option value=""> </option>
<?php
while($g = mysql_fetch_assoc($result2))
{?>
<option name="grad"><?php echo $g["grade"]; ?></option>
<?php } ?>
</select>
</div>
</td>
</tr>
<?php } ?>
<tr>
<td colspan="3">
<div align="center">
<input type="submit" value="Submit">
</div>
</td>
</tr>
</form>
</table>
The table was constructed but only the FIRST ROW able to display data from the both database tables inside the both <select>.
Any solution to solve this problem?
1) Remove <form> inside <table>. Because, A form is not allowed to be a child element of a table, tbody or tr. You can have an entire table inside a form. You can have a form inside a table cell. You cannot have part of a table inside a form. For more info, click this
2) <option> don't have name attribute. Check here
3) Give name to <select></select> . Check here
4) Since, multiple values are being submitted to checkresult2.php page, you have to define name as name="subj[]" and name="grad[]" as array type.
5) An Alternative way for showing data in rest 9 rows is : before while loop give that query there itself, like below.
Updated Code.
<form action="checkresult2.php">
<table class="p1" bgcolor="#FFFFCC" bordercolor="#000000" align="center" width="771" border="2">
<tr>
<td><div align="center"><strong>No.</strong></div></td>
<td><div align="center"><strong>Subject Name</strong></div></td>
<td><div align="center"><strong>Grade</strong></div></td>
</tr>
<?php
for($i=1; $i<=10; $i++)
{?>
<tr>
<td width="44"><div align="center"><?php echo $i; ?></div></td>
<td width="601">
<select name="subj[]">
<option value="">--- Please choose a subject ---</option>
<?php
$result = mysql_query("SELECT * FROM spm_subject");
while($s = mysql_fetch_assoc($result))
{?>
<option value="<?php echo $s['name']; ?>"><?php echo $s["name"]; ?></option>
<?php } ?>
</select>
</td>
<td width="104"><div align="center">
<select name="grad[]">
<option value=""> </option>
<?php
$result2 = mysql_query("SELECT * FROM spm_grade");
while($g = mysql_fetch_assoc($result2))
{?>
<option value="<?php echo $g['grade']; ?>"><?php echo $g["grade"]; ?></option>
<?php } ?>
</select>
</div>
</td>
</tr>
<?php }?>
<tr>
<td colspan="3">
<div align="center">
<input type="submit" value="Submit">
</div>
</td>
</tr>
</table>
</form>
[NOTE: mysql_ is deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0. Use MySQLi or PDO_MySQL extension should be used.]
You have to preprocess the query populating two arrays:
$names = $grades = array();
for( $i=1; $i<=10; $i++ )
{
$names[] = mysql_fetch_assoc( $result );
$grades[] = mysql_fetch_assoc( $result2 );
}
Then, in our code:
<?php foreach( $names as $key => $name ) {?>
<option name="subj"><?php echo $name['name']; ?></option>
<?php } ?>
and
<?php foreach( $grades as $key => $grade ) {?>
<option name="grad"><?php echo $grade['grade']; ?></option>
<?php } ?>
mysql_fetch_assoc fetch the current row from results and then ‘go’ to next row, so when the first for loop is terminate, the cursor has reached the end of results and - in next for loops, there is nothing to fetch.
Please note:
mysql_ syntax was deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0. Instead, the MySQLi or PDO_MySQL extension should be used.

html dynamic form, pass multiple values through post and insert mysql

i have this database
and this form, dynamically generated from the database
<table border="1" cellspacing="0" cellpadding="6">
<tr bgcolor="#CCCCCC">
<td><strong>product id</strong></td>
<td><strong>product name</strong></td>
<td><strong>product price</strong></td>
<td><strong>quantity</strong></td>
</tr>
<form method="post" action="insert.php">
<?php
$query = $dbh->query('SELECT * FROM products');
$results = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($results as $row)
{
?>
<tr>
<td><?php echo $row['product_id']; ?></td>
<td><?php echo $row['product_name']; ?></td>
<td><?php echo $row['product_price']; ?></td>
<td><input name="quantity" type="text" value="0"></td>
</tr>
</form>
<?php } ?>
</table>
<br>
<input type="submit" value="Add Records">
the quantity in the form is a textbox so i can modify it.
I would like to enter the quantities and the pressing the button to insert the values in the order_products table (including the quantity).
1) How can i pass ALL the quantities and product_id (and the rest) to the next page through post? (until now i know how to pass single values)
2) is there a better way to achieve it?
3) the insert statements should be in the same page or the page where i get the post vars?
db scheme
http://i.stack.imgur.com/oqdOy.jpg
thanks
Rob
1) First, you have to wrap your <input>s inside a single form (move your </form> tag after your <input type="submit" value="Add Records">, the way you have it now closes the <form> tag at first iteration) and submit it via HTTP POST method. Then, based on your schema, the only field you'll have to insert aside of quantity is product_id, which value you can assign inside a hidden field, like:
<?php
echo "<input type='hidden' name='pid_$row['product_id']' value='$row['product_id']'>";
echo $row['product_id'];
?>
Notice that you can still echo the value itself for viewing purposes. You also have to generate your quantity <input> field name property dynamically, otherwise $_POST will overwrite values when their keys are the same.
<?php
echo "<input type='text' name='pid-qtd_$row['product_id']'>";
?>
2) It depends on your development priorities. There are some frameworks out there that might simplify your process. I'd recommend you to keep all your DB queries and connection data within a DB helper class and require it wherever you need it.
3) Since you're using PDO, I assume you have an OOP design, which implies in doing that at your DB helper class or such. The page receiving the HTTP request must require your helper and deal with the $_POST parsing to parameters to its query methods. Don't forget to prepare your statements and parameterizing your queries.
Using hidden element you can post your data to second page. Using counter variable you can add dynamic form element and post it into second page.
<form method="post" action="test2.php">
<table border="1" cellspacing="0" cellpadding="6">
<tr bgcolor="#CCCCCC">
<td><strong>product id</strong></td>
<td><strong>product name</strong></td>
<td><strong>product price</strong></td>
<td><strong>quantity</strong></td>
</tr>
<?php
$query = $con->query('SELECT * FROM product'); //your query goes here
$results = $query->fetchAll(PDO::FETCH_ASSOC);
$i=0; //counter variable
foreach ($results as $row)
{
?>
<tr>
<td>
<?php echo $row['prod_id']; ?>
<input type="hidden" name="prod_id<?php echo $i; ?>" value="<?php echo $row['prod_id']; ?>" />
</td>
<td>
<?php echo $row['prodname']; ?>
<input type="hidden" name="name<?php echo $i; ?>" value="<?php echo $row['prodname']; ?>" />
</td>
<td>
<?php echo $row['price']; ?>
<input type="hidden" name="price<?php echo $i; ?>" value="<?php echo $row['price']; ?>" />
</td>
<td><input name="quantity<?php echo $i; ?>" type="text" value="0"></td>
</tr>
<?php
$i++; //increment counter variable
}
?>
<input type="hidden" name="rows" id="rows" value="<?php echo $i; ?>" />
</table>
<br>
<input type="submit" value="Add Records">
</form>
Your insert page code goes here....
for($i=0;$i<=$_POST['rows'];$i++)
{
$prodid = $_POST['prod_id'.$i];
$pname = $_POST['name'.$i];
$pprice = $_POST['price'.$i];
$con ->exec("insert into product(prod_id,prodname,price)values('$prodid', '$pname','$pprice' )" );
}
I suggest putting the product_id in a hidden form element like this:
<tr>
<input type='hidden' name='product_id' value='<?php echo $row['product_id']; ?>'/>
<td><?php echo $row['product_id']; ?></td>
<td><?php echo $row['product_name']; ?></td>
<td><?php echo $row['product_price']; ?></td>
<td><input name="quantity" type="text" value="0"></td>
</tr>
This will send the product_id with your quantity and you can use it in your insert statement.
The only problem with this is if you have more than one row, there will be more than one hidden element for product_id, etc. Ways to overcome this include differentiating them by appending an incrementing number on the hidden element's name, e.g.:
$i = 1;
foreach ($results as $row)
{
$product_id_name = 'product_id_'.$i;
$quantity_name = 'quantity_'.$i;
... echo your table row, using $product_id_name in the hidden element, and $quantity_name in your text input
$i++;
}
Then in your inserting code you have to look for all the items in $_POST whose keys start with "quantity_", and if they are non-zero, get the integer NNN after the key prefix "quantity_", and get the corresponding product_id_NNN value to do your insert.

Use of select tag to display database in textbox PHP

Im trying to display my database value into the textbox using drop down menu. which is i did and it is displaying. the problem here is that when i choose an item in the drop down list, it goes back to the first choice or last choice, the explanation i got was, my loop is selecting all of the items in the field causing the drop down menu to go back to the first choice when i click on other items. can you help me with the code on how to stop going back to the first choice when i select other options. Here is my whole code. i also use functions.
home.php
<?php
session_start();
include('dbconnect.php');
include('functions.php');
if(isset($_POST['brandname'])){
$id = $_POST['brandname'];
$result = mysql_query("SELECT * FROM tblstore WHERE brandname = '$id'");
while($row = mysql_fetch_array($result)){
$price = $row['price'];
$stocks = $row['stocks'];
}
}
?>
<html>
<body>
<form method="POST" name="">
<table align="center">
<tr>
<td>Choose here:</td>
<td>
<select name = "brandname" onchange = "this.form.submit()">
<?php dropdown() ?>
</select>
</td>
</tr>
<tr>
<td>Quantity:</td>
<td><input type="text" name="qty" id="qty" value="" /></td>
</tr>
<tr>
<td>Price:</td>
<td><input type="text" name="price" id="price" value="<?php echo $price ?>" disabled/></td>
</tr>
<tr>
<td>Stocks:</td>
<td><input type="text" name="stocks" id="stocks" value="<?php echo $stocks ?>" disabled/></td>
</tr>
<tr>
<td>Total:</td>
<td><input type="text" name="total" id="total" disabled/></td>
</tr>
<tr>
<td></td>
</tr>
</table>
</form>
<div align = "center">
hi' <?php echo $userRow['username']; ?> Sign Out
</div>
</body>
</html>
functions.php
<?php
function dropdown(){
$all = mysql_query("SELECT * FROM tblstore");
while($row = mysql_fetch_array($all)){
echo "<option value = '".$row['brandname']."' selected='selected'>" .$row['brandname'] . "</option>";
}
}
feel free to edit the whole code.. im a beginner in php and learning my way to it. thanks
Can add the multiple option if you need to select multiple
<select name="brandname" multiple>
<option value="Select">Select</option>
<?php
do {
?>
<option value="<?php echo $row['brandname']?>"> <?php echo $row['brandname'] ?></option>
<?php
} while ($row = mysql_fetch_assoc($all));
?>
</select>

display the content of table in checkbox form

I have a table called "project_name" in my database called "encrypt_decrypt". The table contains only 1 column called "name" which contains different values of name (ex : p1, p2, p3...). I have to retrieve this values(p1,p2,p3..) from my database and display it on a registration form with each value displaying one below the other having a checkbox with it so that user can select any of the name while registering! How do i do this in php ???
Thanks in advance!
<html>
<body>
<form name="reg" action="code_exec2.php" onsubmit="return validateForm()" method="post">
<table width="274" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td><div align="right" style="white-space:nowrap" >Please select the project:</td>
</tr>
<tr>
<td><div align="right"><input type="checkbox" name="project[]" ></div></td>
<td><?php
session_start();
include('connection2.php');
$row=mysql_query("select * from project_name");
$array= array();
$output = mysql_fetch_assoc($row);
while($output){
$array[] = $output;
}
print_r($array);
?></td>
</tr>
<tr>
<td><div align="right"><input type="checkbox" name="Select all"
value="select all" onclick="toggle(this)"></div></td>
<td>Select all</td>
</tr>
<tr>
<td><div align="right"></div></td>
<td><input name="submit" type="submit" value="Submit" /></td>
</tr>
</table>
</form>
</body>
Try this.
$result=mysql_query("select * from project_name");
$checkboxes=array();
while($r=mysql_fetch_assoc($result)){
$checkboxes[]='<input type="checkbox" name="names[]" value="'.$r['name'].'">'.$r['name'].'<br />';
}
Then echo below wherever you want the checkboxes to appear.
echo implode("\n",$checkboxes);
Assuming, that your connection to db is correct, you need to change the way you display results:
<?php
session_start();
include('connection2.php');
$row=mysql_query("select * from project_name");
$array= array();
while($output = mysql_fetch_assoc($row)){
//now you have row with name, and you need to display each name with new tr:
?>
<tr>
<td><div align="right"><input type="checkbox" name="project[]" value="<?php echo $output['name'] ?>"></div></td>
<td><?php echo $output['name'] ?></td>
</tr>
<?php } // closing while loop
?>
Note that I added value to checkbox - if you want to do something with checked project, you have to know which one it was.
And remember taht mysql_ functions are depreated! You should use PDO or mysqli_ instead
i tried this and i got: any ways thanks for all your help :)
<?php
include('connection.php');
$r=mysql_query("select distinct name from project_name");
$ProdArray=array();
while ($row = mysql_fetch_object($r)) {
array_push($ProdArray,$row->name);
}
foreach($ProdArray as $p) {
echo "<tr>";
echo "<td><div align='right'>";
echo "<input type='checkbox' name='project[]' value=" .$p. " />";
echo "</div></td>";
echo "<td>$p</td>";
echo "</tr>";
}
?>

Categories