[interchange-cvs] interchange - heins modified lib/Vend/Menu.pm

interchange-core@icdevgroup.org interchange-core@icdevgroup.org
Thu Aug 15 01:42:01 2002


User:      heins
Date:      2002-08-15 05:41:26 GMT
Modified:  lib/Vend Menu.pm
Log:
* Add multi-level flyout menu style. Uses the tree menu type.

	[menu
			name=3DProducts
			link-class=3Dbarlink
			menu-type=3Dflyout
			flyout-class=3D"categorybar"
			flyout-style=3D"
				padding: 3px;
				border: 3px solid #996633;
			"][/menu]

   Voila. Goes as many levels as you have.

Revision  Changes    Path
2.9       +352 -13   interchange/lib/Vend/Menu.pm


rev 2.9, prev_rev 2.8
Index: Menu.pm
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /var/cvs/interchange/lib/Vend/Menu.pm,v
retrieving revision 2.8
retrieving revision 2.9
diff -u -r2.8 -r2.9
--- Menu.pm	14 Aug 2002 15:40:22 -0000	2.8
+++ Menu.pm	15 Aug 2002 05:41:26 -0000	2.9
@@ -1,6 +1,6 @@
 # Vend::Menu - Interchange payment processing routines
 #
-# $Id: Menu.pm,v 2.8 2002/08/14 15:40:22 mheins Exp $
+# $Id: Menu.pm,v 2.9 2002/08/15 05:41:26 mheins Exp $
 #
 # Copyright (C) 2002 Mike Heins, <mike@perusion.net>
 #
@@ -21,7 +21,7 @@
=20
 package Vend::Menu;
=20
-$VERSION =3D substr(q$Revision: 2.8 $, 10);
+$VERSION =3D substr(q$Revision: 2.9 $, 10);
=20
 use Vend::Util;
 use strict;
@@ -314,6 +314,288 @@
 	return old_simple(@_);
 }
