CSS Dropdown Menu

Post custom hacks and enhancements for phpwcms here only. Maybe some of these things will be included in official release later.
Paal
Posts: 204
Joined: Wed 6. Oct 2004, 19:54
Location: Budapest, Hungary
Contact:

Post by Paal »

Paal wrote: Results:

Code: Select all

<ul>
  <li><a href="index.php?id=11,0,0,1,0,0">Menu 1</a></li>
    <ul>
      <li><a class="cell_active" href="index.php?id=12,0,0,1,0,0">SubMenu 1/1</a></li>
        <ul>
          <li><a href="index.php?id=20,0,0,1,0,0">SubSub 1/1/1</a></li>
        </ul>
      <li><a href="index.php?id=14,0,0,1,0,0">SubMenu 1/2</a></li>
    </ul>
  <li><a href="index.php?id=13,0,0,1,0,0">Menu 2</a></li>
  <li><a href="index.php?id=16,0,0,1,0,0">Menu 4</a></li>
  <li><a href="index.php?id=15,0,0,1,0,0">Menu 3</a></li>
</ul>
Oh, man, wrong syntactic! :shock: :shock: SORRY!!

The correct results:

Code: Select all

<ul>
  <li><a href="#">Menu 1</a>
    <ul>
      <li><a href="#">SubMenu 1/1</a></li>
    </ul>
  </li>  <!-- correct space the </li> tag -->
</ul>
and not this:

Code: Select all

<ul>
  <li><a href="#">Menu 1</a></li> <!-- NOT HERE!! -->
    <ul>
      <li><a href="#">SubMenu 1/1</a></li>
    </ul>
</ul>
I check the mod source...

Sorry again, Paul
User avatar
Oliver Georgi
Site Admin
Posts: 9907
Joined: Fri 3. Oct 2003, 22:22
Contact:

Post by Oliver Georgi »

Hi folks,

I have patched the file - will be included in coming dev release - hope it will be finished today. I have made the list compatible for ALIAS, redirect links and target - and W3C too ;-)


But for everybody not able to wait here are the changes:

in content.func.inc.php combine all {NAV_LIST...} like this:

Code: Select all

// some list based navigations
if( ! ( strpos($content["all"],'{NAV_LIST')===false ) ) {

	// some general list replacements first
	$content["all"] = str_replace('{NAV_LIST}', '{NAV_LIST:0}', $content["all"]);
	$content["all"] = str_replace('{NAV_LIST_TOP}', css_list_top($content["struct"],$content["cat_path"]), $content["all"]);
	$content["all"] = str_replace('{NAV_LIST_CURRENT}', css_list_current_level($content["struct"],$content["cat_path"],$content["cat_id"]), $content["all"]);

	// list based navigation starting at given level
	$replace = 'nav_list_struct($content["struct"],intval($content["cat_id"]),"$1",$template_default["nav_table_struct"]);';
	$content["all"] = preg_replace('/\{NAV_LIST:(\d+)\}/e', $replace, $content["all"]);
	
	//if( ! ( strpos($content["all"],'{NAV_LIST_TOP')===false ) ) {}
// List based navigation with Top Level - default settings
	// creates a list styled top nav menu, + optional Home | {NAV_LIST_TOP:home_name:class_name} | default class name = list_top
	$content["all"] = preg_replace('/\{NAV_LIST_TOP:(.*?):(.*?)\}/e', 'css_list_top($content["struct"],$content["cat_path"], "$1", "$2")', $content["all"]);
	
	//if( ! ( strpos($content["all"],'{NAV_LIST_CURRENT')===false ) ) {//}
	// List based navigation with Top Level - default settings
	// creates a list styled nav menu of current level {NAV_LIST_CURRENT:1:back_name:class_name} | default class name = list_top
	$content["all"] = preg_replace('/\{NAV_LIST_CURRENT:(\d+):(.*?):(.*?)\}/e', 'css_list_current_level($content["struct"],$content["cat_path"],$content["cat_id"],"$2","$1","$3")', $content["all"]);
}
and in front.func.inc.php add these lines of code:

Code: Select all

// -------------------------------------------------------------
// by ionrock http://ionrock.umemusic.com
// 2005.01.17 Paul (paal@mailbox.hu)
// Added 2 new line around 900 line by Thifi (tnx!):  if(trim($temp_menu) == "<ul>") return "";
// 2005.01.30 Enhanced and optimized by Oliver

