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>