=20
+sub old_flyout {
+	return dhtml_flyout(@_);
+}
+
+sub dhtml_flyout {
+	my($name, $opt, $template) =3D @_;
+
+	my @out;
+	my $fdiv =3D $name . "_flyout";
+
+	$template =3D <<EOF if $template !~ /\S/;
+{MV_LEVEL:}<div>{PAGE?}{MV_SPACER}<a id=3D"{CODE}" href=3D"{PAGE}" onMouse=
Over=3D"mousein(this)" onMouseOut=3D"mouseout(this)" TITLE=3D"{DESCRIPTION}=
" class=3D"$opt->{link_class}">{NAME}</A>{/PAGE?}{PAGE:}{MV_SPACER}{NAME}{/=
MV_SPACER}{/PAGE:}</div>{/MV_LEVEL:}
+EOF
+
+	$opt->{cursor_type} ||=3D 'hand';
+	$opt->{flyout_style} ||=3D <<EOF;
+		font-weight: bold;
+		text-align: left;
+		font-size: 10px;
+		font-family: verdana,arial;
+		cursor: hand;
+		text-decoration: none;
+		padding: 2px;
+EOF
+
+
+	push @out, <<EOF;
+<script language=3D"JavaScript1.3">
+var timeoutCode =3D -1;
+var lines =3D new Array;
+EOF
+
+	my %o =3D (
+			start       =3D> $opt->{tree_selector} || $opt->{name},
+			table       =3D> $opt->{table} || $::Variable->{MV_TREE_TABLE} || 'tree=
',
+			master      =3D> 'parent_fld',
+			subordinate =3D> 'code',
+			autodetect  =3D> '1',
+			sort        =3D> $opt->{sort} || 'code',
+			iterator    =3D> \&tree_line,
+			row_repository =3D> [],
+			full        =3D> '1',
+			spacing     =3D> '4',
+		);
+	push @out, Vend::Tags->tree(\%o);
+
+	my $rows =3D $o{row_repository} || [];
+	my %seen;
+	my @levels =3D grep !$seen{$_}++, map { $_->{mv_level} } @$rows;
+	@levels =3D sort { $a <=3D> $b } @levels;
+	shift @levels;
+
+	push @out, <<EOF;
+var last_level =3D $levels[$#levels];
+var link_class =3D '$opt->{link_class}';
+var link_class_open =3D '$opt->{link_class_open}';
+var link_class_closed =3D '$opt->{link_class_closed}';
+var link_style =3D '$opt->{link_style}';
+var link_style_open =3D '$opt->{link_style_open}';
+var link_style_closed =3D '$opt->{link_style_closed}';
+EOF
+	push @out, <<EOF;
+
+	function menu_link (idx) {
+
+		var l =3D lines[ idx ];
+
+		if(l =3D=3D undefined) {
+			alert("Bad idx=3D" + idx + ", no line there.");
+			return;
+		}
+
+		var out =3D '<DIV';
+		if(l[MV_CHILDREN] > 0) {
+			out =3D out + ' id=3D"' + l[0] + '"';
+			out =3D out + ' onMouseOver=3D"mousein(this,' + l[MV_LEVEL] + ')"';
+		}
+		out +=3D '>';
+		var tstyle =3D link_style;
+		var tclass =3D link_class;
+		if(l[PAGE]) {
+			out =3D out + '<a href=3D"' + l[ PAGE ] + '"';
+			if(tclass)
+				out =3D out + ' class=3D"' + tclass + '"';
+			if(tstyle)
+				out =3D out + ' style=3D"' + tstyle + '"';
+			if(l[DESCRIPTION])
+				out =3D out + ' title=3D"' + l[ DESCRIPTION ] + '"';
+			out =3D out + '>';
+			out =3D out + l[ NAME ] + '</a>';
+		}
+		else {
+			out =3D out + l[ NAME ];
+		}
+	// alert("build idx=3D" + idx + " into: " + out);
+		out +=3D '</div>';
+
+		return out;
+	}
+
+	var mydiv =3D '$fdiv';
+
+	function mousein (obj,level) {
+		if( browserType() =3D=3D "other" )
+			return;
+
+		if(level =3D=3D undefined)=20
+			level =3D 0;
+		level++;
+
+		var divname =3D mydiv + level;
+		var fod =3D document.getElementById( divname );
+		if(fod =3D=3D undefined)=20
+			return;
+		fod.style.display =3D 'none';
+		clearTimeout( timeoutCode );
+		timeoutCode =3D -1;
+
+		var html =3D "";
+
+		var idx =3D -1;
+		for(var j =3D 0; j < lines.length; j++) {
+			if(lines[j][0] =3D=3D obj.id) {
+				idx =3D j;
+				break;
+			}
+		}
+
+		if(idx < 0)=20
+			return;
+=09
+		var currentlevel =3D lines[idx][MV_LEVEL];
+		if(currentlevel =3D=3D undefined)
+			currentlevel =3D 0;
+
+		menuClear(currentlevel);
+
+		var x =3D getRightX( obj ) + 1;
+		var y =3D getTopX( obj );
+		var menu =3D fod.style;
+		menu.left =3D x + "px";
+		menu.top =3D y + "px";
+		menu.display =3D 'block';
+
+		var i;
+		for( i =3D idx + 1; ; i++ )
+		{
+			var l =3D lines[i];
+// alert("running link for level=3D" + l[MV_LEVEL] + ", line=3D" + l);
+			if(l =3D=3D undefined || l[MV_LEVEL] < level)
+				break;
+			if(l[MV_LEVEL] =3D=3D level)
+				html +=3D menu_link(i);
+		}
+		fod.innerHTML =3D html;
+	}
+
+	function getRightX( obj )
+	{
+		if( browserType() =3D=3D "ie" )
+			return obj.getBoundingClientRect().right - 2;
+		else {
+			var n =3D 0;
+			var x =3D obj.offsetParent;
+			while(x.offsetParent !=3D undefined) {
+				n +=3D x.offsetLeft;
+				x =3D x.offsetParent;
+			}
+			return n + obj.offsetLeft + obj.offsetWidth;
+		}
+	}
+
+	function getTopX( obj )
+	{
+		if( browserType() =3D=3D "ie" )
+			return obj.getBoundingClientRect().top - 2;
+		else {
+			var n =3D 0;
+			var x =3D obj;
+			while(x.offsetParent !=3D undefined) {
+				n +=3D x.offsetParent.offsetTop;
+				x =3D x.offsetParent;
+			}
+			return n + obj.offsetTop;
+		}
+	}
+=09
+	function mouseout( obj, level )
+	{
+		if( browserType() =3D=3D "other" )
+			return;
+
+		if(level =3D=3D undefined)=20
+			level =3D 0;
+		level++;
+		timeoutCode =3D setTimeout( "menuClear();", 1000 );
+	}
+
+	function menuClear(level)
+	{
+		if (level =3D=3D undefined)
+			level =3D 0;
+		level++;
+		for( var i =3D level; i <=3D last_level; i++) {
+			var thisdiv =3D mydiv + i;
+			var fod =3D document.getElementById( thisdiv );
+			if(fod !=3D undefined)
+				fod.style.display =3D 'none';
+		}
+		clearTimeout( timeoutCode );
+		timeoutCode =3D -1;
+	}
+
+	function menuBusy()
+	{
+		clearTimeout( timeoutCode );
+		timeoutCode =3D -1;
+	}
+
+	var clientType =3D "unknown";
+
+	function browserType()
+	{
+		if( clientType !=3D "unknown"  )
+			return clientType;
+=09
+		clientType =3D "other";
+		if (document.all) {
+			if( document.getElementById )
+		  		clientType =3D "ie";
+		}
+		else if (document.layers) {
+		}
+		else if (document.getElementById) {
+			clientType =3D "ns6";
+		}
+		else
+		{
+		}
+
+		return clientType;
+	}
+
+</script>
+EOF
+
+	for(@levels) {
+		push @out, <<EOF;
+<div id=3D"$fdiv$_" style=3D"
+						position:absolute;
+						display:none;
+						$opt->{flyout_style}
+					"
+		 OnMouseOver=3D"menuBusy();" OnMouseOut=3D"mouseout();"></DIV>
+EOF
+	}
+
+	my $header;
+	$header =3D ::interpolate_html($opt->{header_template})
+		if $opt->{header_template};
+	if($header =3D~ /\S/) {
+		$header =3D Vend::Tags->uc_attr_list($opt, $header);
+		push @out, $header;
+	}
+
+#::logDebug("Template is: $template");
+	for my $row (@$rows) {
+#::logDebug("Doing row: " . ::uneval($row));
+		push @out, Vend::Tags->uc_attr_list($row, $template);
+	}
+
+	my $footer;
+	$footer =3D ::interpolate_html($opt->{footer_template})
+		if $opt->{footer_template};
+	if($footer =3D~ /\S/) {
+		$footer =3D Vend::Tags->uc_attr_list($opt, $footer);
+		push @out, $footer;
+	}
+
+	return join "", @out;
+}
+
 sub dhtml_tree {
 	my($name, $opt, $template) =3D @_;
 	my @out;
@@ -551,14 +833,20 @@
 	}
