I got a dynamic menu that uses bootstrap, but one menu button has about 14 child items. Way too long for a website, so I want to split it in half.
This is the code that I'm trying to replicate:
<ul class="dropdown-menu dropdown-menu-large row" role="menu">
<li class="col-sm-6">
<ul>
<li><a href="life-insurance.html">Life Insurance</a></li>
<li><a href="life-insurance.html">Home Insurance</a></li>
<li><a href="life-insurance.html">Travel Insurance</a></li>
<li><a href="life-insurance.html">Pet Insurance</a></li>
</ul>
</li>
<li class="col-sm-6">
<ul>
<li><a href="life-insurance.html">Boat Insurance</a></li>
<li><a href="life-insurance.html">Auto Insurance</a></li>
<li><a href="life-insurance.html">Bike Insurance</a></li>
<li><a href="life-insurance.html">Business Insurance</a></li>
</ul>
</li>
</ul>
This is what I tried:
$tel = 1;
foreach ( $nmenuccr as $cmenu ) {
// If id matches and category id is 11 (services) split in half
if ( $cmenu['id'] && $cmenu['catid'] == '11' ){
if($tel == 1) {
$hmenu .= '<li class="col-sm-6"><ul>';
}
$hmenu.= '
<li><a href="'.$cmenu['alias'].'.html">'.$cmenu['title'].'</a></li>
';
if(($tel % 7) == 0){
$hmenu .= '</ul></li> <li class="col-sm-6"><ul>';
}
$tel++;
if(($tel % 7) != 0){
$menu .= '</li>';
}
//Else use the normal dropdown layout
}else{
if (strlen($cmenu['title']) > 25){
$shortstrmen = substr($cmenu['title'], 0, 25) . '...';
$hmenu.= '
<li><a href="'.$cmenu['alias'].'.html">'.$shortstrmen.'</a>
';
}else{
$hmenu.= '
<li><a href="'.$cmenu['alias'].'.html">'.$cmenu['title'].'</a>
';
}
}
}
However this returns the following code:
https://jsfiddle.net/sms16v44/
Does anyone see what I am doing wrong?
Keepin it a junky piece of code, you can just quick-fix it this way:
$tel = 0;
/* .. */
// If id matches and category id is 11 (services) split in half
if ( $cmenu['id'] && $cmenu['catid'] == '11' ){
if(++$tel == 1) {
$hmenu .= '<li class="col-sm-6"><ul>';
}
$hmenu.= '<li><a href="'.$cmenu['alias'].'.html">'.$cmenu['title'].'</a></li>';
if(($tel % 7) == 0){
if ($tel == 7) {
$hmenu .= '</ul></li><li class="col-sm-6"><ul>';
} else {
$hmenu .= '</ul></li>';
}
}
//Else use the normal dropdown layout
} // ..
Working example (updated): http://sandbox.onlinephpfunctions.com/code/13fd6974cd66c847747f44a4be9b892aa47e4979
But you should refactor your $nmenuccr
through a function, which will make it an array reflecting the target structure of menu to KISS the view-generating part of code.
Edit: updated operations on $tel
.
Instead of trying to alter your code, I came up with the following. This allows you to automatically create sub menu's out of a menu. I hope it helps out.
It creates it like the following screenshot:
and the other function/way:
<?php
// recreating dummy menu data
function createDummyList() {
$nmenuccr = array();
for($i=0;$i<24;$i++) {
$a = array();
$a['id']=$i;
$a['catid']=$i;
$a['alias']="alias $i";
$a['title']="title $i";
array_push($nmenuccr, $a);
}
return $nmenuccr;
}
/**
* Parse a menu into smaller menu's
* @param type $menu the main menu
* @param type $class html class
* @param type $max_sub_items max items before creating a new submenu
* @param type $submenu (used for recursion)
* @return string
*/
function createMenuList(&$menu, $class, $max_sub_items) {
$out = "<ul class='$class'><li>";
// shift items
$submenu = array();
$i=0;
$loop=0;
while(count($menu) > 0) {
array_push($submenu, array_shift($menu));
$i++;
if ($i == $max_sub_items || count($menu) == 0) {
$out .= createList($submenu, $loop);
$out .= '<li>In between</li>';
$i=0;
$submenu = array();
$loop++;
}
}
$out .= "</li></ul>";
return $out;
}
/**
*
* @param type $list
* @param type $submenu_label
* @return string
*/
function createList(&$list, $loop) {
$out = '<ul>';
foreach($list as $l) {
$out .= '<li><a href="'.$l['alias'].'.html">'.$l['title'].'</a></li>';
}
$out .= '</ul>';
return $out;
}
/**
* Parse a menu into smaller menu's
* @param type $menu the main menu
* @param type $class html class
* @param type $max_sub_items max items before creating a new submenu
* @param type $submenu (used for recursion)
* @return string
*/
function createSubMenuList(&$menu, $class, $max_sub_items, $submenu = 0) {
// create new list
$out = "<ul class='$class'>";
// shift items
for($i=0;$i<$max_sub_items;$i++) {
$item = array_shift($menu);
// add item to list
if (isset($item)) {
$out .= '<li><a href="'.$item['alias'].'.html">'.$item['title'].'</a></li>';
}
}
// check if we're done
if (count($menu) > 0) {
$submenu++;
$out .= "<li class='submenu_$submenu'>";
// create submenu in parent menu
$out .= createSubMenuList($menu, $class, $max_sub_items, $submenu);
$out .= "</li>";
}
$out .= "</ul>";
return $out;
}
// call menu creation function
$list1=createDummyList();
$list2=createDummyList();
echo createSubMenuList($list1, 'hoofdmenu', 7);
echo "<hr />";
echo createMenuList($list2, 'hoofdmenu', 7);
?>
It would be easier to help if you could include the output array as comment too.
However, try this. Change this:
if(($tel % 7) != 0){
$menu .= '</li>';
}
to:
if(($tel % 7) != 0){
$menu .= '</ul></li>';
}
Hopefully it will work
Your check for category ID 11 didn't seem pertinent to your question, so I didn't include that logic in there. Things become a lot simpler when you leave the opening and closing parts outside the loop. Then, you're only outputting your repeated item, and checking for the one case ($tel % 4
) where you put a divider in.
<?php
$nmenuccr = [ // sample data
["alias"=>"life-insurance", "title"=>"Life Insurance"],
["alias"=>"life-insurance", "title"=>"Home Insurance"],
["alias"=>"life-insurance", "title"=>"Travel Insurance"],
["alias"=>"life-insurance", "title"=>"Pet Insurance"],
["alias"=>"life-insurance", "title"=>"Boat Insurance"],
["alias"=>"life-insurance", "title"=>"Auto Insurance"],
["alias"=>"life-insurance", "title"=>"Bike Insurance"],
["alias"=>"life-insurance", "title"=>"Business Insurance"],
];
$hmenu = "<li class=\"col-sm-6\">
\t<ul>
";
foreach ($nmenuccr as $tel=>$cmenu) {
if ($tel % 4 == 0 && $tel > 0) {
$hmenu .= "\t</ul>
</li>
<li class=\"col-sm-6\">
\t<ul>
";
}
$hmenu.= "\t\t<li><a href=\"$cmenu[alias].html\">$cmenu[title]</a></li>
";
}
$hmenu .= "\t</ul>
</li>";
echo $hmenu;
Output:
<li class="col-sm-6">
<ul>
<li><a href="life-insurance.html">Life Insurance</a></li>
<li><a href="life-insurance.html">Home Insurance</a></li>
<li><a href="life-insurance.html">Travel Insurance</a></li>
<li><a href="life-insurance.html">Pet Insurance</a></li>
</ul>
</li>
<li class="col-sm-6">
<ul>
<li><a href="life-insurance.html">Boat Insurance</a></li>
<li><a href="life-insurance.html">Auto Insurance</a></li>
<li><a href="life-insurance.html">Bike Insurance</a></li>
<li><a href="life-insurance.html">Business Insurance</a></li>
</ul>
</li>
Try this for any length of menu.....
<ul class="dropdown-menu dropdown-menu-large row" role="menu">
<?php
$counter = 1;
foreach ($nmenuccr as $cmenu ) {
if($counter == 1){
echo '<li class="col-sm-6"><ul>';
}//.... end of if() .....//
echo '<li><a href="'.$cmenu['alias'].'.html">'.$cmenu['title'].'</a></li>';
$counter ++;
if($counter == 5){
echo "</ul></li>";
$counter = 1;
}//.... end of if() .....//
}//.... end of foreach() .....//
?>
</ul>