Adding "flyouts" (expanding menus) to navigation in 2.1?

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
12 years ago
Hi all

I want to know about adding "flyouts" to the menu (mainly product categories but, to any db-driven one in nop 2.x).  I found the following posted in a more obscure thread on this board and am wondering the same thing as the original poster.  Can any of the more experienced developers familiar with 2.x please comment?

Here is the original post by user "Geralt" on https://www.nopcommerce.com/boards/t/2558/change-category-navigation-to-correct-xhtml.aspx:

....trying to use flyouts for the navigation. Finding no solution I decided to give it a go.

For a super easy fix, I found you can just store some "ul/li" strings in the viewbag in the Controllers/CatalogController.cs/ GetChildCategoryNavigationModel() and it works, but I thought this broke the whole MVC concept (I can post this fix if anyone was interested). So I tried again and came up with the following that follows the MVC pattern more.

Also, please bare in mind I'm super new to the .net/mvc platform, and this is the first time I've tried to use NopCommerce, (or any .net site for that matter), so if I did anything horribly wrong or you can improve this please post about it.

The version of NopCommerce I'm using is 2.1. The final version I posted here uses a partial view--I did it with just an Html helper at first. I don't know which way is better. I can post the helper function too if anyone wanted to see it.

Create a new partial view as "Views/Catalog/_CategoryNavigation.cshtml". The contents are as follows:

_CategoryNavigation.cshtml [new]


@if (Model.Count > 0)
{
    <ul>
    @foreach (var category in Model)
    {
        <li>
        <a href="@Url.RouteUrl("Category", new { categoryId = category.Id, SeName = category.SeName })">@category.Name
            @if (category.DisplayNumberOfProducts)
            {
                <text> (@(category.NumberOfProducts))</text>
            }
        </a>@{Html.RenderPartial("_CategoryNavigation", (IList<Nop.Web.Models.Catalog.CategoryNavigationModel>)category.CategoryNavigationModels);}</li>
    }
    </ul>
}



Adjust "/Views/Catalog/CategoryNavigation.cshtml" as follows:

CategoryNavigation.cshtml [edit]


@model IList<CategoryNavigationModel>

@using Nop.Core.Domain.Catalog
@using Nop.Core.Infrastructure
@using Nop.Services.Catalog
@using Nop.Web.Models.Catalog
@if (Model.Count > 0)
{
    <div class="block block-category-navigation">
        <div class="title">
            @T("Categories")
        </div>
        <div class="clear">
        </div>
        <div class="listbox">
            @{Html.RenderPartial("_CategoryNavigation", (IList<CategoryNavigationModel>)Model);}
        </div>
    </div>
}



Add a new IList to the "/Models/Catalog/CategoryNavigationModel.cs" as follows:

CategoryNavigationModel.cs [edit]


using System.Collections.Generic;
using Nop.Web.Framework.Mvc;

namespace Nop.Web.Models.Catalog
{
    public class CategoryNavigationModel : BaseNopEntityModel
    {
        public string Name { get; set; }

        public string SeName { get; set; }

        public int NumberOfParentCategories { get; set; }

        public bool DisplayNumberOfProducts { get; set; }
        public int NumberOfProducts { get; set; }

        public bool IsActive { get; set; }

        public IList<CategoryNavigationModel> CategoryNavigationModels { get; set; }
    }
}



Change the "/Controllers/CatalogController.cs" as follows (line 341-366):

CatalogController.cs [edit]


[NonAction]
private IList<CategoryNavigationModel> GetChildCategoryNavigationModel(IList<Category> breadCrumb, int rootCategoryId, Category currentCategory, int level)
{
    var result = new List<CategoryNavigationModel>();
    foreach (var category in _categoryService.GetAllCategoriesByParentCategoryId(rootCategoryId))
    {
        var model = new CategoryNavigationModel()
        {
            Id = category.Id,
            Name = category.GetLocalized(x => x.Name),
            SeName = category.GetSeName(),
            IsActive = currentCategory != null && currentCategory.Id == category.Id,
            NumberOfParentCategories = level,
            CategoryNavigationModels = GetChildCategoryNavigationModel(breadCrumb, category.Id, currentCategory, level + 1)
        };

        if (_catalogSettings.ShowCategoryProductNumber)
        {
            model.DisplayNumberOfProducts = true;
            model.NumberOfProducts = GetNumberOfProducts(category, _catalogSettings.ShowCategoryProductNumberIncludingSubcategories);
        }
        result.Add(model);

        //3 lines removed here
    }
            
    return result;
}



Keep in mind this code will return all categories on all pages - again its meant for use with flyouts. If everything worked like it should, your category should be output something like:

<div class="listbox">
    <ul>
        <li><a href="/c/1/books">Books </a></li>
        <li><a href="/c/2/computers">Computers </a>
            <ul>
                <li><a href="/c/3/desktops">Desktops </a>
                    <ul>
                        <li><a href="/c/19/alienware">Alienware </a>
                            <ul>
                                <li><a href="/c/21/aurora">Aurora </a></li>
                            </ul>
                        </li>
                        <li><a href="/c/20/dell">Dell </a></li>
                    </ul>
                </li>
                <li><a href="/c/4/notebooks">Notebooks </a></li>
                <li><a href="/c/5/accessories">Accessories </a></li>
                <li><a href="/c/7/games">Games </a></li>
                <li><a href="/c/6/software">Software </a></li>
            </ul>
        </li>
        <li><a href="/c/8/electronics">Electronics </a>
            <ul>
                <li><a href="/c/9/camera-photo">Camera, photo </a></li>
                <li><a href="/c/10/cell-phones">Cell phones </a></li>
            </ul>
        </li>
    </ul>
