Hi,

well here is my solution, which is completly serverside.
Thus no javascript is needed.

First some description to the attached files.

menu.sql contains the sql command for postgresql 7.1.
It has a table containing the sql tree, based on the
nested set model from SQL for smarties. Then there are
two views for easily getting the direct parent of a menu.
Actually i would like to have one view does it, but couldn't
achieve it. Any ideas or improvements are welcome.
At last there are 4 methods for insert,delete and moving
a child menu to be the first or last child of menu.

menu.xsp procuces a flat dump of the menu from the database.

menu2hier.xsl transforms a flat dump to a hierarchily menu.

menu2html.xsl transfomrs the hierarchily menu to html.

The configuration in the sitemap is the following:

        <map:match pattern="navigate">
           <map:act type="menu-management">
            <map:generate type="serverpages" src="menu.xsp"/>
            <map:transform src="stylesheets/menu2hier.xsl"/>
                <map:transform src="stylesheets/menu2html.xsl">
                 <map:parameter name="menu_ids" value="{menu_ids}"/>
            </map:transform>
                <map:serialize/>
           </map>
        </map:match>

the Action menu-managment if the following:

public class MenuManagementAction extends
AbstractComplementaryConfigurableAction {

        public Map act( Redirector redirector,SourceResolver resolver,Map
objectModel,String source,Parameters param ) throws Exception {
                getLogger().debug( "HelpDesk : MenuManagementAction/act : start" );

    HashMap     result  = new HashMap();
    HttpRequest request = (HttpRequest)objectModel.get(
Constants.REQUEST_OBJECT );
    Session     session = request.getSession();

    getLogger().debug( "HelpDesk : MenuManagementAction/act : request object
= " + request );
    getLogger().debug( "HelpDesk : MenuManagementAction/act : session object
= " + session );

    String id_add_str = request.getParameter( "addid" ) != null ?
request.getParameter( "addid" ) : "0";
    String id_rem_str = request.getParameter( "remid" ) != null ?
request.getParameter( "remid" ) : "0";
    String menu_ids = session.getAttribute( "menu_ids" ) != null ?
(String)session.getAttribute( "menu_ids" ) : "$1$";

    getLogger().debug( "HelpDesk : MenuManagementAction/act : add id string
= " + id_add_str );
    getLogger().debug( "HelpDesk : MenuManagementAction/act : remove id
string = " + id_rem_str );
    getLogger().debug( "HelpDesk : MenuManagementAction/act : show ids = " +
menu_ids );

    if( id_add_str.equals( "" ) )
      id_add_str = "0";

    int id_add = Integer.parseInt( id_add_str.trim() );

    if( id_rem_str.equals( "" ) )
      id_rem_str = "0";

    int id_rem = Integer.parseInt( id_rem_str.trim() );

    getLogger().debug( "HelpDesk : MenuManagementAction/act : add id int = "
+ id_add );
    getLogger().debug( "HelpDesk : MenuManagementAction/act : remove id int
= " + id_rem );

    // decompose
    Vector menu_ids_vec = new Vector();
    for( StringTokenizer tokens = new StringTokenizer(
menu_ids.trim(),"$" );tokens.hasMoreTokens(); )
      menu_ids_vec.add( (String)tokens.nextToken() );

    // add
    if( id_add > 0 ) {
      boolean found = false;
      for( Enumeration ids = menu_ids_vec.elements();ids.hasMoreElements()
&& !found; ) {
        if( ((String)ids.nextElement()).equals( Integer.toString(
id_add ) ) )
          found = true;
      }

      if( !found )
        menu_ids_vec.add( Integer.toString( id_add ) );
    }

    // rem
    if( id_rem > 1 ) {
      for( Enumeration ids =
menu_ids_vec.elements();ids.hasMoreElements(); ) {
        String id = (String)ids.nextElement();

        if( id.equals( Integer.toString( id_rem ) ) ) {
          menu_ids_vec.removeElement( id );
          break;
        }
      }
    }

    // compose
    menu_ids = "$";
    for( Enumeration ids = menu_ids_vec.elements();ids.hasMoreElements(); )
      menu_ids += (String)ids.nextElement() + "$";

    session.setAttribute( "menu_ids",menu_ids );
    result.put( "menu_ids",menu_ids );
                getLogger().debug( "HelpDesk : MenuManagementAction/act : show ids
composed = " + menu_ids );

                getLogger().debug( "HelpDesk : MenuManagementAction/act : result = " +
result );
                getLogger().debug( "HelpDesk : MenuManagementAction/act : end != null" 
);

                return Collections.unmodifiableMap( result );
        }
}

And no some explainantion.
The actions computes a session attribute menu_ids, which is even
forwarded to the second stylesheet. It contains a $ seperated
id from mneu table, which should be displayed expanded.

Have a lot of fun with it. It may not be the best solution, but i like
it and suggestion and improvments are as stated welcome.

Max




Hi.,
   I appreciate if anyone is generous enough to share
xsl code for building collapsing menu structure for my
sample project...


Thanks

 --- Vadim Gritsenko <[EMAIL PROTECTED]> wrote: > If
you write for Oracle you could use "connect by"
> clause of select statement.
>
http://technet.oracle.com/docs/products/oracle8i/doc_library/817_doc/server.
817/a85397/state21b.htm#2065648
>
> Vadim
>
> > -----Original Message-----
> > From: Max Larsson
> [mailto:[EMAIL PROTECTED]]
> > Sent: Thursday, August 23, 2001 2:00 AM
> > To: [EMAIL PROTECTED]
> > Subject: AW: separation of content and logic
> >
> >
> > Hi,
> >
> > > Now I want to generate a Menuestructure from
> database
> > > entries in the way a filebrowser works, expand
> an entry on mouseclick,
> > > on the second mouseclick collapse them (html
> links).
> > > My first guess was to use nested select
> statements
> > > to only get those entries I want to show
> (expanded or collapsed).
> >
> > I am trying to do the same. At the moment i am
> trying to use
> > the nested set model from "SQL for smarties". See:
> >
> > http://www.dbmsmag.com/9603d06.html
> > http://www.dbmsmag.com/9604d06.html
> > http://www.dbmsmag.com/9605d06.html
> >
> > > As I thought further may be it would be better
> in the xsp
> > > to always retrieve all items from the database
> > > and then decide in the stylesheet which entries
> to
> > > show and which not (e.g. by session attributes).
> > > But in a xsl I cann't use <xsp:logic>
> >
> > After thinking a lot i decided to let xsp retrieve
> > the complete menu structure and let the xsl
> stylesheet
> > decide which menu items are collapsed or
> expandended.
> > To that i will give the xsl stylesheet a
> parameter,
> > which contains all the ids of the menuitems, wich
> shall
> > be expanded. That's my idea, if it works have to
> > be proved.
> >
> > Max
> >
> >
>
---------------------------------------------------------------------
> > Please check that your question has not already
> been answered in the
> > FAQ before posting.
> <http://xml.apache.org/cocoon/faqs.html>
> >
> > To unsubscribe, e-mail:
> <[EMAIL PROTECTED]>
> > For additional commands, e-mail:
> <[EMAIL PROTECTED]>
> >
> >
>
>
---------------------------------------------------------------------
> Please check that your question has not already been
> answered in the
> FAQ before posting.
> <http://xml.apache.org/cocoon/faqs.html>
>
> To unsubscribe, e-mail:
> <[EMAIL PROTECTED]>
> For additional commands, e-mail:
> <[EMAIL PROTECTED]>
>

=====
Thanks and have great day
srini

____________________________________________________________
Do You Yahoo!?
Send a newsletter, share photos & files, conduct polls, organize chat
events. Visit http://in/ groups.yahoo.com

---------------------------------------------------------------------
Please check that your question has not already been answered in the
FAQ before posting. <http://xml.apache.org/cocoon/faqs.html>

To unsubscribe, e-mail: <[EMAIL PROTECTED]>
For additional commands, e-mail: <[EMAIL PROTECTED]>

menu.sql

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
	<xsl:output method="xml" encoding="ISO-8859-1"/>
	
	<xsl:template match="menu-container[ @type = 'flat' ]">
		<menu-container type="hierarchy">
			<xsl:apply-templates select="menu[ position() = 1 and @level = 1]"/>
		</menu-container>
	</xsl:template>
	
	<xsl:template match="menu[ @subs > 0 ]">
		<xsl:variable name="level" select="@level"/>
		<xsl:variable name="subs" select="@subs + 1"/>
		<menu>
            <xsl:apply-templates select="node()|@*"/>
			<xsl:for-each select="following-sibling ::menu[ position() &lt; $subs and @level = $level + 1]">
				<xsl:apply-templates select="."/>
			</xsl:for-each>
		</menu>
	</xsl:template>

	<xsl:template match="menu[ @subs = 0 ]">
		<menu>
            <xsl:apply-templates select="node()|@*"/>
		</menu>
	</xsl:template>
	
	<xsl:template match="node()|@*" priority="-1">
		<xsl:copy>
			<xsl:apply-templates select="node()|@*"/>
		</xsl:copy>
	</xsl:template>

</xsl:stylesheet>
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; xmlns:fo="http://www.w3.org/1999/XSL/Format";>
	<xsl:output method="xml" encoding="ISO-8859-1"/>

    <xsl:param name="menu_ids">$1$</xsl:param>
	
	<xsl:template match="page">
		<html>
			<!-- These HTML-pages and the information herein are property of GM Service Operations. Distribution without prior consent is prohibited. Internal use only. -->
			<head>
				<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
				<meta http-equiv="expires" content="0"/>
				<meta http-equiv="pragma" content="no-cache"/>
				<title><xsl:value-of select="normalize-space( @title )"/></title>
				<style type="text/css">
					<xsl:comment>
						a:active { font-weight:bold; }
						a:hover { font-weight:bold; }
						span { font-family:Arial; font-size:9pt; }
						a { text-decoration:none; }
						td { font-family:Arial; font-size:9pt; }
						input { font-family:Arial; font-size:9pt; }
					</xsl:comment>
				</style>
			</head>
			<body bgcolor="#A6CAF0" text="#000000" alink="#FF0000" vlink="#0000FF" link="#000000">
				<xsl:apply-templates select="node()|@*"/>
			</body>
		</html>
	</xsl:template>
	
	<xsl:template match="menu-container[ @type = 'hierarchy' ]">
		<xsl:apply-templates select="menu"/>
	</xsl:template>
	
	<xsl:template match="menu[ menu and contains( $menu_ids,@id ) ]">
		<xsl:param name="indent" select="1"/>
		<!-- menu with opened submenu --> 
		<nobr>
			<img src="/icon/1x1.gif" alt="" border="0" width="{$indent}" height="1"/>
			<a href="navigate?remid={@id}" target="Navigation">
				<img src="/icon/symb_folder_opened.gif" border="0" width="9" height="9" alt="{normalize-space( description ) }"/>
			</a>
			<img src="/icon/1x1.gif" alt="" border="0" width="6" height="1"/>
			<a href="{normalize-space( link )}" target="{normalize-space( target )}" title="{normalize-space( description )}">
				<span>
					<xsl:value-of select="normalize-space( title )"/>
				</span>
			</a>
		</nobr>
		<br/>
		<xsl:apply-templates select="menu">
			<xsl:with-param name="indent" select="$indent + 15"/>
		</xsl:apply-templates>
	</xsl:template>
	
    <xsl:template match="menu[ menu and not( contains( $menu_ids,@id ) ) ]">
        <xsl:param name="indent" select="1"/>
        <!-- menu with opened submenu --> 
        <nobr>
            <img src="/icon/1x1.gif" alt="" border="0" width="{$indent}" height="1"/>
            <a href="navigate?addid={@id}" target="Navigation">
                <img src="/icon/symb_folder_closed.gif" border="0" width="9" height="9" alt="{normalize-space( description ) }"/>
            </a>
            <img src="/icon/1x1.gif" alt="" border="0" width="6" height="1"/>
            <a href="{normalize-space( link )}" target="{normalize-space( target )}" title="{normalize-space( description )}">
                <span>
                    <xsl:value-of select="normalize-space( title )"/>
                </span>
            </a>
        </nobr>
        <br/>
    </xsl:template>

	<xsl:template match="menu[ not( menu )]">
		<xsl:param name="indent" select="1"/>
		<!-- Leaf  -->
		<nobr>
			<a href="{normalize-space( link )}" target="{normalize-space( target )}" title="{normalize-space( description )}">
				<img src="/icon/1x1.gif" alt="" border="0" width="{$indent}" height="1"/>
				<img src="/icon/symb_document.gif" border="0" width="9" height="9" alt="{normalize-space( description ) }"/>
				<img src="/icon/1x1.gif" alt="" border="0" width="6" height="1"/>
				<span>
					<xsl:value-of select="normalize-space( title )"/>
				</span>
			</a>
		</nobr>
		<br/>
	</xsl:template>

	<xsl:template match="node()|@*" priority="-1">
		<xsl:copy>
			<xsl:apply-templates select="node()|@*"/>
		</xsl:copy>
	</xsl:template>
</xsl:stylesheet>

menu.xsp

---------------------------------------------------------------------
Please check that your question has not already been answered in the
FAQ before posting. <http://xml.apache.org/cocoon/faqs.html>

To unsubscribe, e-mail: <[EMAIL PROTECTED]>
For additional commands, e-mail: <[EMAIL PROTECTED]>

Reply via email to