=20
 	$template ||=3D qq[
-{MV_SPACER}{MV_CHILDREN?}<A href=3D"{TOGGLE_URL}" class=3D"{TOGGLE_CLASS}"=
 style=3D"{TOGGLE_STYLE}">{TOGGLE_ANCHOR}</A>{URL?}<A href=3D"{URL}" class=
=3D"{TOGGLE_CLASS}" style=3D"{TOGGLE_STYLE}">{/URL?}{NAME}{URL?}</a>{/URL?}=
{/MV_CHILDREN?}{MV_CHILDREN:}{TOGGLE_ANCHOR}{URL?}<A href=3D"{URL}" class=
=3D"{LINK_CLASS}" style=3D"{LINK_STYLE}">{/URL?}{NAME}{URL?}</a>{/URL?}{/MV=
_CHILDREN:}<br>
+{MV_SPACER}{MV_CHILDREN?}<A href=3D"{TOGGLE_URL}" class=3D"{TOGGLE_CLASS}"=
 style=3D"{TOGGLE_STYLE}">{TOGGLE_ANCHOR}</A>{PAGE?}<A href=3D"{HREF}" clas=
s=3D"{TOGGLE_CLASS}" style=3D"{TOGGLE_STYLE}">{/PAGE?}{NAME}{PAGE?}</a>{/PA=
GE?}{/MV_CHILDREN?}{MV_CHILDREN:}{TOGGLE_ANCHOR}{PAGE?}<A href=3D"{HREF}" c=
lass=3D"{LINK_CLASS}" style=3D"{LINK_STYLE}">{/PAGE?}{NAME}{PAGE?}</a>{/PAG=
E?}{/MV_CHILDREN:}<br>
 ];
=20
-	if($row->{page}) {
+	if(! $row->{page}) {
+	}
+	elsif ($row->{page} =3D~ /^\w+:/) {
+		$row->{href} =3D $row->{page};
+	}
+	else {
 		unless($row->{form} =3D~ /[\r\n]/) {
 			$row->{form} =3D join "\n", split $Global::UrlSplittor, $row->{form};
 		}
-		$row->{url} =3D Vend::Tags->area( { href =3D> $row->{page}, form =3D> $r=
ow->{form} });
+		$row->{form} ||=3D ' ';
+		$row->{href} =3D Vend::Tags->area( { href =3D> $row->{page}, form =3D> $=
row->{form} });
 	}
 	$row->{name} =3D~ s/ /&nbsp;/g;
 	$opt->{toggle_base_url} ||=3D Vend::Tags->history_scan(
@@ -624,6 +912,9 @@
 			}
 		}
