Adding Additional Data to Kendo UI Context Menu Items
I want to use Kendo UI context menu in my application. I expected the standard text behavior to appear in the menu itself, but a different value (id or key) is returned in the event handler select
.
For example, the menu shows a list of names, but when I click on one of them, I get an ID associated with the name.
I've tried adding additional properties besides text
to the item array in the context menu, but I don't see them in the event object in the handler.
I cannot use text to find the matching ID that matches it, as there might be records with the same text but different IDs.
Any ideas?
Edit:
I am currently creating a 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 satisfies my needs, it adds an extra element to the DOM which, while being insignificant, is not ideal ...
source to share
It is undocumented, but it ContextMenu
actually inherits Menu
. Therefore, all options are available Menu
. In particular, you can add an object attr
to your data items, 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 handler select
:
select: (e) => {
console.log($(e.item).data('item-key'));
}
source to share
Option 1) You can add data that will indicate your ID. I did it using mvc wrapper, but it can be done using pure javascript too.
@(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 can define with each element (throught html content) a function that will be called in each onClick event for a specific element.
items.Add().Encoded(false).Text("<span onclick='update()'>Update</span>");
items.Add().Encoded(false).Text("<span onclick='delete()'>Delete</span>");
...
Update
<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>
source to share