Post by Qphoria » Tue Aug 19, 2008 8:11 am

Hmm, but it seems that you are still reliant on the "path" value to break your menu levels. maybe not.

I actually have a working version, it does it a bit different tho, using some help from a php forum they recommended this. It works, but it uses multiple db queries.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by ogun » Tue Aug 19, 2008 6:04 pm

was looking at category nesting a while ago, with something that might be useful for an admin menu too:

http://forum.opencart.com/index.php/top ... tml#msg854

it runs a single query to get the details as JNeuhoff suggested, then works through the result to build an associative array of the menu contents.
the time taken to run the initial query and the subsequent function is negligible - but still, there's room for optimisation in the query (e.g. replacing the joined tables with selects that only include the required columns). if it's any use, i could modify it to look at menu, menu_to_menu (and maybe menu_description - is localisation going to be db or file-based?).

would be great to have a more sensible menu system, js seems over the top/obstructive given the nature of the task.

Active Member

Posts

Joined
Tue Aug 14, 2007 6:04 am

Post by Qphoria » Tue Aug 19, 2008 7:22 pm

Currently, the 2-layer db menu I have has localization in the database. This "could" be set back to filebased, but then whats easier? adding another a few more sql inserts for more languages or creating another file? At this point it could go either way so lets just focus on seeing if it works.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by JNeuhoff » Tue Aug 19, 2008 7:40 pm

OK, assuming the following DB tables (I think each sub-menu can only have exactly one parent...):

menu:


menu_id  menu_parent_id  title  icon  href  sort_order 
........................
........................



menu_description:


menu_id  language_id  desc-whatever 
............
............


You could use the following PHP code for generating HTML view of nested menus, using only one database query, whose results are stored in a session object (to make it even faster):

Code: Select all

<?php

// Viewer support functions for HTML templates


//
// use OpenCart's admin/config.php
//
require_once("config.php");


//
// find the last update date of the menu DB tables
//
function lastMenusUpdate() {
	$sql = "SHOW TABLE STATUS FROM ".DB_NAME." LIKE 'menu%';";
	$rows = mysql_query($sql) or die('Query failed: ' . mysql_error());
	$result = "0000-00-00 00:00:00";
	while ($row = mysql_fetch_array($rows, MYSQL_ASSOC)) {
		$lastUpdate = $row['Update_time'];
		if ($lastUpdate > $result) {
			$result = $lastUpdate;
		}
	}
	return $result;
}


//
// get an array of menu items from a database query and/or session object
//
function getMenus( $languageId ) {
	if ( (!isset($_SESSION['menus'])) || 
	     (!isset($_SESSION['menus_date'])) ||
	     ($_SESSION['menus_date'] < lastMenusUpdate())
	) {
		$menus =  array();
		$sql  = "SELECT m.menu_id, m.parent_menu_id, m.title, m.icon, m.href, m.sort_order, md.* ";
		$sql .= "FROM `menu` m ";
		$sql .= "INNER JOIN menu_description md ON md.menu_id = m.menu_id ";
		$sql .= "AND md.language_id =$languageId ";
		$sql .= "ORDER BY m.parent_menu_id, m.sort_order, m.menu_id;";
		$result = mysql_query($sql) or die('Query failed: ' . mysql_error());
		while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
			$menus[] = $row;
		}
		$_SESSION['menus'] = &$menus;
		$_SESSION['menus_date'] = date( "Y-m-d H:i:s" );
		mysql_free_result($result);
	}
	return $_SESSION['menus'];
}