=20
+		if($opt->{fields_repository}) {
+			$opt->{fields_repository} =3D [ @$fields ];
+		}
 		push @$fields, 'open';
 		for(my $i =3D 1; $i < @$fields; $i++) {
 			push @out, "var \U$fields->[$i]\E =3D $i;";
@@ -638,10 +929,13 @@
 		return unless $transform{$_}->($row, $opt->{$_});
 	}
=20
-	if($row->{page}) {
+	if($row->{page} and $row->{page} !~ /^\w+:/) {
 		my $form =3D $row->{form};
+		if($form and $form !~ /[\r\n]/) {
+			$form =3D join "\n", split $Global::UrlSplittor, $form;
+		}
+
 		if($form) {
-			$form =3D~ s/&/\n/g;
 			$form .=3D "\nopen=3D";
 		}
 		else {
@@ -650,6 +944,9 @@
 		$row->{page} =3D Vend::Tags->area( { href =3D> $row->{page}, form =3D> $=
form });
 	}
=20
+	if($opt->{row_repository}) {
+		push @{$opt->{row_repository}}, $row;
+	}
 	my @values =3D @{$row}{@$fields};
=20
 	for(@values) {
@@ -694,12 +991,17 @@
 #::logDebug("passed transforms, row now: " . ::uneval($row)) if  $row->{de=
bug};
=20
 	#return $row->{name} if ! $row->{page} and $row->{name} =3D~ /^\s*</;
-	if($row->{page}) {
-		$row->{form} =3D~ tr/&/\n/;
+	if(! $row->{page}) {
+	}
+	elsif ($row->{page} =3D~ /^\w+:/) {
+		$row->{href} =3D $row->{page};
+	}
+	else {
+		unless($row->{form} =3D~ /[\r\n]/) {
+			$row->{form} =3D join "\n", split $Global::UrlSplittor, $row->{form};
+		}
 		$row->{href} =3D Vend::Tags->area( { href =3D> $row->{page}, form =3D> $=
row->{form} });
 	}
-		$row->{name} =3D errmsg($row->{name});
-		$row->{description} =3D~ s/"/&quot;/g;
 	return Vend::Tags->uc_attr_list($row, $template);
 }
=20
@@ -778,8 +1080,45 @@
 							});
 		}
=20
-		return old_tree(@_) unless $opt->{dhtml_browser};
-		return dhtml_tree(@_);
+		return old_tree($name,$opt,$template) unless $opt->{dhtml_browser};
+		return dhtml_tree($name,$opt,$template);
+	}
+	elsif($opt->{menu_type} eq 'flyout') {
+		$opt->{link_class_open}   ||=3D $opt->{link_class};
+		$opt->{link_class_closed} ||=3D $opt->{link_class};
+		if(is_yes($opt->{no_image})) {
+			$opt->{no_image} =3D 1;
+			$opt->{toggle_anchor_clear}  ||=3D '&nbsp;';
+			$opt->{toggle_anchor_closed} ||=3D '+';
+			$opt->{toggle_anchor_open}   ||=3D '-';
+		}
+		else {
+			$opt->{no_image} =3D 0;
+			my $nm =3D "img_$_";
+			$opt->{toggle_anchor_open} =3D Vend::Tags->image( {
+							src =3D> $opt->{img_open}  || $menu_default_img{open},
+							border =3D> 0,
+							extra =3D> $opt->{img_open_extra} || 'align=3Dabsbottom',
+							});
+			$opt->{toggle_anchor_closed} =3D Vend::Tags->image( {
+							src =3D> $opt->{img_closed} || $menu_default_img{closed},
+							border =3D> 0,
+							extra =3D> $opt->{img_closed_extra} || 'align=3Dabsbottom',
+							});
+			if($opt->{toggle_anchor_closed} =3D~ /\s+width=3D"?(\d+)/i) {
+				$opt->{img_clear_extra} ||=3D "height=3D1 width=3D$1";
+			}
+			$opt->{toggle_anchor_clear} =3D Vend::Tags->image( {
+							src =3D> $opt->{img_clear} || $menu_default_img{clear},
+							getsize =3D> 0,
+							border =3D> 0,
+							extra =3D> $opt->{img_clear_extra},
+							});
+		}
+
+		return old_flyout($name,$opt,$template) unless $opt->{dhtml_browser};
+#::logDebug("ready to run dhtml_flyout");
+		return dhtml_flyout($name,$opt,$template);
 	}
 	elsif($opt->{menu_type} eq 'simple') {
 		if($opt->{search}) {