Binding Menu Component to data with variable URLs

1 Answer 48 Views
Menu
Chris
Top achievements
Rank 1
Iron
Iron
Iron
Chris asked on 04 Sep 2024, 02:25 PM | edited on 04 Sep 2024, 02:27 PM

I have a menu component on my view, which gives access to actions that relate to the current record on screen - so in effect I need to have the menu items have URLs similar to the following :

/Controller/Action/{cust_id}/{action_type}

Where {cust_id} will relate to the main record loaded, and {action_type} is rendered from a list within the model of all the available actions. The text for the URLs need to show the action name.

I have tried binding my menu to the Model as per the code below - is there a  recommended way to pass in the variable elements, or do I have to abandon the ActionName and ControllerName below, and just construct the whole Url manually? I have put pseudo code in to show what I mean :

@( Html.Kendo().Menu() .Name("menu") // The name of the Menu is mandatory. It specifies the "id" attribute of the widget. .BindTo(Model.TaskTypes, mappings => { mappings.For<CRM.Core.CRM.TaskType>(binding => binding // Define the first level of the Menu. .ItemDataBound((item, type) => // Define the mapping between the Menu item properties and the model properties. { item.Text = type.TaskTypeName; item.ActionName = "New"; item.ControllerName = "Task";
item.SomePropertyHere = model.CustomerId; item.SomeOtherPropertyHere = type.TaskTypeId; })); }) )



Chris
Top achievements
Rank 1
Iron
Iron
Iron
commented on 05 Sep 2024, 09:31 AM

Also can I use the bound data method to only have URLs for some menu items, as there will be those that are section headers that won't need a URL and will only be there for traversing the menu navigation?
Chris
Top achievements
Rank 1
Iron
Iron
Iron
commented on 05 Sep 2024, 10:11 AM

Sorry - more questions - can I also set the LinkHtmlAttributes so I can cause a menu item to call some JQuery code - i.e. set it's onclick?

1 Answer, 1 is accepted

Sort by
0
Mihaela
Telerik team
answered on 09 Sep 2024, 01:07 PM

Hello Chris,

In order to construct the item's URL in format "/Controller/Action/{cust_id}/{action_type}", I would recommend using the Url property:

@(
Html.Kendo().Menu()
                .Name("menu")
                .BindTo(Model.TaskTypes, mappings =>
                {
                    mappings.For<CRM.Core.CRM.TaskType>(binding => binding 
                        .ItemDataBound((item, type) => 
                            {
                                item.Text = type.TaskTypeName;
                                item.Url = "/New/Task/" + type.CustomerId + "/" + type.ActionType;
                            }));
                })
)

To add the "CustomerId" and "ActionType" as query string parameters, you can use the RouteValues property:

@(
Html.Kendo().Menu()
                .Name("menu")
                .BindTo(Model.TaskTypes, mappings =>
                {
                    mappings.For<CRM.Core.CRM.TaskType>(binding => binding 
                        .ItemDataBound((item, type) => 
                            {
                                item.Text = type.TaskTypeName;
                                item.ActionName = "New";
                                item.ControllerName = "Task";
                                item.RouteValues = new RouteValueDictionary { { "cust_id", type.CustomerId }, { "action_type", type.ActionType } };
                            }));
                })
)

As a result, the item's URL will be constructed as follows:

/Task/New?cust_id={value}&action_type={value}

Regarding the items that don't have a specified URL, use if-else statement within the ItemDataBound() configuration:

.ItemDataBound((item, type) => // Define the mapping between the Menu item properties and the model properties.
{
                                              if(type.TaskTypeName == "Task 2")
                                              {
                                                  item.Text = type.TaskTypeName;
                                              } else
                                              {
                                                  item.Text = type.TaskTypeName;
                                                  item.ActionName = "New";
                                                  item.ControllerName = "Task";
                                                  item.RouteValues = new RouteValueDictionary { { "cust_id", type.CustomerId }, { "action_type", type.ActionType } };
                                              }

})

In regards to the custom item's attributes, the LinkHtmlAttributes is a read-only property, so I would suggest defining the Menu's items by using the Items() configuration:

@(Html.Kendo().Menu()
        .Name("menu")
        .Items(items =>
        {
            foreach (var item in Model.TaskTypes)
            {
                items.Add().Text(item.TaskTypeName)
                .Url("/New/Task/" + item.CustomerId + "/" + item.ActionType)
                .LinkHtmlAttributes(new { onclick = "itemClick(this);" })
                .HtmlAttributes(new { @class = "menuItem" });
            }
        })
)

I hope these examples will be helpful.

 

Regards,
Mihaela
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tags
Menu
Asked by
Chris
Top achievements
Rank 1
Iron
Iron
Iron
Answers by
Mihaela
Telerik team
Share this question
or