function nav_list_struct ($struct, $act_cat_id, $level) {
	// start with home directory for the listing = top nav structure
	// 1. Build the recursive tree for given actual article category ID
	
	// return the tree starting with given start_id (like breadcrumb)
	// if the $start_id = 0 then this stops because 0 = top level
	
	$level = intval($level);
	$start_id = $act_cat_id;
	$c = 0;
	
	while ($start_id) {
		$data[$start_id] = 1;
		$start_id		 = $struct[$start_id]["acat_struct"];
	}
	$temp_tree = (sizeof($data)) ? array_reverse($data, 1) : false;
	
	foreach($struct as $key => $value) {
		if($struct[$key]["acat_struct"] == $act_cat_id && $key && !$struct[$key]["acat_hidden"]) {
			$c++;
		}
	}
	$c = (!$c) ? 1 : 0;
	
	//get depth of level
	$level_depth = 0; $start_level = $level;
	while ($start_level) {
		$start_level = $struct[$start_level]["acat_struct"];
		$level_depth++;
	}
	$temp_menu = build_list ($struct, $level, $temp_tree, $act_cat_id); //starts at root level
	//$temp_menu = str_replace('<li><li>', '<li>', $temp_menu);
	$temp_menu = str_replace("\n\n", "\n", $temp_menu);
	return ($temp_menu) ? ($temp_menu) : "";
}

// -------------------------------------------------------------

function build_list ($struct, $level, $temp_tree, $act_cat_id) {
	// this returns the level structure based on given arrays
	// it is special for browsing from root levels
	
	$temp_menu = "\n<ul>\n";
	foreach($struct as $key => $value) {
		
		if(isset($_SESSION["frontend_user_in"]) && $_SESSION["frontend_user_in"] && $struct[$key]["acat_regonly"]) {
			$struct[$key]["acat_regonly"] = 0;
		}
		
		if($struct[$key]["acat_struct"] == $level && $key && !$struct[$key]["acat_hidden"] && !$struct[$key]["acat_regonly"]) {
			
			if(!$struct[$key]["acat_redirect"]) {
				$link = 'index.php?';
				if($struct[$key]["acat_alias"]) {
					$link .= html_specialchars($struct[$key]["acat_alias"]);
				} else {
					$link .= 'id='.$key.',0,0,1,0,0';
				}
				$redirect['target'] = '';
			} else {
				$redirect = get_redirect_link($struct[$key]["acat_redirect"], ' ', '');
				$link = $redirect['link'];
			}
			
			if(!empty($temp_tree[$key])) {
			
				$temp_menu .= "\n<li>";
				if($act_cat_id == $key) {
					$temp_menu .= '<a class="listActive" href="'.$link.'"'.$redirect['target'].'>';
					$temp_menu .= html_specialchars($struct[$key]["acat_name"])."</a>";
				} else {
					$temp_menu .= '<a href="'.$link.'">'.html_specialchars($struct[$key]["acat_name"]).'</a>';
				}
				
				$temp_menu .= build_list ($struct, $key, $temp_tree, $act_cat_id);
				$temp_menu .= '</li>';
				
			} else {
				$temp_menu .= "\n<li>".'<a href="'.$link.'"'.$redirect['target'].'>';
				$temp_menu .= html_specialchars($struct[$key]["acat_name"])."</a></li>\n";
			}
		}
	}

	$temp_menu = trim($temp_menu);
	return $temp_menu != "<ul>" ? $temp_menu."\n</ul>" : '';
}

// end ionrock
// -------------------------------------------------------------
Oliver
Oliver Georgi | phpwcms Developer | GitHub | LinkedIn | Систрон
Jens*
Posts: 56
Joined: Fri 18. Jun 2004, 18:53

Post by Jens* »

Hallo Oliver,

wie kann ich denn jeder Ebene eine eigene Klasse zuweisen?

jens
User avatar
Oliver Georgi
Site Admin
Posts: 9907
Joined: Fri 3. Oct 2003, 22:22
Contact:

Post by Oliver Georgi »

schau Dir das Ergebnis der Ausgabe an - dann siehst Du wie ;-)
Oliver Georgi | phpwcms Developer | GitHub | LinkedIn | Систрон
Jens*
Posts: 56
Joined: Fri 18. Jun 2004, 18:53

Post by Jens* »

ja?

nur aktive haben ein

<li><a class="listActive" href="index.php?produkte">Produkte</a><ul>