//
// generate an HTML view of (possibly nested) menus, using UL and LI HTML-elements
//
function generateMenusView( &$menus, $id, $level, $noRaquo=FALSE ) {
	$listItems = "";
	$style = "";
	$width = 0;
	$j = count( $menus );
	for ($i=0; $i<$j; $i++) {
		$menu = $menus[$i];
		if ($menu['parent_menu_id'] != $id) {
			continue;
		}
		$title = $category['title'];
		$href = HTTP_SERVER."index.php?".htmlentities(urlencode($menu['href']));
		$subList = generateMenusView( $menus, $menu['menu_id'], $level+2, $noRaquo );
		$indent = str_repeat( "  ", $level+1 );
		$listItems .= ($i != 0) ? $indent : "";
		$listItems .= "<li><a href=\"$href\">";
		if (strlen($subList)>0) {
			if ($id==0) {
				$listItems .= htmlentities($title);
				$listItems .= ($noRaquo) ? "" : " »";
			}
			else {
				$listItems .= ($noRaquo) ? "" : " <span style=\"float:right;\">»</span>";
				$listItems .= htmlentities($title);
			}
		}
		else {
			$listItems .= htmlentities($title);
		}
		$listItems .= "</a>";
		$width = max( $width, strlen($title) );
		$listItems .= ($subList != "") ? "\n".$subList : "";
		$listItems .= ($subList != "") ? $indent : "";
		$listItems .= "</li>\n";
	}
	$result = "";
	if (strlen($listItems) > 0) {
		if ($id>0) {
			$width = round($width * 12.5) + (($width <= 10) ? 12.5*2 : 0);
			$indent = str_repeat( "  ", $level );
			$result = $indent;
			$result .= "<ul style=\"width:$width"."px;\">\n".$listItems;
			$result .= $indent;
			$result .= "</ul>\n";
		}
		else {
			$result = $listItems;
		}
	}
	return $result;
}

