You are viewing this forum as a guest. Login to an existing account, or create a new account, to reply to topics and to create new topics.
I posted this originally for ccp6 but thought I would re-post this mod for ccp7 code base.
I haven't seen any problems yet on the browsers I have tested it on with the exception of FF on Mac which I think is coming from some of the developer extensions I have installed into FF as when I tested on a machine that had a standard install of FF it worked with out a problem, other wise it was a little slow responding and the menus collapsed when the pointer rested a bit.
Your going to change some core scripts here so it will be subject to be overwritten in updates and as always you should make copies of the files affected just in case.
This is going to be a long post but we will first start with a new row in the core_settings database at System Dashboard > System > Database > Raw Database Adminn with the following:
id = ecom.menusubdisp
name = Front Menu Sub-Category Display.
app = ecom
section = Catalog Global Displays
displaytype = SELECT-CUSTOM
displaydata = ecom.submenudisp
required = 1
value = 3
descripton = Select the number of sub-categories to be displayed under main menu items.
next create 4 new entries into the core_selectcustom database:
id = ecom.submenudisp.0
app = ecom
selectid = ecom.submenudisp
selectname = No Sub-Categories
selectvalue = 0
selectorder = 0
id = ecom.submenudisp.1
app = ecom
selectid = ecom.submenudisp
selectname = One Sub-Categories
selectvalue = 1
selectorder = 1
id = ecom.submenudisp.2
app = ecom
selectid = ecom.submenudisp
selectname = Two Sub-Categories
selectvalue = 2
selectorder = 2
id = ecom.submenudisp.3
app = ecom
selectid = ecom.submenudisp
selectname = Three Sub-Categories
selectvalue = 3
selectorder = 3
This will give you a new field in System Dashboard > Store > Component > Settings > Catalog Global Displays which will allow you to either limit the number of sub-categories or turn it off completely.
Next you will need to place this java script in your public_dir/media/script directory which I originally got from Dymanic Drive for there SuckerTree UL menu but any java script that deals with ul list should be able to be used for this
I named my file femenus.js
//SuckerTree Vertical Menu 1.1 (Nov 8th, 06) //By Dynamic Drive: http://www.dynamicdrive.com/style/ var menuids=["skin_fenav1"] //Enter id(s) of SuckerTree UL menus, separated by commas function buildsubmenus(){ for (var i=0; i<menuids.length; i++){ var ultags=document.getElementById(menuids[i]).getElementsByTagName("ul") for (var t=0; t<ultags.length; t++){ ultags[t].parentNode.getElementsByTagName("a")[0].className="subfolderstyle" if (ultags[t].parentNode.parentNode.id==menuids[i]) //if this is a first level submenu ultags[t].style.left=ultags[t].parentNode.offsetWidth+"px" //dynamically position first level submenus to be width of main menu item else //else if this is a sub level submenu (ul) ultags[t].style.left=ultags[t-1].getElementsByTagName("a")[0].offsetWidth+"px" //position menu to the right of menu item that activated it ultags[t].parentNode.onmouseover=function(){ this.getElementsByTagName("ul")[0].style.display="block" } ultags[t].parentNode.onmouseout=function(){ this.getElementsByTagName("ul")[0].style.display="none" } } for (var t=ultags.length-1; t>-1; t--){ //loop through all sub menus again, and use "display:none" to hide menus (to prevent possible page scrollbars ultags[t].style.visibility="visible" ultags[t].style.display="none" } } } if (window.addEventListener) window.addEventListener("load", buildsubmenus, false) else if (window.attachEvent) window.attachEvent("onload", buildsubmenus)
now you will need to add or update some css entries in the skin's all.css, most of these should be in a standard ccp file but if you have a custom skin all bets are off, this is my total css for my menu (Most of these css rules currently exist but they have been changed from there default ccp rules).
.skin_fenav ul { color: inherit; background-color: inherit; padding: 0px; margin: 0px 0px 10px 0px; list-style: none; width: auto; } .skin_fenav ul li { color: inherit; background-color: inherit; padding: 0px; margin: 0px; border-bottom: 1px solid #CDCDCD; list-style: none; position: relative; } .skin_fenav ul li a { color: #333333; background-color: inherit; font-weight: normal; display: block; text-decoration: none; padding: 3px 5px 3px 5px; overflow: auto; /*force hasLayout in IE7 */ } .skin_fenav ul li a:hover { color: #333333; background-color: #CCCCCC; text-decoration: none; } /* add to css */ .skin_fenav ul li ul { position: absolute; width: 130px; /*sub menu width*/ top: 4px; visibility: hidden; background-color: #FFFFFF; background-repeat: repeat; border: 2px solid #C2C2C2; z-index: 4; } .subfolderstyle { background: url(navarrow.png) no-repeat center right; z-index: 4 } /* end of add */
you may need to fine tune the css to fit your site and even create a navearrow (or what ever you name it) picture for the subforderstyle if you want it to display and or correct the url paths. I just created a images directory inside my skin css directory to hold my images called in my css calles.
In the java scrip the variable var menuids=["skin_fenav1"] needs to hold the name of the menu we are going to build, you will notice that it is different than the css (with an add 1 in the name) which I will explain latter but can be anything.
Next place a call for the java script in the head section of the skin's skin.php file
<script type="text/javascript" src="/media/scripts/femenu.js"></script>
Now comes the really fun part, we are going to edit two core files, the first resides in the private_dir/your_directory_name/apps/ecom/ECOM/ext, in the script skinwidgets.php is where we are going to edit the "Function: categories" I am going to post the entire function but all edits are surrounded or pre-seeded by the commit "SLP"
// +------------------------------------------------------------------+ // | Function: categories | // +------------------------------------------------------------------+ function categories () { // +-- // | This function prints the categories widget. // +-- // +--- // | SLP added xcat to fields pulled in sql statement below and the // | call to get the sub folder variable. // +--- $sublevel = $this->globals('core_settings.ecom.menusubdisp'); $table = 'ecom_cat'; $sql = "SELECT id, name, xcat FROM {$table} WHERE splashdisp="; $sql .= $this->CORE_DB->quote(1) . " AND "; // +------------------------ // +-- // | Handle visibility. // +-- $usergroup = $this->globals('core_user.usergroup'); if (empty($usergroup)) { $sql .= 'catview=' . $this->CORE_DB->quote('A'); } else { $sql .= '((catview=' . $this->CORE_DB->quote('A') . ') OR '; $sql .= '(catview=' . $this->CORE_DB->quote('L') . ' AND '; $sql .= '(catviewg LIKE ' . $this->CORE_DB->quote_like($usergroup . ',', 'SUFFIX') . ' OR '; $sql .= 'catviewg LIKE ' . $this->CORE_DB->quote_like(',' . $usergroup, 'PREFIX') . ' OR '; $sql .= 'catviewg LIKE ' . $this->CORE_DB->quote_like(', ' . $usergroup, 'PREFIX') . ' OR '; $sql .= 'catviewg LIKE ' . $this->CORE_DB->quote_like(',' . $usergroup . ',', 'WRAP') . ' OR '; $sql .= 'catviewg LIKE ' . $this->CORE_DB->quote_like(', ' . $usergroup . ',', 'WRAP') . ' OR '; $sql .= 'catviewg=' . $this->CORE_DB->quote($usergroup) . ')))'; } // End of if statement. // +-- // | Execute the query. // +-- $result = $this->CORE_DB->sql_do(array('sql' => $sql, 'table' => $table, 'order' => array('sortorder' => 'ASC'))); if ($this->IsError($result)) {return 1;} if (empty($result)) {return 1;} // +-- // | Build the menu array. // +-- $menu_array = array(); // +--- // | SLP add for fly out menu. Get menu items that are not main displays. // +--- $sql = "SELECT id, name, xcat FROM {$table} WHERE splashdisp="; $sql .= $this->CORE_DB->quote(0); $result2 = $this->CORE_DB->sql_do(array('sql' => $sql, 'table' => $table, 'order' => array('sortorder' => 'ASC'))); //+--------------- $sub1 = ''; $sub2 = ''; $sub3 = ''; foreach ($result as $num => $row) { // +--- // | SLP added for fly-out menu. Start building the display if we are allowed to. // +--- If (($sublevel >= '1') && (!(empty($row['xcat'])))) { $xsub1 = explode(",",$row['xcat']); // +--- // | Setup first level fly-out build. // +--- foreach ($xsub1 as $num => $xrow) { $xid = trim($xrow," ,\n,\r"); foreach ($result2 as $num => $xresult2) { // +--- // | Setup second level fly-out. // +--- if ($xid == $xresult2['id']) { $xsub2 = explode(",",$xresult2['xcat']); $name = $xresult2['name']; } // End of if statement. } // End of foreach statement. if (($sublevel >= '2') && (!(empty($xsub2[0])))) { foreach ($xsub2 as $num => $xrow2) { $xid2 = trim($xrow2," ,\n,\r"); // +--- // | Setup third level fly-out. // +--- foreach ($result2 as $num => $xresult3) { if ($xid2 == $xresult3['id']) { $name2 = $xresult3['name']; $xsub3 = explode(",",$xresult3['xcat']); } // End of if statement. } // End of foreach statement. if (($sublevel >= '3') && (!(empty($xsub3)))) { foreach ($xsub3 as $num => $xrow3) { $xid3 = trim($xrow3,"\n, ,\r"); foreach ($result2 as $num => $xresult4) { if ($xid3 == $xresult4['id']) {$name3 = $xresult4['name'];} } // End of foreach statement. // +--- // | Build third level array. // +--- if (!(empty($name3))) { $sub3[] = array('text' => $name3, 'app' => 'ecom', 'namespace' => 'catshow', 'params' => array('ref' => $xid3)); unset($name3); } // End of if statement. } // End of foreach statement. } // End of if statement. // +--- // | Build second level array. // +--- if (!(empty($name2))) { $sub2[] = array('text' => $name2, 'app' => 'ecom', 'namespace' => 'catshow', 'params' => array('ref' => $xid2), 'sub3' => $sub3); unset($name2); } // End of if statement. $sub3 = ''; } // End of foreach statement. } // End of if statement. if (!(empty($name))) { $sub1[] = array('text' => $name, 'app' => 'ecom', 'namespace' => 'catshow', 'params' => array('ref' => $xid), 'sub2' => $sub2); unset($name); } // End of if statement. $sub2 = ''; } // End of foreach statement. } // End of if statement. // +--------------------------------- // | SLP added subcat key to menu_array. // +--- $menu_array[] = array('text' => $row['name'], 'app' => 'ecom', 'namespace' => 'catshow', 'params' => array('ref' => $row['id']), 'subcat' => $sub1); // +--- // | SLP added. // +--- $xsub1 = ''; $sub1 = ''; } // End of foreach statement. if (empty($menu_array)) {return 1;} // +-- // | Globalize the menu array. // +-- $this->globals('core_app.skinwidget_categories',$menu_array); // +-- // | Print the generic frontend menu includes and log that we were here. // +-- $this->CORE_Display->include_file('ecom','skinwidgetcategories.php'); if ($this->debug) {$this->debugger("categories: Printed the categories widget. App: ecom");} // +-- // | Return true. // +-- return 1; } // End of function.
The second script resides in the private_dir/apps/ecom/ECOM/includes by the name of skinwidgetscategories.php, again the whole script. This is where the menu name used in the java script needs to be the name of the ul id in this line "print '<ul id="skin_fenav1">' . $eol; " in the include
<?php $widget_name = $this->xhtml_encode($this->globals('core_app.name_skinwidget_categories')); if (empty($widget_name)) {$widget_name = 'Categories';} $eol = $this->globals('core.eol'); $skinwidget_array = $this->globals('core_app.skinwidget_categories'); if (!(empty($skinwidget_array))) { print '<div class="skin_fenavh">' . $widget_name . '</div>' . $eol; print '<div class="skin_fenav">' . $eol; print '<ul id="skin_fenav1">' . $eol; foreach ($skinwidget_array as $num => $data) { $text = $this->xhtml_encode($data['text']); $link = $this->link_namespace($data['app'],$data['namespace'],$data['params']); print ' <li><a href="' . $link . '" title="' . $text . '">'; //+--- //| Setup the first menu fly out if we have information. //+--- if (!(empty($data['subcat']))) { $xsub1 = $data['subcat']; print $text . '</a>' . $eol; print '<ul>' . $eol; foreach ($xsub1 as $num => $xdata) { $textsub1 = $this->xhtml_encode($xdata['text']); $linksub1 = $this->link_namespace('ecom',$xdata['namespace'],$xdata['params']); print ' <li><a href="' . $linksub1 . '" title="' . $textsub1 . '">'; //+--- //| Setup the second menu fly out if we have information. //+--- if (!(empty($xdata['sub2']))) { $xsub2 = $xdata['sub2']; print $textsub1 . '</a>' . $eol; print '<ul>' . $eol; foreach ($xsub2 as $xdata2) { $textsub2 = $this->xhtml_encode($xdata2['text']); $linksub2 = $this->link_namespace('ecom',$xdata2['namespace'],$xdata2['params']); print ' <li><a href="' . $linksub2 . '" title="' . $textsub2 . '">'; //+--- //| Setup the third menu fly out if we have information. //+--- if (!(empty($xdata2['sub3']))) { $xsub3 = $xdata2['sub3']; print $textsub2 . '</a>' . $eol; print '<ul>' . $eol; foreach ($xsub3 as $xdata3) { $textsub3 = $this->xhtml_encode($xdata3['text']); $linksub3 = $this->link_namespace('ecom',$xdata3['namespace'],$xdata3['params']); print ' <li><a href="' . $linksub3 . '" title="' . $textsub3 . '">'; print $textsub3 . '</a></li>' . $eol; } // End of foreach statement. print '</ul>' . $eol; print '</li>' . $eol; unset($xsub3); } else { print $textsub2 . '</a></li>' . $eol; } // End of if statement. } // End of foreach statement. print '</ul>' . $eol; print '</li>' . $eol; unset($xsub2); } else { print $textsub1 . '</a></li>' . $eol; } // End of if statement. } // End of foreach statement. print '</ul>' . $eol; print '</li>' . $eol; unset($xsub1); } else { print $text . '</a></li>' . $eol; } // End of if statement. } // End of foreach statement. print '</ul>' . $eol . $eol; print '</div>' . $eol . $eol; } // End of if statement. ?>
If all is done correctly you will have a main menu display that will contain up to three levels of sub-categories, categories will be displayed in the order they are placed into each categories Related Categories fields (xcat). Since it all takes place after the menus are checked for the user group only those menu that the group is allowed to see will be displayed and at this time no main menu item will be displayed as a sub-cateogry but can be changed if needed. If you have a large number of menu items this may cause a longer load time but on my site I haven't seen any delays that I can say are from this mod and at this time it is building around 100 menu items.
Have fun.
John
Last edited by dh783 (04-08-2011 15:05:38)
Offline
The call for the java script in the head section of the skin's skin.php file should read
<script type="text/javascript" src="media/scripts/femenus.js"></script>
(Plural)
Offline
I have a very large number of menu items and this mod still worked great for me. My front page load time was a little over a half second before and a little over two and a half seconds after.
Offline
Hi
Can you point me to a site running this mod so I can have a look. I was looking for something to produce nested lists for categories on a site I am working on and this might reduce the admin weight of having to maintatin static menus formed from nested lists.
Thanks
Kenny
Offline
You can look at my site with the web link under my name, also fixmyrust.com and threedogsportinggoods.com which are currently using this mod and have quite a large menu listing.
John
Offline
Thanks for that
Looks like I might be able to do something with this though my client has had me add collapsible headers to the sidebar menus so it would need a bit extra nifty coding to incorporate the extra page elements to wrap the lists.(not impossible I suspect) I will keep this post in mind though as it does exactly what I was looking for when I set out.
Thanks, very useful
Kenny
Offline
Thanks for your great input, John
I have managed to implement on our Europecart 7 cart with good success, although with 2 issues I was hoping to hear if anyone has solved:
1. Breadcrumbs are behaving weird. It seems to keep adding pages.
2. IE7 z-index issue. I know this is a browser issue, but has anyone got a good workaround?
**EDIT** I found a workaround that works.. just needed to add z-index to a couple of css entries.
See: http://www.contextinteriors.co.uk/ec7/
Note this is the EC7 cart running in parallel with our old CCP6 cart, and awaiting last minor updates before we switch over.
Last edited by jonasaedin (12-10-2009 06:04:48)
Offline
John, it's very kind of you to share this work.
This feature is something I'm going to experiment with here because I'd very much like to use it.
(I'm a relative newbie to CCP7 but can follow clear instructions like those you gave, although I use a custom skin - that should be fun!).
I noticed however that in IE6 (yes I know it's old but a lot of people still use it...), the results seem flaky on two of the sites mentioned (contextinteriors and fixmyrust). Often the third cat level fails to appear, and often it appears but is unclickable - the menu collapses. Sometimes the first click on the third cat level works, but subsequent clicks fail - the menu collapses.
The ThreeSportingDogs site seems to work well in IE6, albeit a little slow (but judging by the overall site speed that might just be the hosting?).
So I just wondered, John, is the implementation on ThreeSportingDogs different to that on the other two sites?
Kind regards
Paul
Offline
The only thing that could be different between sites is the css rules involved that I know of. IE6 in my test is really bad at creating a display even with out this mod as I could never get the same look when all other would display thing correctly.
John
Offline
The percentage of people still using IE6 has, finally, reached the point of being insignificant really. You will drive yourself crazy if you try to continue to cater to severely outdated and badly broken browsers.
Offline
Just for reference - the contextinteriors website has not yet been adjusted for IE6.. we will probably opt for a dedicated CSS files for this and probably also disable the treesucker meny and just allow the tree to be visible at all times.
Hopefully need for IE6 compatibility will slowly dissapear. According to our current stats only very few access our working website using IE6.
Offline
Any quick fix for the breadcrumbs problem?
Offline
Has anyone got this to work in a horizontal dropdown?
Will it just be a case of rewriting the css, or is the mod "flyout" specific
Rich
Last edited by puredesign (01-14-2010 05:40:00)
Offline
I've used the horizontal version of the sucker menu as below:-
//SuckerTree Horizontal Menu (Sept 14th, 06) //By Dynamic Drive: http://www.dynamicdrive.com/style/ var menuids=["skin_fenav1"] //Enter id(s) of SuckerTree UL menus, separated by commas function buildsubmenus_horizontal(){ for (var i=0; i<menuids.length; i++){ var ultags=document.getElementById(menuids[i]).getElementsByTagName("ul") for (var t=0; t<ultags.length; t++){ if (ultags[t].parentNode.parentNode.id==menuids[i]){ //if this is a first level submenu ultags[t].style.top=ultags[t].parentNode.offsetHeight+"px" //dynamically position first level submenus to be height of main menu item ultags[t].parentNode.getElementsByTagName("a")[0].className="mainfoldericon" } else{ //else if this is a sub level menu (ul) ultags[t].style.left=ultags[t-1].getElementsByTagName("a")[0].offsetWidth+"px" //position menu to the right of menu item that activated it ultags[t].parentNode.getElementsByTagName("a")[0].className="subfoldericon" } ultags[t].parentNode.onmouseover=function(){ this.getElementsByTagName("ul")[0].style.visibility="visible" } ultags[t].parentNode.onmouseout=function(){ this.getElementsByTagName("ul")[0].style.visibility="hidden" } } } } if (window.addEventListener) window.addEventListener("load", buildsubmenus_horizontal, false) else if (window.attachEvent) window.attachEvent("onload", buildsubmenus_horizontal)
But there is something keeping the menu in a vertical format. The Javascript is working fine, as the submenu's are 'dropping down' absolutely fine.
Can anyone help me develop this so that we can share it on the forum?
Rich
Offline
I don't understand why you'd do this with JS instead of straight CSS. It's so much easier with CSS. Look at the menus on the kryptronic.com site - no JS. It's easy to position the ul and ul->li->ul that way so the menus are vertical instead of horizontal as shown.
Offline
jonasaedin wrote:
Just for reference - the contextinteriors website has not yet been adjusted for IE6.. we will probably opt for a dedicated CSS files for this and probably also disable the treesucker meny and just allow the tree to be visible at all times.
Hopefully need for IE6 compatibility will slowly dissapear. According to our current stats only very few access our working website using IE6.
Love your interiors site. We're thing of going to Europa cart from CCP 6, would you recommend the upgrade?
Cheers
Offline
Well there was a bit more work involved in doing the upgrade than I expected and there is still a few outstanding issues particularly re. UK VAT, google checkout and sitemap/HDSEO xmods which you will be able to read a lot more threads about if you search on these keywords in the forum. You will also find that some of the features that worked in the UK Clickart 6 version has suddenly dissapeared.
My Client, however, is fairly happy - he likes the new admin and some of the new features.
I am still not sure it was really worth the upgrade and have felt a bit let down by a slow reacting Kryptonic and an expensive support system, used to be much better in the old days.
On the other hand I am sure we will get there eventually and CCP7/EC7 still is a very nice and flexible cart.
Offline
thanks for your feedback jonasaedin,
will this new menu mod work in CCP6?
Offline
hi john, I had a quick search but struggled to find the post, can you post the link to it?
Thanks
Stu
Offline
excellent, cheers
Offline
Some changes where made to stop error messages being printed in the debug statement that where coming from the use of the unset statement, so these changes where made to the original code at your private_dir/your_dir/apps/ecom/ECOM/ext/skinwidget.php in function categories
declare the three sub array just before the foreach statement
$sub1 = ''; $sub2 = ''; $sub3 = ''; foreach ($result as $num => $row) {
and then replace the unset commands
unset($sub3):
with
$sub3 = '';
and
unset($sub2);
with
$sub2 = '';
and
unset($xsub1); unset($sub1);
with
$xsub1 = ''; $sub1 = '';
I have also corrected the first posting on this code above.
John
Last edited by dh783 (09-04-2010 22:37:40)
Offline