</div>
12 years ago
Anyone??
12 years ago
Bump...

I am really curious as to why this post hasn't been replied to.  

Have I gone offside in some way?

Thanks,
nopCanuck
12 years ago
I was given this link from another post.

I'll try this when I get home tonight and see if it works and let you know.

You might want to move this to the customisations thread rather than general support.

Kind Regards,
12 years ago
Okay,

I got this implemented and it does the job of getting it into this kind of layout.

<div class="listbox">
    <ul>
        <li><a href="/c/1/books">Books </a></li>
        <li><a href="/c/2/computers">Computers </a>
            <ul>
                <li><a href="/c/3/desktops">Desktops </a>
                    <ul>
                        <li><a href="/c/19/alienware">Alienware </a>
                            <ul>
                                <li><a href="/c/21/aurora">Aurora </a></li>
                            </ul>
                        </li>
                        <li><a href="/c/20/dell">Dell </a></li>
                    </ul>
                </li>
                <li><a href="/c/4/notebooks">Notebooks </a></li>
                <li><a href="/c/5/accessories">Accessories </a></li>
                <li><a href="/c/7/games">Games </a></li>
                <li><a href="/c/6/software">Software </a></li>
            </ul>
        </li>
        <li><a href="/c/8/electronics">Electronics </a>
            <ul>
                <li><a href="/c/9/camera-photo">Camera, photo </a></li>
                <li><a href="/c/10/cell-phones">Cell phones </a></li>
            </ul>
        </li>
    </ul>
</div>

I will try to now get the flyout working with CSS.
12 years ago
Excellent, got this all working now. :o) Moved it into where the HeaderMenu is so that it is a drop style :o)

Cheers nopCanuck.
12 years ago
Hi guys,

I implemented this with succes in V2.2 but I'm new to MVC so: can you provide me the steps/examples to implement the categories on the place where now the home/new products etc links are in the Darkorange theme?

thx!
12 years ago
This is what I have done in both 1.8 but and now doing in 2.2. The example below is for 2.2.
I am also waiting on this post to see if this is a better way to go (https://www.nopcommerce.com/boards/t/12233/customised-menu.aspx)

MOVE CATEGORIES MENU to HEADER

Recomend viewing this page and follow these instructions on all changes:
http://blog.csharpwebdeveloper.com/2011/09/27/cheat-sheet-for-effectively-extending-nopcommerce/

I did not show how to reference new files. So I you don't know how to do that then changing the following will move the categories to the header but might not help you during the next upgrade



Downloaded:
SuperfishMenu.js
(http://plugins.jquery.com/node/3355)
Customized the CSS files to work for me. (not shown)
It really doesn't matter where you put the category menu when you use this.


Below are all the files I have modified but created seperate files prepare for future upgrades

1.)
HeaderMenu.cshtml (only file that I did not create seperate file for)

@{
    //current category ID
    int currentCategoryId = 0;
    if (Url.RequestContext.RouteData.Values["controller"].ToString().Equals("catalog",

StringComparison.InvariantCultureIgnoreCase) &&
        Url.RequestContext.RouteData.Values["action"].ToString().Equals("category",

StringComparison.InvariantCultureIgnoreCase))
    {
        currentCategoryId = Convert.ToInt32(Url.RequestContext.RouteData.Values["categoryId"].ToString());
    }
    }

<div class="headermenu">
    @Html.Partial("~/Views/Catalog/_SearchBox.cshtml")
    @Html.Action("CategoryNavigation_LMN", "Catalog", new { currentCategoryId = currentCategoryId })
    @Html.Action("Menu", "Common")
    
</div>

2.) (had to change this quite a bit)
CategoryNavigation.cshtml (created copy and used copy)

    <ul class="sf-menu" id="sf-lmn">
        <li>
        @T("Categories")
            <ul>

                @foreach (var category in Model)
                {
                    <li class="@(category.IsActive ? "active" : "inactive")"
                    @if (category.NumberOfParentCategories > 0)
                    {
                        //TODO we hard-coded 'margin-left'. But we should set 'margin-right' for RTL languages
                        if (this.ShouldUseRtlTheme())
                        {
                        <text>style="margin-right: @(category.NumberOfParentCategories * categoryPadding)

px"</text>
                        }
                        else
                        {
                        <text>style="margin-left: @(category.NumberOfParentCategories * categoryPadding)

px"</text>
                        }
                    }
                    ><a href="@Url.RouteUrl("Category", new { categoryId = category.Id, SeName =

category.SeName })">@category.Name
                        @if (category.DisplayNumberOfProducts)
                        {
                            <text> (@(category.NumberOfProducts))</text>
                        }
                    </a></li>
                }

            </ul>
        </li>
    </ul>


3.) (simply commented out the category navigation)
_ColumnsTwo.CShtml (created copy and used copy)

  @*
  @Html.Action("CategoryNavigation", "Catalog", new { currentCategoryId = currentCategoryId })
        <div class="clear">
        </div>
  *@


Hope this is helpful.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.