?>
The rendering magic of the UL and LI elements has of course to be CSS-driven, you could use the stylesheets from ADX Menu ( http://www.aplus.co.yu/adxmenu/) for this.
Last edited by JNeuhoff on Tue Aug 19, 2008 7:50 pm, edited 1 time in total.

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by Qphoria » Tue Aug 19, 2008 8:57 pm

JNeuhoff wrote: OK, assuming the following DB tables (I think each sub-menu can only have exactly one parent...):
You mean the tables are no good for multilevel nested?
JNeuhoff wrote: The rendering magic of the UL and LI elements has of course to be CSS-driven, you could use the stylesheets from ADX Menu ( http://www.aplus.co.yu/adxmenu/) for this.
LOL you really like that adxmenu eh? The css is easy once we get the table out into an unordered list.
Last edited by Qphoria on Tue Aug 19, 2008 9:18 pm, edited 1 time in total.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by Qphoria » Tue Aug 19, 2008 9:42 pm

While it isn't what we want just yet (as it uses multiple queries), I have a 10-line method working:

[php]
    function index() {   
        .......       
        $this->listMenu(0);
        .......
    }

    function listMenu ($parent, $level=0) {
        $database =& $this->locator->get('database');
       
        $sql = "SELECT menu_id, title, icon, href
                FROM ad_menu
                WHERE parent_id = " . $parent . " order by sort_order";
        $res = $database->query($sql);
        while (list ($title, $id) = mysql_fetch_row($res)) {
            $indent = str_repeat('---', $level);
            echo "$indent $title";
            $this->listMenu ($id, $level+1);
        }
    }
[/php]

Using 1 table (image attached)

I've checked a few other carts and a multi-query method is actually what they use for store front categories. I think for a storefront, the less db queries the better. For the backend, its not really that important. But I think we should keep working towards that goal. At least we have a possible backup plan with this. It even supports proper sort order per menu, per level

Attachments

???
ad_menu.jpg
Last edited by Qphoria on Wed Aug 20, 2008 2:50 am, edited 1 time in total.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by bruce » Tue Aug 19, 2008 10:31 pm

use the force luke...

you already have exactly what you need in the work you did on the category menus

give the menus a path and the job is done

Active Member

Posts

Joined
Wed Dec 12, 2007 2:26 pm

Post by Qphoria » Tue Aug 19, 2008 10:40 pm

LOL. Like I said above, I can't give it a path from a sql file because the paths might not line up. The only way would be to have a structured admin menu importer that could create the path as it is added.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by JNeuhoff » Tue Aug 19, 2008 10:48 pm

You mean the tables are no good for multilevel nested?
Well, I was thinking that the menus are strictly in a hierarchy, with no limit to the number of nested levels. No sub-menu can have more than one parent, it really is a sort of
  menu ---- many-to-one ----menu
hence we don't need the 'menu_to_menu' table. All we need is a foreign key in the menu table itself: 'parent_menu_id' in this case.
Last edited by JNeuhoff on Tue Aug 19, 2008 10:52 pm, edited 1 time in total.

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by Qphoria » Wed Aug 20, 2008 2:52 am

Ah.. yea that is what I was finding too, even with the multiple-query method i posted above, it only needed one table with the parent_id in it.

I am going to try your code and ogun's to see what I can do with it.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by Qphoria » Wed Aug 20, 2008 4:22 am

Ahh.. good news! I managed to modify ogun's code to work with the admin menu!

It currently makes a proper tree for all levels, but only makes 2 levels. I'm sure that can be modified pretty easily. It even appears to respect sort_order.

From what I could tell, there was a problem that I ran into with returning the output variable from the recursive tree listing. I am not a complete pro with recursive loops yet so for now I just made the output a global variable so I didn't have to worry about returning anything and losing what was already there, this may have been a problem for you too when you first made this.

I actually like this setup too because it is all combined into one file instead of using external libraries. Only 2 small functions.
It also doesn't rely on a "path" which makes it ideal for the Admin menu as well as being more versatile on the categories side

Nice work ogun!

I will work on getting multiple levels going and style up a demo.

Stay tuned.
Last edited by Qphoria on Wed Aug 20, 2008 4:25 am, edited 1 time in total.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by Qphoria » Wed Aug 20, 2008 9:39 pm

Ahoy! We are soooo close! My eyes are crossing looking at the css. I got the listing working perfect and the css works for the first 2 levels, but shows ALL 3rd levels at the same time. Need to figure out how to hide the 3rd levels until hovering their parent. I think it's like some one-liner that I'm overlooking.

Maybe you guys can take a look:

DEMO (user:demo / pass:demo) - Put your mouse over "Admin->Configuration". Notice all menus after that popout, especially the User sub and the Localisation sub overlapping. Need to hide them until you mouse over the parent menu.

If you got FF Web developer then take a crack at EditCSS (menu.css), otherwise to just look at the css here

The menu structure is a simple UL based menu, each sub goes down by one ul:

Code: Select all

<div class="adminMenu">
  <ul>
    <li>Admin
      <ul>
        <li>Home</li>
        <li>Catalog</li>
        <li>Configuration
          <ul>
            <li>Setting</li>
....
....
....
          </ul>
        </li>
      </ul>
    </li> 
  </ul>
</div>
Last edited by Qphoria on Wed Aug 20, 2008 9:44 pm, edited 1 time in total.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by ogun » Wed Aug 20, 2008 9:53 pm

that's looking great :)
if you don't mind waiting until tomorrow evening i can have a go at the css then. got a vertical cascading menu that i should be able to convert to horizontal easily enough. iirc there's also a bit of js that needs to go into the page header to make the menu behave in the same way between different versions of ie and firefox.

Active Member

Posts

Joined
Tue Aug 14, 2007 6:04 am

Post by Qphoria » Wed Aug 20, 2008 10:21 pm

ogun wrote: that's looking great :)
if you don't mind waiting until tomorrow evening i can have a go at the css then. got a vertical cascading menu that i should be able to convert to horizontal easily enough. iirc there's also a bit of js that needs to go into the page header to make the menu behave in the same way between different versions of ie and firefox.
Oh noes! not js! I assume you mean the csshover.htc bit. Cursed IE6

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by JNeuhoff » Thu Aug 21, 2008 12:24 am

Cursed IE6
Indeed!

As you know, I always use the ADX Menu (CSS styles for nested unordered lists), and in all web browsers its CSS-only rendering, but IE6 always requires some terrible Javascript-based workarounds.

Export/Import Tool * SpamBot Buster * Unused Images Manager * Instant Option Price Calculator * Number Option * Google Tag Manager * Survey Plus * OpenTwig


User avatar
Guru Member

Posts

Joined
Wed Dec 05, 2007 3:38 am


Post by Qphoria » Thu Aug 21, 2008 1:19 am

;D :D
I tried the adx css from your site and it actually worked properly when i modified the code a bit. I'll have to check for what missing in the current css.  : ;)

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by Qphoria » Fri Aug 22, 2008 5:35 am

Ok. I got the CSS working :) It might need some "cleaning up" but it works. The colors aren't quite right yet, but  IT WORKS :)

DEMO (user:demo/pass:demo)

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by bruce » Fri Aug 22, 2008 7:45 am

It is a good start and from my limited testing...

Firefox  = behaves nicely in firefox 2.0.0.16
IE6      = menu bar but no menus (yes this browser is a travesty but still in common use)
IE7      = not tested
Safari  = menus disappear unexpectedly with fast mouse movement
Opera  = behaves nicely in Opera 9.51

However, in all browsers, the menus disappear instantly when the mouse moves out of the menu area. They should really persist for a little while to allow for slight user inaccuracy with the mouse.

Before you spend too much more time trying to get a "pure" css menu, have a look at http://apptools.com/rants/jsmenu.php for an interesting discussion and some techniqes for what you are trying to do.

cheers

Bruce

Active Member

Posts

Joined
Wed Dec 12, 2007 2:26 pm

Post by Qphoria » Fri Aug 22, 2008 8:01 am

bruce wrote:
IE6       = menu bar but no menus (yes this browser is a travesty but still in common use)
IE7       = not tested
IE7 works perfect.
FF3.x works perfect.

I know, I still need to add the csshover.htc for IE6, as well as some IE fixes.
There's actually another "hack" i saw for IE6 and other compatibility issue that doesn't seem to require the js for ie6. Take a look at the source of this demo. This is claimed to be the definitive perfect css only menu with full support across all browsers without js. It uses conditional IE6 statements to add "extras" when using IE6. I haven't added those conditional statements to this menu tho.
bruce wrote: However, in all browsers, the menus disappear instantly when the mouse moves out of the menu area. They should really persist for a little while to allow for slight user inaccuracy with the mouse.
Well yea, that's of course the single downside of having no javascript.
bruce wrote: Before you spend too much more time trying to get a "pure" css menu, have a look at http://apptools.com/rants/jsmenu.php for an interesting discussion and some techniqes for what you are trying to do.
I'm not against a little bit of javascript for making it a bit more "robust". I was just against the existing way of putting the entire menu into a javascript script file. For delay we can add a simple onHover script to the links and put a 3 line timer function while keeping the menu completely designed by css and stored in the database.
Last edited by Qphoria on Fri Aug 22, 2008 8:06 am, edited 1 time in total.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by ogun » Fri Aug 22, 2008 5:54 pm

that's looking great Qphoria, nice work!

would be tempted to go for a straightforward ie conditional statement in the header around the csshover fix rather than taking the cssplay route. there are still people out there with ancient browsers, but they probably don't have any money so an online shop doesn't need to worry about them too much :)

for the disappearing menus on mouseout, an invisible area around the menus (e.g. some padding in the containing ULs) would cover most user inaccuracies with the mouse.

would it be worth waiting for this:
Daniel wrote: You can expect a demo of the new admin section soon.
..before going much further? maybe Daniel's already removed the js/changed how the menu works.

Active Member

Posts

Joined
Tue Aug 14, 2007 6:04 am
Who is online

Users browsing this forum: No registered users and 2 guests