It is a very common occurrence to need to open a menu link in a new tab. Currently the prescribed way to do this is to create a Template for the Menu Items. This involves a lot of manual implementation (verbose template code, helper methods, changing the menu item object to not use the Url property so as to override the default UrlField behavior). This is a lot of extra work to accomplish a very common and simple task.
I propose that a new property be introduced to the Menu component (to be added to Menu Items) - a boolean field that defines whether or not to open the link in a new tab (i.e. "NewTab", or "External", or something of the like). It could default to false so that, in most cases, it could be ignored. But if set to true, the Menu component would handle adding "target='_blank'" and "rel='noopener noreferer'" to the link, while leaving all of the other functionality and styling in place.
It would greatly simplify the usage. And I would suggest that every programming who is building navigation menus would have a case where it's needed.
I would think, though I haven't looked at the core code yet, that this would be a relatively simple feature to add.
public class MenuItem
{
public string Text { get; set; }
public ISvgIcon? Icon { get; set; }
public string Url { get; set; } = string.Empty;
public bool NewTab { get; set; } = false;
public List<MenuItem>? Items { get; set; }
public MenuItem(string text, ISvgIcon? icon, string url, bool newTab, List<MenuItem>? items)
{
Text = text;
Icon = icon;
Url= url;
NewTab = newTab;
Items = items;
}
}Currently, if a sub-menu is opened and the user moves the mouse back to a different parent item, the whole menu is closed.
Video: https://app.screencast.com/rcdHp9oklAU4z
Reproduction: https://blazorrepl.telerik.com/mxuClvaB36CB47v425
===
ADMIN EDIT
===
This bug also affects the ContextMenu component.
The current implementation of the component has hardcoded values for the alignment of the popup - e.g.:
for horizontal orientation: left horizontal align and bottom vertical align
for vertical orientation: right horizontal align and top vertical align
Ideally, those should be customizable to facilitate various use-cases.
I'm using the Menu component and I am handling the OnClick event. I noticed that when an exception is thrown in its handler, it does not reach the ErrorBoundary.
===
ADMIN EDIT
===
This issue also affects the SplitButton component.
Hello,
If I disable a Menu item at runtime, it prohibits access to child items via the mouse, but still opens the child group of items if I use the keyboard navigation.
Here is a test page with a workaround included (which is to recreate the Menu).
<TelerikButton OnClick="@DisableItem">Disable Services item</TelerikButton>
<TelerikButton OnClick="@EnableItem">Enable Services item</TelerikButton>
@if (ShowMenu)
{
<TelerikMenu Data="@MenuItems" />
}
@code {
List<MenuItem> MenuItems { get; set; }
bool ShowMenu { get; set; } = true;
async Task DisableItem()
{
MenuItems.Find(x => x.Text == "Services").Disabled = true;
MenuItems = new List<MenuItem>(MenuItems);
// workaround start
ShowMenu = false;
await Task.Delay(1);
ShowMenu = true;
// workaround end
}
async Task EnableItem()
{
MenuItems.Find(x => x.Text == "Services").Disabled = false;
MenuItems = new List<MenuItem>(MenuItems);
}
protected override void OnInitialized()
{
MenuItems = new List<MenuItem>()
{
new MenuItem()
{
Text = "Company",
Items = new List<MenuItem>()
{
new MenuItem()
{
Text = "Overview"
},
new MenuItem()
{
Text = "Events"
}
}
},
new MenuItem()
{
Text = "Services",
Items = new List<MenuItem>()
{
new MenuItem()
{
Text = "Consulting"
},
new MenuItem()
{
Text = "Education"
}
}
}
};
base.OnInitialized();
}
public class MenuItem
{
public string Text { get; set; }
public bool Disabled { get; set; }
public List<MenuItem> Items { get; set; }
}
}
Currently, on mobile devices (where is no hover), to open the child menu you need to click/tap the parent and the only way close it afterwards is if you click away. This is not very convenient for mobile usage. I want to be able to close the child menu on click/tap of the parent as well.
While the menu is usable the way it is, it could be better. If you take a look at the example menu in the best practices link that I provided in the original post, you will see what I mean. Some of the differences include the following:
Best practices example: https://www.w3.org/TR/wai-aria-practices-1.1/examples/menubar/menubar-1/menubar-1.html
I'd like to be able to build a custom menu that contains other controls and that is similar to the ones on the grid column menu but usable from anywhere.
The closest I can get with Telerik controls is the Menu with custom templates, but ideally I could anchor the menu to a button that has a custom icon or text (vs hovering over a hyperlink)
The Menu uses the NavigationManager to go to the pages that are assigned to the individual MenuItem objects. Is there a way to pass the "force load" value to these menu items?
-------------------- ADMIN EDIT --------------------
You can work around the issue if you skip setting Url field of the items that you want to force load and set your own property. Then, handle OnClick of the menu items and check if this property is set and manually call the navigation manager for the URL. You can see the code for this approach below:
public List<MenuItem> MenuItems { get; set; }
protected void OnClickHandler(MenuItem item)
{
if (item.ForceLoadUrl != null)
{
navManager.NavigateTo(item.ForceLoadUrl, true);
}
}
public class MenuItem
{
public string Text { get; set; }
public string Url { get; set; }
public string ForceLoadUrl { get; set; }
public List<MenuItem> Items { get; set; }
}
protected override void OnInitialized()
{
MenuItems = new List<MenuItem>()
{
new MenuItem()
{
Text = "site.css",
ForceLoadUrl = "/css/site.css"
},
new MenuItem()
{
Text = "Counter",
Url = "/counter"
},
new MenuItem()
{
Text = "Fetch Data",
Url = "/fetchdata"
}
};
base.OnInitialized();
}
I need to style the entire menu item, not just my template, but there are classes from the menu that I cannot override with my code or template.
If the collection you pass to the Menu Data parameter is null or empty, you will get an exception like this
System.ArgumentNullException: Value cannot be null. (Parameter 'source')