I'm hoping the Daniweb community can help where other forums have been unable to!
I am attempting to have my code count how many top level menu items there are and then determine what position each menu item is in. So, if it is the first, it will append the class of that item to "first" and if it is the last, it will append the class to "last."
I did the same thing with other variables and it worked. For example, I have the code set to append the class to "parent" if there are subitems and also "active" if it is the current link. However, I am running into difficulty with first/last. I've been through several attempts. My first incarnation was:
<?php
/*
Class: MenuDefault
Menu base class
*/
class MenuDefault extends Menu {
/*
Function: process
Returns:
Object
*/
public function process($module, $element) {
self::_process($module, $element->first('ul:first'));
return $element;
}
/*
Function: _process
Returns:
Void
*/
protected static function _process($module, $element, $level = 0) {
if ($level == 0) {
$element->attr('class', 'menu '.$module->menu_style);
} else {
$element->addClass('level'.($level + 1));
}
foreach ($element->children('li') as $li) {
// is active ?
if ($active = $li->attr('data-menu-active')) {
$active = $active == 2 ? ' active current' : ' active';
}
// is parent ?
$ul = $li->children('ul');
$parent = $ul->length ? ' parent' : null;
// is first or last ? -- PROBLEM AREA
$lis = $element->children("li");
for($forl=0,$imax=$lis;
$forl<$imax;$forl++){
if ($forl==0) $position_n = 'first';
elseif ($forl==$imax-1) $position_n = 'last';
else $position_n = null;}
// set class in li
$li->attr('class', sprintf('level%d item%s '. $position_n .$parent.$active, $level + 1, $li->attr('data-id')));
// set class in a/span
foreach ($li->children('a,span') as $child) {
// get title
$title = $child->first('span:first');
// set subtile
$subtitle = $title ? explode('||', $title->text()) : array();
if (count($subtitle) == 2) {
$li->addClass('hassubtitle');
$title->html(sprintf('<span class="title">%s</span><span class="subtitle">%s</span>', trim($subtitle[0]), trim($subtitle[1])));
}
// set image
if ($image = $li->attr('data-menu-image')) {
$title->prepend(sprintf('<span class="icon" style="background-image: url(\'%s\');"> </span>', $image));
}
$child->addClass(sprintf('level%d'.$parent.$active, $level + 1));
}
// process submenu
if ($ul->length) {
self::_process($module, $ul->item(0), $level + 1);
}
}
}
}
However, that generated "first" for every menu item. See below for example:
<ul class="menu menu-dropdown">
<li class="level1 item24 first">...Subcode...</li>
<li class="level1 item22 first parent">...Subcode...</li>
<li class="level1 item23 first active current">...Subcode...</li>
<li class="level1 item20 first">...Subcode...</li>
<li class="level1 item19 first">...Subcode...</li>
</ul>
What I wanted was:
<ul class="menu menu-dropdown">
<li class="level1 item24 first">...Subcode...</li>
<li class="level1 item22 parent">...Subcode...</li>
<li class="level1 item23 active current">...Subcode...</li>
<li class="level1 item20">...Subcode...</li>
<li class="level1 item19 last">...Subcode...</li>
</ul>
Then in another forum, it was suggested to me that " Your basic logic for determining first and last is correct, but you should not add a new loop to do it; instead you need to make it part of the loop that is already looping over the <li>'s (ie: the foreach loop at the top of the snippet I posted). Because of the use of the foreach statement, you need to do a little extra work in order to obtain numerically useful index values.
// is first or last ? -- PROBLEM AREA
$children_elements = array_values($element->children('li')); [/U]
$last_child_index = count($children_elements)-1;
foreach($children_elements as $child_index => $li) {
if ($forl==0) $position_n = 'first';
elseif ($forl==$imax-1) $position_n = 'last';
else $position_n = null;}
That brought a bunch of errors:
*Warning: array_values() [
function.array-values
]: The argument should be an array in ... on line 59
Warning: Invalid argument supplied for foreach() in ... on line 61
Warning: array_values() [
function.array-values
]: The argument should be an array in ... on line 59
Warning: Invalid argument supplied for foreach() in ... on line 61
Warning: array_values() [
function.array-values
]: The argument should be an array in ... on line 59
Warning: Invalid argument supplied for foreach() in ... on line 61
Warning: array_values() [
function.array-values
]: The argument should be an array in ... on line 59
Warning: Invalid argument supplied for foreach() in ... on line 61
Warning: array_values() [
function.array-values
]: The argument should be an array in ... on line 59
Warning: Invalid argument supplied for foreach() in ... on line 61
Warning: array_values() [
function.array-values
]: The argument should be an array in ... on line 59
Warning: Invalid argument supplied for foreach() in ... on line 61
Warning: array_values() [
function.array-values
]: The argument should be an array in ... on line 59*
Line 59 being $children_elements = array_value($element->children('li'));
So it seemed like $children_elements was either empty or not an array so I tested with this:
if(empty($children_elements)) {
echo hi;
}
Hi was generated. So it seems empty.
Sorry if this was long but I had no idea how to explain quicker. Please help. I'm stumped and if I can't get this working, a large portion of my time will go to waste as I'll have to scrap the theme design completely.
Thanks in advance.