:roll: *grübel*
frold
Posts: 2151
Joined: Tue 25. Nov 2003, 22:42

Post by frold »

Jens* wrote:ja?

nur aktive haben ein

<li><a class="listActive" href="index.php?produkte">Produkte</a><ul>

:roll: *grübel*
eg see: http://www.phpwcms.de/forum/viewtopic.php?p=32052#32052
http://www.studmed.dk Portal for doctors and medical students in Denmark
User avatar
Oliver Georgi
Site Admin
Posts: 9907
Joined: Fri 3. Oct 2003, 22:22
Contact:

Post by Oliver Georgi »

ja - danbn kannst Du das speziell anders setzen - oder aber die gleichen Stilangaben nutzen

Code: Select all

li, .listActive {..}
Oliver
Oliver Georgi | phpwcms Developer | GitHub | LinkedIn | Систрон
Jens*
Posts: 56
Joined: Fri 18. Jun 2004, 18:53

Post by Jens* »

hmm,

nutze ich {navlist}
sieht der code wie folgt aus:

<ul>
<li><a class="listActive" href="index.php?produkte">Produkte</a><ul>
<li><a href="index.php?id=12,0,0,1,0,0">Community</a></li>
</ul></li>
<li><a href="index.php?id=2,0,0,1,0,0">Leistungen</a></li>

<li><a href="index.php?id=7,0,0,1,0,0">Projekte</a></li>
<li><a href="index.php?referenzen">Referenzen</a></li>
<li><a href="index.php?support">Support</a></li>
<li><a href="index.php?kontakt">Kontakt</a></li>
<li><a href="index.php?impressum">Impressum</a></li>
</ul>
Ist das beabsichtigt, dass hier <li> ohne class="ebene1" .. genutzt wird?


Bei {NAV_LIST_CURRENT} ist mir die Verwendung klar...
<div id="list_level">
<ul id="list_level_ul">
<li id="list_level_parent"><a href="index.php?id=0,0,0,1,0,0" id="list_level_parent_link">Produkte</a></li>

<li><a href="index.php?id=12,0,0,1,0,0">Community</a></li>
</ul>
</div>

Mag ja auch sein, dass ich den Wald vor lauter Bäumen nicht sehe.. :-)

Jens
User avatar
Oliver Georgi
Site Admin
Posts: 9907
Joined: Fri 3. Oct 2003, 22:22
Contact:

Post by Oliver Georgi »

was brauchst Du denn?

Oliver
Oliver Georgi | phpwcms Developer | GitHub | LinkedIn | Систрон
Jens*
Posts: 56
Joined: Fri 18. Jun 2004, 18:53

Post by Jens* »

sowas wie:

Code: Select all

<div id="nav">
      <ul class="nav">
         
<li class="level1">name1</li>
<li class="level1_aktiv">name2</li>
<li class="level2">sub2</li>
<li class="level2">sub2</li>
<li class="level3">sub21</li>
<li class="level1">name3</li>
<li class="level1">name4</li>
         
      </ul>
</div>

Jens

User avatar
Oliver Georgi
Site Admin
Posts: 9907
Joined: Fri 3. Oct 2003, 22:22
Contact:

Post by Oliver Georgi »

Enhanced function:

{NAV_LIST} - starting at level 0, no class Name, active <li class="listActive">
{NAV_LIST:StartID} - starting at level StartID, active <li class="listActive">
{NAV_LIST:StartID:ClassName} -> <ul class="ClassNameLevelID">, active <li class="ClassNameLevelIDActive">

Try it and check source code and you will understand.

in front.func.inc.php:

Code: Select all

function nav_list_struct ($struct, $act_cat_id, $level, $class='') {
	// start with home directory for the listing = top nav structure
	// 1. Build the recursive tree for given actual article category ID
	
	// return the tree starting with given start_id (like breadcrumb)
	// if the $start_id = 0 then this stops because 0 = top level
	
	$level		= intval($level);
	$data		= array();
	$start_id 	= $act_cat_id;
	$class 		= trim($class);
	$depth		= 0;
	
	while ($start_id) {
		$data[$start_id] = 1;
		$start_id		 = $struct[$start_id]["acat_struct"];
	}
	$temp_tree = sizeof($data) ? array_reverse($data, 1) : false;

	$temp_menu = build_list ($struct, $level, $temp_tree, $act_cat_id, $class, $depth);
	$temp_menu = str_replace("\n\n", "\n", $temp_menu);
	return $temp_menu ? $temp_menu : '';
}

