while loop inside foreach - php

i'm trying to create a hierarchical select menu with multiple selection.
i select the categories and i store them in an array comma separated.etc(1,5,10). everything works fine except that each time i select another value the while loop echo's duplicate values on drop down list.
Is there any other way i could do this without having duplicate values?
$tree = '<select name="an_det_category[]" class="an_det_category" multiple>';
$var=explode(",",$row_detail_rec['an_det_category']);
print_r(array_values($var))
foreach ($var as $var1){
$result10 = mysql_query("select * from announcment_categories where an_parendid=0 and an_langid=".$_GET['langid']."");
while ($row= mysql_fetch_array($result10)){
if ($row['an_location']==$var1){$ka='"selected="selected"">';
}else{
$ka='">';
}
$tree .= '<option value="'.$row['an_location'].$ka;
$tree .= $row['an_name'];
$tree .= '</option>';
$tree .= getLowerRanks($row['an_location'],1,$var1);
}
}
$tree .= '</select>';

Don't do a for loop. Just loop through the database results, and use in_array to test whether the current category is in one of the selected categories.
while ($row = mysql_fetch_array($result10)) {
if (in_array($row['an_location'], $var)) {
$ka = 'selected="selected"';
} else {
$ka = '';
}
$tree .= "<option value='{$row['an_location']}' $ka>";
$tree .= $row['an_name'];
$tree .= '</option>';
// I'm not sure what this is, or how to reproduce it in this version
// $tree .= getLowerRanks($row['an_location'], 1, $var1);
}

Related

How to keep the selected data in the select combo after the query?

