I want to utilize the Kendo UI Context Menu in my app. I was expecting the standard behavior of having text displayed in the menu itself but a different value (an ID or key) being returned to the select
event handler.
For instance, the menu displays a list of names but when I click on one of them, I get the ID associated with the name.
I've tried adding additional properties besides text
to the array of items in the context menu but I don't see them on the event object in the handler.
I can't use the text to find the appropriate id that matches it since there could be entries with the same text but different IDs.
Any ideas?
Edit:
Currently I build the context menu like this:
open: (e) => {
let itemKeys = [1, 2, 3];
let menu = e.sender;
menu.remove(".context-menu-item");
menu.append(itemKeys.map((itemKey) => {
return {
text: "<div data-item-key='" + itemKey + "'>Test Text</div>",
cssClass: "context-menu-item",
encoded: false
};
}));
}
While this solution does satisfy my needs, it adds an extra element to the DOM which, while being insignificant, isn't perfect...
It's undocumented, but ContextMenu
actually inherits from Menu
. Therefore, all options of Menu
are available. In particular, you can add an attr
object to your data items, cf the example in the documentation.
To complete your example:
open: (e) => {
let itemKeys = [1, 2, 3];
let menu = e.sender;
menu.remove(".context-menu-item");
menu.append(itemKeys.map((itemKey) => {
return {
text: "Test Text",
cssClass: "context-menu-item",
// add whatever attribute
attr: {
'data-item-key': itemKey
}
};
}));
}
Then, in your select
handler:
select: (e) => {
console.log($(e.item).data('item-key'));
}
Option 1) You might add a data that will specify your Id. I made this with mvc wrapper but it can be done with pure javascript as well.
@(Html.Kendo()
.ContextMenu()
.Name("contextMenuGridTicketTestiMessaggi")
.Target("#gridTicketTestiMessaggi")
.Filter("tr")
.Orientation(ContextMenuOrientation.Vertical)
.Items(items =>
{
items.Add().Text("Update").HtmlAttributes(new { data_toggle = "update" });
items.Add().Text("Save").HtmlAttributes(new { data_toggle = "save" });
items.Add().Text("Delete").HtmlAttributes(new { data_toggle = "delete" });
})
.Events(e => {
e.Select("contextMenuGridTicketTestiMessaggiSelect");
}));
var contextMenuGridTicketTestiMessaggiSelect = function(e) {
var action = $(e.item).data("toggle");
var that = this;
if (action === "update") {}
...
Option 2) You might define with every item(throught html content) a function to be called in each onClick event for the specific item.
items.Add().Encoded(false).Text("<span onclick='update()'>Update</span>");
items.Add().Encoded(false).Text("<span onclick='delete()'>Delete</span>");
...
<div id="target">Target</div>
<ul id="context-menu"></div>
<script>
$("#context-menu").kendoContextMenu({
target: "#target",
open: function(e) {
let itemKeys = [1, 2, 3];
let menu = e.sender;
menu.remove(".context-menu-item");
menu.setOptions({
dataSource: itemKeys.map((itemKey) => {
return {
text: "<div data-item-key='" + itemKey + "' style='white-space: nowrap'>Test Text</div>",
cssClass: "context-menu-item",
encoded: false
};
})
});
},
select: function(e) {
console.log($($(e.item).find("div")[0]).data("item-key"))
}
});
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With