// -------------------------------------------------------------

function build_list ($struct, $level, $temp_tree, $act_cat_id, $class='', $depth=0) {
	// this returns the level structure based on given arrays
	// it is special for browsing from root levels
	
	if($class != '') {
		$curClass = ' class="'.$class.$depth.'"';
		$curClassNext = ' class="'.$class.($depth+1).'"';
		$curClassActive = ' class="'.$class.'Active'.$depth.'"';
	} else {
		$curClass = '';
		$curClassNext = '';
		$curClassActive = ' class="listActive"';
	}
	
	$depth++;
	
	$temp_menu = "\n<ul".$curClass.">\n";
	foreach($struct as $key => $value) {
		
		if(isset($_SESSION["frontend_user_in"]) && $_SESSION["frontend_user_in"] && $struct[$key]["acat_regonly"]) {
			$struct[$key]["acat_regonly"] = 0;
		}
		
		if($struct[$key]["acat_struct"] == $level && $key && !$struct[$key]["acat_hidden"] && !$struct[$key]["acat_regonly"]) {
			
			if(!$struct[$key]["acat_redirect"]) {
				$link = 'index.php?';
				if($struct[$key]["acat_alias"]) {
					$link .= html_specialchars($struct[$key]["acat_alias"]);
				} else {
					$link .= 'id='.$key.',0,0,1,0,0';
				}
				$redirect['target'] = '';
			} else {
				$redirect = get_redirect_link($struct[$key]["acat_redirect"], ' ', '');
				$link = $redirect['link'];
			}
			
			if(!empty($temp_tree[$key])) {
			
				if($act_cat_id == $key) {
					$temp_menu .= "\n<li".$curClassActive.">";
				} else {
					$temp_menu .= "\n<li>";
				}
				/*
				if($act_cat_id == $key) {
					$temp_menu .= '<a class="listActive" href="'.$link.'"'.$redirect['target'].'>';
					$temp_menu .= html_specialchars($struct[$key]["acat_name"])."</a>";
				} else {
					$temp_menu .= '<a href="'.$link.'">'.html_specialchars($struct[$key]["acat_name"]).'</a>';
				}
				*/
				$temp_menu .= '<a href="'.$link.'">'.html_specialchars($struct[$key]["acat_name"]).'</a>';
				
				$temp_menu .= build_list ($struct, $key, $temp_tree, $act_cat_id, $class, $depth);
				$temp_menu .= '</li>';
				
			} else {
				$temp_menu .= "\n<li>".'<a href="'.$link.'"'.$redirect['target'].'>';
				$temp_menu .= html_specialchars($struct[$key]["acat_name"])."</a></li>\n";
			}
		}
	}

	$temp_menu = trim($temp_menu);
	return $temp_menu != "<ul".$curClassNext.">" ? $temp_menu."\n</ul>" : '';//$temp_menu != "<ul>"
}
in content.func.inc.php:

Code: Select all

// some list based navigations
if( ! ( strpos($content["all"],'{NAV_LIST')===false ) ) {

	//reads all active category IDs beginning with the current cat ID - without HOME
	$content["cat_path"] = get_active_categories($content["struct"], $content["cat_id"]);

	// some general list replacements first
	$content["all"] = str_replace('{NAV_LIST}', '{NAV_LIST:0}', $content["all"]);
	$content["all"] = str_replace('{NAV_LIST_TOP}', css_list_top($content["struct"],$content["cat_path"]), $content["all"]);
	$content["all"] = str_replace('{NAV_LIST_CURRENT}', css_list_current_level($content["struct"],$content["cat_path"],$content["cat_id"]), $content["all"]);

	// list based navigation starting at given level
	$replace = 'nav_list_struct($content["struct"],$content["cat_id"],"$1", "$2");';
	$content["all"] = preg_replace('/\{NAV_LIST:(\d+):{0,1}(.*){0,1}\}/e', $replace, $content["all"]);
	
	//if( ! ( strpos($content["all"],'{NAV_LIST_TOP')===false ) ) {}
	// List based navigation with Top Level - default settings
	// creates a list styled top nav menu, + optional Home | {NAV_LIST_TOP:home_name:class_name} | default class name = list_top
	$content["all"] = preg_replace('/\{NAV_LIST_TOP:(.*?):(.*?)\}/e', 'css_list_top($content["struct"],$content["cat_path"], "$1", "$2")', $content["all"]);
	
	//if( ! ( strpos($content["all"],'{NAV_LIST_CURRENT')===false ) ) {//}
	// List based navigation with Top Level - default settings
	// creates a list styled nav menu of current level {NAV_LIST_CURRENT:1:back_name:class_name} | default class name = list_top
	$content["all"] = preg_replace('/\{NAV_LIST_CURRENT:(\d+):(.*?):(.*?)\}/e', 'css_list_current_level($content["struct"],$content["cat_path"],$content["cat_id"],"$2","$1","$3")', $content["all"]);
}
Oliver
Oliver Georgi | phpwcms Developer | GitHub | LinkedIn | Систрон
Jens*
Posts: 56
Joined: Fri 18. Jun 2004, 18:53

