From 7e66c98dd50c4712003b1ea54da37035c84c3f3e Mon Sep 17 00:00:00 2001 From: Lombiq Date: Wed, 21 Oct 2015 19:52:03 +0200 Subject: [PATCH] Adding the ability to add a menu item under another item directly, #4009 --- .../Navigation/Controllers/AdminController.cs | 57 ++++++++++++++----- .../Navigation/Scripts/navigation-admin.js | 23 +++++++- .../Navigation/Styles/navigation-admin.css | 11 +++- .../Core/Navigation/Views/Admin/Index.cshtml | 6 +- 4 files changed, 79 insertions(+), 18 deletions(-) diff --git a/src/Orchard.Web/Core/Navigation/Controllers/AdminController.cs b/src/Orchard.Web/Core/Navigation/Controllers/AdminController.cs index a0b8087f2..da5c05a9d 100644 --- a/src/Orchard.Web/Core/Navigation/Controllers/AdminController.cs +++ b/src/Orchard.Web/Core/Navigation/Controllers/AdminController.cs @@ -34,7 +34,6 @@ namespace Orchard.Core.Navigation.Controllers { _menuService = menuService; _menuManager = menuManager; _navigationManager = navigationManager; - Services = orchardServices; T = NullLocalizer.Instance; Logger = NullLogger.Instance; @@ -155,7 +154,7 @@ namespace Orchard.Core.Navigation.Controllers { ModelState.AddModelError(key, errorMessage.ToString()); } - public ActionResult CreateMenuItem(string id, int menuId, string returnUrl) { + public ActionResult CreateMenuItem(string id, int menuId, string returnUrl, string parentMenuItemPosition = null) { if (!Services.Authorizer.Authorize(Permissions.ManageMenus, _menuService.GetMenu(menuId), T("Couldn't manage the main menu"))) return new HttpUnauthorizedResult(); @@ -164,25 +163,31 @@ namespace Orchard.Core.Navigation.Controllers { if (menuPart == null) return HttpNotFound(); - + // load the menu var menu = Services.ContentManager.Get(menuId); if (menu == null) return HttpNotFound(); - - try { - // filter the content items for this specific menu - menuPart.MenuPosition = Position.GetNext(_navigationManager.BuildMenu(menu)); - + + try { + if (!String.IsNullOrEmpty(parentMenuItemPosition)) { + var menuEntries = _menuService.GetMenuParts(menuId).Select(CreateMenuItemEntries); + menuPart.MenuPosition = GetNextChildPosition(menuEntries, parentMenuItemPosition); + } + else { + // filter the content items for this specific menu + menuPart.MenuPosition = Position.GetNext(_navigationManager.BuildMenu(menu)); + } + var model = Services.ContentManager.BuildEditor(menuPart); - + return View(model); } catch (Exception exception) { if (exception.IsFatal()) { throw; - } + } Logger.Error(T("Creating menu item failed: {0}", exception.Message).Text); Services.Notifier.Error(T("Creating menu item failed: {0}", exception.Message)); @@ -191,7 +196,7 @@ namespace Orchard.Core.Navigation.Controllers { } [HttpPost, ActionName("CreateMenuItem")] - public ActionResult CreateMenuItemPost(string id, int menuId, string returnUrl) { + public ActionResult CreateMenuItemPost(string id, int menuId, string returnUrl, string parentMenuItemPosition = null) { if (!Services.Authorizer.Authorize(Permissions.ManageMenus, _menuService.GetMenu(menuId), T("Couldn't manage the main menu"))) return new HttpUnauthorizedResult(); @@ -205,12 +210,18 @@ namespace Orchard.Core.Navigation.Controllers { if (menu == null) return HttpNotFound(); - + var model = Services.ContentManager.UpdateEditor(menuPart, this); - menuPart.MenuPosition = Position.GetNext(_navigationManager.BuildMenu(menu)); + if (!String.IsNullOrEmpty(parentMenuItemPosition)) { + var menuEntries = _menuService.GetMenuParts(menuId).Select(CreateMenuItemEntries); + menuPart.MenuPosition = GetNextChildPosition(menuEntries, parentMenuItemPosition); + } + else { + menuPart.MenuPosition = Position.GetNext( _navigationManager.BuildMenu(menu)); + } + menuPart.Menu = menu; - Services.ContentManager.Create(menuPart); if (!ModelState.IsValid) { @@ -222,5 +233,23 @@ namespace Orchard.Core.Navigation.Controllers { return this.RedirectLocal(returnUrl, () => RedirectToAction("Index")); } + + private static string GetNextChildPosition(IEnumerable menuItems, string parentMenuItemPosition) { + var parentMenuItemPositionPlusDot = parentMenuItemPosition + "."; + var childElements = menuItems.Where(childElement => childElement.Position.StartsWith(parentMenuItemPositionPlusDot)); + if (childElements.Any()) { + var result = childElements + .Select(childElement => { + var positionParts = childElement.Position.Substring(parentMenuItemPositionPlusDot.Length).Split(new[] { '.' }, 2, StringSplitOptions.RemoveEmptyEntries); + + return positionParts.Any() ? int.Parse(positionParts[0]) : 0; + }) + .Max(); + + return parentMenuItemPositionPlusDot + (result + 1); + } + + return parentMenuItemPositionPlusDot + "1"; + } } } diff --git a/src/Orchard.Web/Core/Navigation/Scripts/navigation-admin.js b/src/Orchard.Web/Core/Navigation/Scripts/navigation-admin.js index 08dc685de..a90905408 100644 --- a/src/Orchard.Web/Core/Navigation/Scripts/navigation-admin.js +++ b/src/Orchard.Web/Core/Navigation/Scripts/navigation-admin.js @@ -52,6 +52,27 @@ } }); - + $(function () { + $(".navigation-menu-item > div").on("click", function () { + if ($(".navigation-menu-item > div.menu-item-selected").length) { + if ($(this).hasClass("menu-item-selected")) { + $(this).removeClass("menu-item-selected"); + } + else { + $(".navigation-menu-item > div").removeClass("menu-item-selected"); + $(this).addClass("menu-item-selected") + } + } + else { + $(this).addClass("menu-item-selected"); + } + }); + + $(".menu-item-actions > .button").on("click", function (e) { + if ($(".navigation-menu-item > div.menu-item-selected").length) { + e.originalEvent.currentTarget.href = $(this).attr("href") + "&parentMenuItemPosition=" + $(".navigation-menu-item > div.menu-item-selected > .navigation-position > input").val(); + } + }); + }); })(jQuery); diff --git a/src/Orchard.Web/Core/Navigation/Styles/navigation-admin.css b/src/Orchard.Web/Core/Navigation/Styles/navigation-admin.css index 060019a1f..da095754e 100644 --- a/src/Orchard.Web/Core/Navigation/Styles/navigation-admin.css +++ b/src/Orchard.Web/Core/Navigation/Styles/navigation-admin.css @@ -172,4 +172,13 @@ .dir-rtl div.menu-item-actions { left:10px; right: inherit; - } \ No newline at end of file + } + +.navigation-menu li div.menu-item-selected { + background-color: #6a7b42; + color: #fff; +} + +.navigation-menu li div.menu-item-selected a { + color: #edf9f5; +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Navigation/Views/Admin/Index.cshtml b/src/Orchard.Web/Core/Navigation/Views/Admin/Index.cshtml index 5ba816e41..8841f4c23 100644 --- a/src/Orchard.Web/Core/Navigation/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Core/Navigation/Views/Admin/Index.cshtml @@ -46,6 +46,8 @@