I'm building a menu and i need to have the parents keys on my generated sub items
The function looks like this:
function get_menu($tagmenu){
$menu="";
$count=0;
foreach ($tagmenu as $key => $value) {
$is_active=false;
$class="";
if(isset($_GET["tagsearch"])){
if($key == $_GET["tagsearch"]){
$is_aktive=true;
};
};
$menu.= "<ul>";
$sub="";
if(is_array($value)){
if (count($value)>0) {
$sub.= "<div class='submenu'>";
$sub.=get_menu($value);
$sub.= "</div>";
}
}
$li= "<li class='menuitem'><a href='?tagsearch=".$key."'>".$key."</a>";
if (strpos($sub,"'menuitem active'")!==false || $is_active ) {
$li=str_replace("'menuitem'", "'menuitem active'", $li);
}
$menu.=$li.$sub;
$menu.= "</li>";
$menu.= "</ul>";
}
return $menu;
}
And this is the array;
Array(
[fotografie] => Array(
[schwarzweiss] => Array(
[street] => Array()
)
)
)
Is it possible with this stucture to add all keys of the parent array to the link?
At the end it should look like
Yes, it is. You need to add second parameter to recursive function, in which you pass current string.
function get_menu($tagmenu, $shortcut = array())
{
$menu="";
$count=0;
foreach ($tagmenu as $key => $value)
{
$shortcut[] = $key;
$is_active=false;
$class="";
if(isset($_GET["tagsearch"]))
{
if($key == $_GET["tagsearch"])
{
$is_aktive=true;
};
};
$menu.= "<ul>";
$sub="";
if(is_array($value))
{
if (count($value)>0)
{
$sub.= "<div class='submenu'>";
$sub.=get_menu($value, $shortcut);
$sub.= "</div>";
}
}
$li= "<li class='menuitem'>".$key."";
if (strpos($sub,"'menuitem active'")!==false || $is_active )
{
$li=str_replace("'menuitem'", "'menuitem active'", $li);
}
$menu.=$li.$sub;
$menu.= "</li>";
$menu.= "</ul>";
}
return $menu;
}
echo get_menu(
array(
'fotografie' => array(
'schwarzweiss' => array(
'street' => array()
)
)
)
);
You have had already href attribute on the link, so I've used class attr to show you the example.
Demo: http://sandbox.onlinephpfunctions.com/code/184eaa428de75511eda1ffee8f8ad08b82a03919
Related
I have a php recursive function as shown in the below:
function displayDropdown(&$catList, $parent, $current=[], $level=0) {
if ($parent==0) {
foreach ($catList[$parent] as $catID=>$nm) {
displayDropdown($catList, $catID, $current);
}
}
else {
foreach ($catList[$parent] as $catID=>$nm) {
$sel = (in_array($catID, $current)) ? " selected = 'selected'" : '';
echo "<option value='$catID' $sel>$nm</option>\n";
if (isset($catList[$catID])) {
displayDropdown($catList, $catID, $current, $level+1);
}
}
}
}
This function is working for me. but I want to get output from a variable instead of echoing inside the function. Actually I need to return option list from the funciton.
This is how I tried it, but it doesn't work for me.
function displayDropdown(&$catList, $parent, $current=[], $level=0) {
$optionsHTML = '';
if ($parent==0) {
foreach ($catList[$parent] as $catID=>$nm) {
displayDropdown($catList, $catID, $current);
}
}
else {
foreach ($catList[$parent] as $catID=>$nm) {
$sel = (in_array($catID, $current)) ? " selected = 'selected'" : '';
$optionsHTML .= "<option value='$catID' $sel>$nm</option>\n";
if (isset($catList[$catID])) {
displayDropdown($catList, $catID, $current, $level+1);
}
}
}
//return displayDropdown($optionsHTML);
return $optionsHTML;
}
UPDATE:
This is how I call this function.
displayDropdown($catList, 0, [$cid])
This is how I create $catList array inside while loop with the result of a query.
while ($stmt->fetch()) {
$catList[$parent][$catID] = $name;
}
Array structure as below:
Array
(
[1] => Array
(
[2] => Uncategorized
[3] => SHOW ITEMS
[4] => HORN
[5] => SWITCH
[6] => LIGHT
)
[0] => Array
(
[1] => Products
)
)
1
Hope somebody may help me out.
you need also like this $optionsHTML .= displayDropdown(...)
function displayDropdown(&$catList, $parent, $current=[], $level=0) {
$optionsHTML = '';
if ($parent==0) {
foreach ($catList[$parent] as $catID=>$nm) {
$optionsHTML .= displayDropdown($catList, $catID, $current);
}
}
else {
foreach ($catList[$parent] as $catID=>$nm) {
$sel = (in_array($catID, $current)) ? " selected = 'selected'" : '';
$optionsHTML .= "<option value='$catID' $sel>$nm</option>\n";
if (isset($catList[$catID])) {
$optionsHTML .= displayDropdown($catList, $catID, $current, $level+1);
}
}
}
return $optionsHTML;
}
Trying to get to grips with PHP, but I have absolutely no idea how to do this.
I want to take this array:
$things = array('vehicle' => array('car' => array('hatchback', 'saloon'),'van','lorry'),
'person' => array('male', 'female'),
'matter' => array('solid', 'liquid', 'gas'),
);
and turn it into this into something like this in HTML:
Vehicle
Car
Hatchback
Saloon
Van
Lorry
Person
Male
Female
Matter
Solid
Liquid
Gas
Tried a number of solutions from searching, but cannot get anything to work at all.
What you are looking for is called Recursion. Below is a recursive function that calls itself if the value of the array key is also an array.
function printArrayList($array)
{
echo "<ul>";
foreach($array as $k => $v) {
if (is_array($v)) {
echo "<li>" . $k . "</li>";
printArrayList($v);
continue;
}
echo "<li>" . $v . "</li>";
}
echo "</ul>";
}
Try something like:
<?php
function ToUl($input){
echo "<ul>";
$oldvalue = null;
foreach($input as $value){
if($oldvalue != null && !is_array($value))
echo "</li>";
if(is_array($value)){
ToUl($value);
}else
echo "<li>" + $value;
$oldvalue = $value;
}
if($oldvalue != null)
echo "</li>";
echo "</ul>";
}
?>
Code source: Multidimensional array to HTML unordered list
Trying to construct a navigation using multi-dimensional arrays and recursion. I have the following code:
First I run <?php $title = 'pagename'; ?> on each individual page beneath doctype (for active class detection)
ARRAY:
<?php
$nav_array = array ('Home' => 'index.php',
'About' => array ( 'about.php', array (
'Michael' => array( 'michael.php', array (
'Blog' => 'blog.php',
'Portfolio' => 'portfolio.php')),
'Aaron' => 'aaron.php' ,
'Kenny' => 'kenny.php',
'David'=> 'david.php')),
'Services' => array ( 'services.php', array (
'Get Noticed' => 'getnoticed.php',
'Hosting' => 'hosting.php')),
'Clients' => 'clients.php',
'Contact Us' => 'contact.php'
);
$base = basename($_SERVER['PHP_SELF']);
?>
FOREACH: (generates nav)
<ul>
<?php
foreach ($nav_array as $k => $v) {
echo buildLinks ($k, $v, $base);
}
?>
</ul>
buildLinks:
<?php // Building the links
function buildLinks ($label_name, $file_name, $active_class) {
if ($label_name == $title) {
$theLink = "<li><a class=\"selected\" href=\"$file_name\">$label_name</a></li>\n";
} else {
$theLink = "<li>$label_name</li>\n";
}
return $theLink;
}
?>
Result: http://khill.mhostiuckproductions.com/siteLSSBoilerPlate/arraytest.php
The sub menu's will appear on the hover of parent element using CSS. I need to be able to fall through multiple sub-levels without modifying anything but the array.
How do I make my foreach fall through the rest of the array recursively?
(Note: that I have to have the ability to apply a class of active to current pages, and a class of arrow to parent elements that have a sub-menu present.)
No matter what data structure you use to build your navigation, you'll need to make your function recursive, here's a quick and dirty way:
echo "<ul>";
foreach ($nav_array as $nav_title => $nav_data) {
echo buildLinks($nav_title, $nav_data, $base, $title);
}
echo "</ul>";
/* NOTE that we pass $title to the function */
function buildLinks ($label_name, $file_name, $active_class, $title) {
$theLink = '';
/* this is dirty code, you should reconsider your data structure */
$navigation_list = false;
if (is_array($file_name)) {
$navigation_list = $file_name[1];
$file_name = $file_name[0];
}
if ($active_class == $title) {
$theLink = "<li><a class=\"selected\" href=\"$file_name\">$label_name</a></li>\n";
} else {
$theLink = "<li>$label_name</li>\n";
}
if ($navigation_list) {
$theLink .= "<ul>";
foreach ($navigation_list as $nav_title => $nav_data) {
$theLink .= buildLinks($nav_title, $nav_data, $active_class, $title);
}
$theLink .= "</ul>";
}
return $theLink;
}
Not a clean solution in anyway, if I were you I'd change the data structure to be an easier one to handle.
I think this is a very bad way. I recommend to save your menu elements as XML or JSON and use parsers. It will facilitate your work.
I have the array below which I would like to output in a specific HTML list format.
My PHP array is as follow:
Array
(
[MAIN] => Master Product
[ID1] => Array
(
[0] => Product 1
)
[ID2] => Array
(
[0] => Product 2
[ID3] => Array
(
[0] => Product 3
)
[ID4] => Array
(
[0] => Product 4
)
)
)
The HTML list format I am looking for is as follows.
<ul id="treeview">
<li>Master Product
<ul>
<li>Product 1</li>
<li>Product 2
<ul>
<li>Product 3</li>
<li>Product 4</li>
</ul>
</li>
</ul>
</li>
</ul>
Any help would be appreciated.
Try this on for size:
function recurseTree($var){
$out = '<li>';
foreach($var as $v){
if(is_array($v)){
$out .= '<ul>'.recurseTree($v).'</ul>';
}else{
$out .= $v;
}
}
return $out.'</li>';
}
echo '<ul>'.recurseTree($yourDataArrayHere).'</ul>';
$data = array(); // your data
function toUL($data=false, $flatten=false){
$response = '<ul>';
if(false !== $data) {
foreach($data as $key=>$val) {
$response.= '<li>';
if(!is_array($val)) {
$response.= $val;
} else {
if(!$flatten){
$response.= toUL($val);
} else {
// pulls the sub array into the current list context
$response.= substr($response,0,strlen($response)-5) . toUL($val);
}
}
$response.= '</li>';
}
}
$response.= '</ul>';
return $response;
}
// Test #1 -- named values
echo toUL(array('a'=>'b','c'=>'d','e'=>array('f'=>'g')));
// Result #1
b
d
g
// Test #2 -- value lists
echo toUL(array('a','b','c',array('d','e','f')));
// Result #2
a
b
c
d
e
f
Inspired from this answer but where leaves are surounded by <li>
function recurseTree($var)
{
$out = '';
foreach ($var as $v) {
if (is_array($v)) {
$out .= '<ul>'.recurseTree($v).'</ul>';
} else {
$out .= '<li>'.$v.'</li>';
}
}
return $out;
}
And if you have associative array you can try this function:
function recurseTree($var)
{
$out = '';
foreach($var as $k => $v){
if (is_array($v)) {
$out .= '<dl>'.self::recurseTree($v).'</dl>';
} else {
$out .= '<dt>'.$k.'</dt>'.'<dd>'.$v.'</dd>';
}
}
return $out;
}
I'm not so strong with arrays but I need to determine how to count the number of parents a child array has in order to determine the indenting to display it as an option in a SELECT.
So, if I have this array:
array(
'World'=>array(
'North America'=>array(
'Canada'=>array(
'City'=>'Toronto'
)
)
)
);
How would I go about determining how many parents 'City' has in order to translate that into the number of spaces I want to use as an indent?
Thanks for any help.
EDIT: Let's see if I can explain myself better:
I have this code I'm using to build the OPTIONS list for a SELECT:
function toOptions($array) {
foreach ($array as $key=>$value) {
$html .= "<option value=\"" . $key . "\" >";
$html .= $value['title'];
$html .= "</option>";
if (array_key_exists('children', $value)) {
$html .= toOptions($value['children']);
}
}
return $html;
}
print toOptions($list);
So, I'm trying to determine how to get the number of parents in order to add spaces before the title in this line:
$html .= $value['title'];
Like:
$html .= " " . $value['title'];
But, I'm not sure how to figure out how many spaces to add.
Hopefully this is more clear.
Thanks for any help so far.
$x = array(
'World'=>array(
'North America'=>array(
'Canada'=>array(
'City'=>'Toronto'
)
)
)
);
// This function do something with the key you've found in the array
function visit($name, $depth)
{
echo $name . ' has ' . $depth . ' parents.';
}
// This function visits all the contents aff $array
function find_recursive($array, $depth = 0)
{
if (is_array($array)) {
foreach ($array as $k => $value) {
visit($k, $depth + 1);
find_recursive($array, $depth + 1);
}
}
}
For visiting:
find_recursive($x);
Well. Off the top what you are dealing with is a multi dimensional array.
You could run a count w/ foreach on each level of the array, and use the count number returned +1 for each level the foreach loops through.
I'm not sure if this answers your question, but I am trying to see exactly what it is you are trying to achieve.
As you are already using a recursive function to display that data, you can just extend your function. There is no need to traverse the array more often than one time:
function getWhitespaces($count) {
$result = '';
while($count--) {
$result .= '$nbsp;';
}
return $result;
}
function toOptions($array, $level=0) {
foreach ($array as $key=>$value) {
$html .= "<option value=\"" . $key . "\" >";
$html .= getWhitespaces($level) + $value['title'];
$html .= "</option>";
if (array_key_exists('children', $value)) {
$html .= toOptions($value['children'], $level + 1);
}
}
return $html;
}
print toOptions($list);
Try the following.. Your solution screams for recursion in my mind. Its a bit ugly but it seems to work
$totraverse = array(
'Moon' => array(
'Dark Side' => "Death Valley"
),
'Halley Commet' => "Solar System",
'World' => array(
'North America' => array(
'Canada' => array(
'City' => 'Toronto'
)
), 'South America' => array(
'Argentina' => array(
'City' => 'Toronto'
)
)
)
);
function traverse($totraverse_, $path="", $count=0) {
global $array;
// echo count($totraverse_) . " count\n";
if (!is_array($totraverse_)) {
echo "returning $path and $key\n";
return array($path, $count);
} else {
foreach ($totraverse_ as $key => $val) {
echo "assting $path and $key\n";
$result = traverse($val, $path . "/" . $key, $count + 1);
if($result){
$array[]=$result;
}
}
}
echo false;
}
$array = array();
traverse($totraverse);
foreach($array as $item){
echo "{$item[0]}--->{$item[1]}\n";
}