Post by Jens* »

thx for it. I will try it tonight... :-)

EDIT

Works fine THX!!

:-)
User avatar
sustia
Posts: 651
Joined: Fri 2. Apr 2004, 22:29
Location: Lecce (Italy)
Contact:

Post by sustia »

Sorry, I have lost myselt trying to understand...how I can realize the horizontal menu?
I must apply some hacks to the CSS or in the code?
It is included in the DEV 1.2 version?
Thanks
Campeones del mundo!
Vegetables!
brans

Post by brans »

--...--/index.php/topic,68.0.html
apply this patch and use the following settings instead of the mentioned ones.

Code: Select all

javascript:

startList = function() {
if (document.all&&document.getElementById) {
navRoot = document.getElementById("nav");
for (i=0; i<navRoot.childNodes.length; i++) {
node = navRoot.childNodes[i];
if (node.nodeName=="LI") {
node.onmouseover=function() {
this.className+=" over";
  }
  node.onmouseout=function() {
  this.className=this.className.replace(" over", "");
   }
   }
  }
 }
}
window.onload=startList;

Code: Select all

css:
body {
	font: normal 11px verdana;
	}

ul {
	margin: 0;
	padding: 0;
	list-style: none;
	width: 150px; /* Width of Menu Items */
	border-bottom: 1px solid #ccc;
	}
	
ul li {
	position: relative;
	}
	
li ul {
	position: absolute;
	left: 149px; /* Set 1px less than menu width */
	top: 0;
	display: none;
	}

/* Styles for Menu Items */
ul li a {
	display: block;
	text-decoration: none;
	color: #777;
	background: #fff; /* IE6 Bug */
	padding: 5px;
	border: 1px solid #ccc; /* IE6 Bug */
	border-bottom: 0;
	}
	
/* Holly Hack. IE Requirement \*/
* html ul li { float: left; height: 1%; }
* html ul li a { height: 1%; }
/* End */

li:hover ul, li.over ul { display: block; } /* The magic */
User avatar
sustia
Posts: 651
Joined: Fri 2. Apr 2004, 22:29
Location: Lecce (Italy)
Contact:

Post by sustia »

Hi Brans, if I understand well I must do the following steps:

Code: Select all

---------------[CREATE]---------------
phpwcms_template/inc_script/frontend_render/reptag_dropdown.php
---------------[ADD]---------------
<?php
// -------------------------------------------------------------
if( ! ( strpos($content["all"],'{DROPDOWN')===false ) ) {
   $content["all"] = str_replace('{DROPDOWN}', '{DROPDOWN:0}', $content["all"]);
   $replace = 'build_dhtmlmenu( "$1","id=nav", 0);';
   $content["all"] = preg_replace('/\{DROPDOWN:(\d+)\}/e', $replace, $content["all"]);
}
// -------------------------------------------------------------
?>
create the javascript as described below replacing with the code that you posted here:

Code: Select all

---------------[CREATE]---------------
include/inc_js/dropdown.js
---------------[ADD]---------------
sfHover = function() {
var sfEls = document.getElementById("nav").getElementsByTagName("LI");
for (var i=0; i<sfEls.length; i++) {
sfEls[i].onmouseover=function() {
this.className+=" sfhover";
}
sfEls[i].onmouseout=function() {
this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
---------------[CLOSE]---------------

and:

Code: Select all

---------------[OPEN]---------------
phpwcms-backend => html-head of your template

---------------[ADD]---------------
<script type="text/javascript" src="/phpwcms_template/inc_js/dropdown.js"></script>
---------------[CLOSE]---------------
At the end putting the code you have posted in the CSS file.
It's correct?
Campeones del mundo!
Vegetables!
Post Reply