I have this function that allows me to select a category (from a select combo) to associate with a product while I'm creating it. It works well but when I modify the product, I would like that the category assigned during creation, remain selected and visible at the beginning of the combo.
I suppose that i have to change something into the function when i update the product.
Any suggestion?
Thanks
Function:
function CategoryTree(&$output=null, $cat_parent_id=0, $indent=null){
global $con;
try {
// prepare select query
$query = "SELECT * FROM category WHERE cat_parent_id=:parentid AND cat_lang = '{$_SESSION['lang']}'";
$stmt = $con->prepare($query);
// this is the first question mark
$stmt->bindParam(2, $id);
// execute our query
$stmt->execute(array( 'parentid' => $cat_parent_id));
while($c = $stmt->fetch(PDO::FETCH_ASSOC)){
$disable= "";
if($cat_parent_id==0 ){
$disable= 'disabled="disabled" style="color:black;font-weight:bold;font-style:oblique"';
}
$output .= '<option '. $disable.' value=' . $c['cat_id'] . '>' . $indent . $c['cat_name'] . "</option>\n";
if($c['cat_id'] != $cat_parent_id){
CategoryTree($output, $c['cat_id'], $indent . " ");
}
}
// return the list of categories
return $output;
}
// show error
catch(PDOException $exception){
die('ERROR: ' . $exception->getMessage());
}
}
HTML:
<select name="category" class="form-control" id="category" required />
<option value="">Select a category</option>
<?php
echo CategoryTree();
?>
</select>
I think what you need (if I have understood your problem correctly) is to make use of the 'selected' attribute of the option you can say which option is marked as selected when the page loads by saying
'<option '. $disable.' value=' . $c['cat_id'] . ' selected>'
(https://www.w3schools.com/tags/att_option_selected.asp)
You can then use the value in the $_POST['category'] when the form is submitted and compare it to the category value ($c['cat_id']) in the loop to decide which element is selected.
When the form is submitted and the page reloaded then the last selected value will remain selected.
Forgive me if I haven't understood your question properly, but I THINK this is what you mean
Ok, I'll rewrite my question here, since I can't explain myself. I have to rewrite this code from the old mysql_ to PDO.
Perhaps by writing code directly it is better understood.
The main function:
/*
Generate combo box options containing the categories we have.
if $catId is set then that category is selected
*/
function buildCategoryOptions($catId = 0)
{
$sql = "SELECT cat_id, cat_parent_id, cat_name
FROM tbl_category WHERE cat_lang = '{$_SESSION['lang']}'
ORDER BY cat_id";
$result = dbQuery($sql);
$categories = array();
while($row = dbFetchArray($result)) {
list($id, $parentId, $name) = $row;
if ($parentId == 0) {
// we create a new array for each top level categories
$categories[$id] = array('name' => $name, 'children' => array());
} else {
// the child categories are put int the parent category's array
$categories[$parentId]['children'][] = array('id' => $id, 'name' => $name);
}
}
// build combo box options
$list = '';
foreach ($categories as $key => $value) {
$name = $value['name'];
$children = $value['children'];
$list .= "<optgroup label=\"$name\">";
foreach ($children as $child) {
$list .= "<option value=\"{$child['id']}\"";
if ($child['id'] == $catId) {
$list.= " selected";
}
$list .= ">{$child['name']}</option>\r\n";
}
$list .= "</optgroup>";
}
return $list;
}
Create.php:
$catId = (isset($_GET['catId']) && $_GET['catId'] > 0) ? $_GET['catId'] : 0;
$categoryList = buildCategoryOptions($catId);
and then
<select name="cboCategory" id="cboCategory" class="width-50">
<option value="" selected>-- Choose Category --</option>
<?php
echo $categoryList;
?>
</select>
update.php
// get category list
$sql = "SELECT cat_id, cat_parent_id, cat_name
FROM tbl_category
ORDER BY cat_id";
$result = dbQuery($sql) or die('Cannot get Product. ' . mysql_error());
$categories = array();
while($row = dbFetchArray($result)) {
list($id, $parentId, $name) = $row;
if ($parentId == 0) {
$categories[$id] = array('name' => $name, 'children' => array());
} else {
$categories[$parentId]['children'][] = array('id' => $id, 'name' => $name);
}
}
// build combo box options
$list = '';
foreach ($categories as $key => $value) {
$name = $value['name'];
$children = $value['children'];
$list .= "<optgroup label=\"$name\">";
foreach ($children as $child) {
$list .= "<option value=\"{$child['id']}\"";
if ($child['id'] == $cat_id) {
$list .= " selected";
}
$list .= ">{$child['name']}</option>";
}
$list .= "</optgroup>";
}
?>
and then
<select name="cboCategory" id="cboCategory" class="box">
<option value="" selected>-- Choose Category --</option>
<?php
echo $list;
?>
</select>
The functions are:
dbQuery() = global $dbConn;
$result = mysqli_query($dbConn, $sql) or die(mysqli_error($dbConn));
return $result;
dbFetchArray = function dbFetchArray($result, $resultType = MYSQL_NUM) {
return mysqli_fetch_array($result, $resultType);
}

How to display multilevel one to many relationship tree

How to loop all records and display all the respective children using HTML <ul></ul>? I tried using PHP Do While but stuck at only 1 level.
MySQL (select * from user)
Desired output
Tree View
List View
The easy was is to do that with the help of array. Hope it helps.
$data = array();
foreach ($result as $item) {
$key = $item['name']; // or $item['info_id']
if (!isset($data[$key])) {
$data[$key] = array();
}
$data[$key][] = $item;
}
You can use this code:
$aResults; // it is your mysql result (array)
$resultSorted = array();
$resultSorted = recursiveList($aResults, '');
function recursiveList(&$aResults, $iKey)
{
$aChilds = '<ul>';
foreach ($aResults as $iLoopKey => $aResult) {
if ($aResult['parent'] == $iKey) {
unset($aResults[$iLoopKey]);
$aChilds .= '<li>' . $aResult['name'] . '</li>';
$aChilds .= recursiveList($aResults, $aResult['name']);
}
}
return $aChilds . '</ul>';
}
// Output example
echo '<pre>';
print_r($resultSorted);
As a result, I recived:
Also you'd better use 'parent_id' instead 'parent' in yours tables.

PHP - Update HTML Select list to show current value

I'm working on a simple HTML form that will include a drop down list for the selected Salesperson. The list is coming from a database and is in an array that is stored in a variable $ids and looks like this:
Array ( [John Jones] => JJ [Sally Smith] => SS [Victor Howards] => VH [Barnie Kemp] => BK )
Here's how the select list is currently constructed:
<?php
$output = "";
$selected = false;
foreach ($ids as $id => $value) {
$output .= "<option value=\"$value\"";
if ($id == $record->getField('initials')) {
$selected = true;
$output .= " selected";
$selectedID = $record->getField("id");
}
$output .= ">$id</option>";
}
if (!$selected) {
$chosen = $record->getField("initials");
$output = "<option value=\"$chosen\" selected>$chosen</option>$output";
}
echo $output;
?>
I'm trying to update the select list to show the current value for this field as the selected option. I have the name/value stored in these variables:
$initials
$name
So if $initials = 'SS' I would like Sally Smith to be the selected value in the list.
Try to use as simple as follow
<?php
$output = "";
foreach ($ids as $id => $value) {
$selected = "";
if ($id == $record->getField('initials')) {
$selected = "selected";
}
$output .= "<option value='$value' $selected>$id</option>";
}
echo $output;
?>
Do not make your code complex.. do it like this one:
$value=$record->getField('initials');
foreach ($ids as $id => $valueData) {
if($id==$value)
echo "<option value='".$id."' selected='selected' >$id</option>";
else
echo "<option value='".$id."'>$id</option>";
}

create a drop down list from a multi dimensional array

I have a multi dimensional array created from a mysql query. with each index holding an array containing customer information. I want to create a drop down list from this with the value being customer ID and the text being customer name but I don't know how to access the arrays inside the main array.
I have the following function which I used to create other drop down lists from single arrays but when I try to use it with a multi dimensional array all it returns is the index numbers. (i get a list of 0, 1, 2, 3)
function createDropDown($name = '', $options = array()) {
$dropDown = '<select name="'.$name.'">';
foreach ($options as $option => $value) {
$dropDown .= '<option value='.$value.'>'.$option.'</option>';
}
$dropDown .= '</select>';
return $dropDown;
}
EDIT
its 2 dimensional, an array holding arrays of customer details.
my query is ran on a different page so I save the results into a session variable with this.
$searchtext = $_POST['searchDB'];
$query = "SELECT * FROM customer WHERE First_Name LIKE '%$searchtext%'";
$data = mysql_query($query) or die(mysql_error());
$Customers = array();
while($row = mysql_fetch_assoc($data)){
$Customers[] = $row;
}
$anymatches = mysql_num_rows($data);
if ($anymatches != 0) {
$_SESSION['names']=$Customers;
}
print_r($array) gives me the following:
Array ( [0] => Array ( [ID] => 25 [First_Name] => Maggy [Surname] => barrows [Company_Name] => squiggle [Telephone] => 12121212 [Alt_Telephone] => 4343434 [notes] => ) )
Like that:
function createDropDown($name = '', $options = array()) {
$dropDown = '<select name="'.$name.'">';
foreach ($options as $option => $value) {
$dropDown .= '<option value='.$value['ID'].'>'.$value['First_Name'].' '.$value['Surname'].'</option>';
}
$dropDown .= '</select>';
return $dropDown;
}
function createDropDown($name = '', $options = array()) {
$dropDown = '<select name="'.$name.'">';
foreach ($options as $option ) {
$dropDown .= '<option value="'.$option["name"].'">'.$option["name"].'</option>';
}
$dropDown .= '</select>';
return $dropDown;
}
Try something like the above replaceing "name" with the field name of what you want for the value and label
In your foreach, the $option => $value might be easier to understand as $key => $option. The $key is the index of the option, and the $option is the value you set.
If $value is a single-dimension array, you can just access its values by their indices ($option['id'] and $option['name'], for example).
If your options are single-dimensional, you can just access them with something like:
foreach($options as $option) {
$dropDown .= '<option value="' . $option['id'] . '">' . $option['name'] . '</option>';
}
Since you are dealing with a 2 dimensional array, or in other words one array nested within another you have to run another foreach loop like this:
function createDropDown($name = '', $options = array()) {
$dropDown = '<select name="'.$name.'">';
foreach ($options as $customer) {
foreach($customer as $info) {
$dropDown .= '<option value='.$info["id"].'>'.$info["name"].'</option>';
}
}
$dropDown .= '</select>';
return $html;
}
I'm not sure what your actual indexes within your nested array are, so you may have to tweak the above code a little bit. Good luck!

how to change a while sql query loop into an array loop

i record number of queries of my website and in page the below script runs , 40 extra queries added to page .
how can I change this sql connection into a propper and light one
function tree_set($index)
{
//global $menu; Remove this.
$q=mysql_query("select id,name,parent from cats where parent='$index'");
if(mysql_num_rows($q) === 0)
{
return;
}
// User $tree instead of the $menu global as this way there shouldn't be any data duplication
$tree = $index > 0 ? '<ul>' : ''; // If we are on index 0 then we don't need the enclosing ul
while($arr=mysql_fetch_assoc($q))
{
$subFileCount=mysql_query("select id,name,parent from cats where parent='{$arr['id']}'");
if(mysql_num_rows($subFileCount) > 0)
{
$class = 'folder';
}
else
{
$class = 'file';
}
$tree .= '<li>';
$tree .= '<span class="'.$class.'">'.$arr['name'].'</span>';
$tree .=tree_set("".$arr['id']."");
$tree .= '</li>'."\n";
}
$tree .= $index > 0 ? '</ul>' : ''; // If we are on index 0 then we don't need the enclosing ul
return $tree;
}
//variable $menu must be defined before the function call
$menu = '....<ul id="browser" class="filetree">'."\n";
$menu .= tree_set(0);
$menu .= '</ul>';
echo $menu;
i heard , this can be done by changing it into an array , but i don't know how to do so
thanks in advance
Try this (untested code):
function tree_set($index)
{
//global $menu; Remove this.
$q=mysql_query("select id,name,parent from cats where parent='$index'");
if(mysql_num_rows($q) === 0)
return;
$cats = array();
$cat_ids = array();
while($arr=mysql_fetch_assoc($q))
{
$id = intval($arr['id']);
$cats[$id] = $arr;
}
$subFilesCountQuery="select parent,count(*) as subFileCount from cats where parent=".
join(" OR parent=",array_keys($cats))." GROUP BY parent";
$subFileCountResult=mysql_query($subFilesCountQuery);
while($arr=mysql_fetch_assoc($subFileCountResult))
{
$id = intval($arr['parent']);
$cats[$id]['subFileCount'] = $arr['subFileCount'];
}
// If we are on index 0 then we don't need the enclosing ul
$tree = $index > 0 ? '<ul>' : '';
foreach($cats as $id => $cat)
{
if($cat['subFileCount'] > 0)
$class = 'folder';
else
$class = 'file';
$tree .= '<li>';
$tree .= '<span class="'.$class.'">'.$arr['name'].'</span>';
$tree .=tree_set("".$arr['id']."");
$tree .= '</li>'."\n";
}
$tree .= $index > 0 ? '</ul>' : '';
What I'm doing is two queries: One to fetch all the categories (your original first query) followed by a second query to fetch all the subcategory counts in one fell swoop. I am also storing all categories in an array which you can loop through, rather than displaying as you fetch from the database.
It can be done by copying your data out into an array, and then using that copy: i.e.
while($arr=mysql_fetch_assoc($q))
{
$results[] = $arr;
}
later on, you then do whatever op you want on $results
The main problem with your code is you are mixing your display logic all in with your SQL query.
Select whole tree in single query, like "select id,name,parent from cats". Iterate on result, build array in PHP that will represent your tree, then draw HTML using array as source

Categories