20 Answers, 1 is accepted
To achieve this, you could bind to the click event of the command and since it is just a link tag under the hood, you could manipulate it's href attribute and attach the parameters.
E.g.
.ToolBar(toolbar =>
{
toolbar.Custom().Text(
"Clickme"
).Name(
"Clickme"
).Action(
"myAction"
,
"myController"
);
})
$(
".k-grid-Clickme"
).on(
"click"
,
function
() {
var
grid = $(
"#grid"
).data(
"kendoGrid"
);
var
selectedData = grid.dataItem(grid.select());
if
(selectedData) {
var
selectedId = selectedData.ProductID;
var
href = $(
this
).attr(
"href"
);
href +=
"?id="
+ selectedId;
$(
this
).attr(
"href"
, href);
}
});
I hope this approach will work in your scenario.
Kind regards,
Dimiter Madjarov
the Telerik team

Sorry for the inconvenience, but currently this is the only way to achieve this. Nevertheless if you consider that adding this ability to a custom toolbar button will be useful for other users too, you could post it in our Kendo User Voice portal. If it receives enough votes from the community, we will consider to implement it in future releases of Kendo UI.
Kind regards,
Dimiter Madjarov
the Telerik team

Just wanted to say thank you for the response.
Regads
Thanks for the feedback. I am glad the information was helpful.
Regards,
Dimiter Madjarov
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

Is there any improvement on this kind scenario in recent years?
If there is a way to pass current datasource object to Action method, it will better fit in MVC.
Hello Adam,
If the current approach is not suitable, you could directly use a template with an action link and add the k-button CSS class to the link so that it looks like the Grid commands.
Regards,Dimiter Madjarov
Telerik
See What's Next in App Development. Register for TelerikNEXT.

Hi Dimiter,
I have a dynamic grid, for n number of providers, I am creating service table for each provider. I am adding the provider id to the each service grid name, so that i can refer that service is from which provider. But I am not sure how to get the name of the grid on click of the custom command button.
//for each model.id, it create the below code
<
div
class
=
"container-fluid"
>
<
div
class
=
"row"
>
<
div
class
=
"col-xs-18 col-md-12"
>
@(Html.Kendo().Grid<
BHEBS.Areas.Admin.Models.ContractModel.serviceDetails
>()
.Name("grid" + Model.Id)
.Columns(columns =>
{
columns.Bound(o => o.ServiceId).Hidden(true);
columns.Bound(p => p.ServiceName);
columns.Bound(o => o.ServiceType);
columns.Bound(o => o.AdultChild);
columns.Bound(o => o.Qualifier);
columns.Bound(o => o.ServiceModifier);
columns.Bound(o => o.WomenSetAside).Title("Women Set Aside");
columns.Bound(o => o.StartDate).Format("{0:MM/dd/yyyy}");
columns.Bound(o => o.EndDate).Format("{0:MM/dd/yyyy}");
//custom command
columns.Command(command => command.Custom("Budget").SendDataKeys(true).Click("budgetClick").HtmlAttributes(new { @class = "k-button k-button-icontext k-grid-add k-primary" }));
})
//.Events(e => e.DataBound("onDataBound"))
.Pageable(pageable => pageable.Refresh(true).PageSizes(true).ButtonCount(5))
.Sortable()
.Scrollable()
.Filterable()
.Selectable()
.Resizable(resize => resize.Columns(true))
.HtmlAttributes(new { style = "height:350px;" })
.DataSource(dataSource => dataSource.Ajax().PageSize(10).Read(read => read.Action("Services_Read", "Contract", new { contractorId = @Html.Raw(Json.Encode(Model.Id)), contractId = @Html.Raw(Json.Encode(Model.contractId)) }))))
</
div
>
</
div
>
</
div
>
custom command button click event
function budgetClick(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
var modelObj = @Html.Raw(Json.Encode(Model));
//trying to get table name for that service table
alert(e.sender.options.table.parent('div')[0].id);
Id = dataItem.Id;
var element = $(document.body);
kendo.ui.progress(element, true);
$.ajax({
url: '@Url.Action("ContractBudgetService", "ContractBudget")',
type: 'GET',
data: {
'contractId':modelObj.Id,
'contractorId':$(this).parents('.panel-wrap').attr('id'),
'serviceId': Id
},
success: function (data) {
kendo.ui.progress(element, false);
$('#ContractBudgetIndexDiv').html(data);
},
error: function () {
kendo.ui.progress(element, false);
console.log("error in saving the record");
}
});
//window.location.href = '@Url.Action("Edit","Contractor")/' + Id;
}
Hello,
You could access the current Grid via it's data-role attribute and then get it's id attribute, which is the same as the name.
E.g.
$(e.currentTarget).closest(
"[data-role='grid']"
).attr(
"id"
);
Dimiter Madjarov
Telerik

Hello Richard,
Are you retrieving the correct Grid instance, using the code from the last post? If that is the case and the issue is still reproducing, you could send us a sample project here or in a support ticket, so we could take a look and provide further help.
Regards,Dimiter Madjarov
Telerik

My implementation and works!
columns.Command(c => c.Custom("Download").Click("downloadPDF")).Width(100);
function downloadPDF(e) {
var id = $(id.currentTarget).closest("tr").find('td:first').html();
}

correction
columns.Command(c => c.Custom("Download").Click("downloadPDF")).Width(100);
function downloadPDF(e) {
var id = $(e.currentTarget).closest("tr").find('td:first').html();
}

I know this is an old thread, but I just started using Telerik and this thread was the first search result on Google. I was trying to figure out how to add a custom-formatted "View" button that would pass the ID to the appropriate view.
I was able to successfully getting working with the sample code on this page of the Grid documentation:
https://docs.telerik.com/aspnet-mvc/helpers/grid/faq#how-do-i-use-action-links
Hopefully this helps someone else! There isn't a link to that sample on the Custom Commands page (https://demos.telerik.com/aspnet-mvc/grid/custom-command) which might have saved others like me a great deal of time.
I'm glad to hear that the post was helpful.
We will consider linking the article inside the command article for better visibility.
The feedback is highly appreciated.
Regards,
Stefan
Progress Telerik

Sorry to yet again revive an old thread but I think its related closely enough to the original post... I have a grid that is mimicking a folder structure using a DetailsTemplate Each folder can have a subfolder or multiple sub folders which I am building from a template. The issue I am having is that when I try to pass the parent data object (I need some of the data from the row that I am expanding), I can get it to send the data object in a toolbar button ONLY if I do the following...
.ToolBar(toolbar =>
{ toolbar.Custom().Text(
"CreateFolder"
).Url(
"javascript:#=CreateFolder(data)#"
).HtmlAttributes(
new
{ type =
"button"
});
toolbar.Custom().Text(
"Upload File"
).HtmlAttributes(
new
{ onclick =
"#=UploadFile(data)#"
, href =
"javascript:void(0)"
, type =
"button"
});
})

Sorry for the second post. I couldn't get past the formatted code block to finish typing...
The problem I am having when I do that, is when the details grid initializes, it calls that function. That isn't the wanted functionality. If I move the code #=# around the data like so CreateFolder(#=data#), I get an error saying invalid character - It is seeing the function as CreateFolder([object Object]).
I'm not sure if it is even possible to pass the object in that toolbar template to a javascript function or not... I can pass string values no problem, just cant seem to get the dataItem for the master row to pass. I can't reference the grid in jquery because the grid names are dynamic based off random guid Id's.
Here is the full code for the template. Any help would be appreciated.
@(Html.Kendo().Grid<ShareFile.Api.Client.Models.Item>()
.Name(
"documents_#=Id#"
)
.AutoBind(
true
)
.Columns(columns =>
{
columns.Bound(d => d.url).ClientTemplate(
"\\#=InitializeName(data)\\#"
).Width(300).MinResizableWidth(300).Title(
"File Name"
);
columns.Bound(d => d.__type).Title(
"File Type"
).Width(50).ClientTemplate(
"\\#=InitializeType(data)\\#"
);
columns.Bound(e => e.FileSizeInKB).Width(150).MinResizableWidth(150).Title(
"Size"
).ClientTemplate(
"\\#=FileSizeInKB\\# Kb</a>"
);
columns.Bound(e => e.Description).Width(175).Title(
"Description"
).MinResizableWidth(175);
columns.Bound(e => e.FileName).Visible(
false
);
})
.DataSource(datasource => datasource
.Custom()
.Schema(schema => schema
.Model(model => {
model.Id(p => p.Id);
}
)
)
.Transport(transport =>
{
transport.Read(read =>
read.Action(
"GetFolderItems"
,
"Documents"
,
new
{ folderUrl =
"#=url#"
})
);
})
)
.ToolBar(toolbar =>
{
toolbar.Custom().Text(
"Create Folder"
).Url(
"javascript:#=CreateFolder(data)#"
).HtmlAttributes(
new
{ type =
"button"
});
toolbar.Custom().Text(
"Upload File"
).HtmlAttributes(
new
{ onclick =
"#=UploadFile(data)#"
, href =
"javascript:void(0)"
, type =
"button"
});
})
.ClientDetailTemplateId(
"template"
)
.Events(e=> e.DataBound(
"dataBound"
))
.Sortable()
.HtmlAttributes(
new
{ style =
"height: 500px;"
})
.ToClientTemplate())
In order to execute a JavaScript function when the toolbar button in a detail Grid is clicked I would suggest the following approach. Define the toolbar button like this:
.ToolBar(t=>t.Custom().Text(
"Test"
).Name(
"CustomButton"
))
Then handle the click event of the parent Grid and check if the nested toolbat button was clicked:
$(
"#parentGridID"
).on(
"click"
,
".k-grid-CustomButton"
,
function
(e) {
e.preventDefault();
var
masterGrid = $(e.delegateTarget).getKendoGrid();
var
masterRow = $(
this
).closest(
"tr"
).prev(
".k-master-row"
);
var
masterItem = masterGrid.dataItem(masterRow);
console.log(masterItem.FirstName);
// more code
});
Give the approach a try and let me know how it works for you.
Regards,
Viktor Tachev
Progress Telerik

Viktor,
Thanks for your reply! I was able to get a work around going based off of what you sent. I don't know the 'parentGridID" when I'm navigating as they are dynamic names with guid id's. However, using the following code, I was able to pass the data object like I needed.
This is the custom toolbar code.
toolbar.Custom().Text(
"Create Folder"
).HtmlAttributes(
new
{ onclick =
"CreateFolder(this)"
, href =
"javascript:void(0)"
, type =
"button"
});
and this is the function to get the parent grid - parent row data item.
function
CreateFolder(e) {
var
grid = $(e).closest(
"[data-role=grid]"
);
var
parentRow = grid.closest(
".k-detail-row"
).prev();
var
parentGrid = parentRow.closest(
"[data-role=grid]"
).data(
"kendoGrid"
);
var
dataItem = parentGrid.dataItem(parentRow);
var
detailsTemplate = kendo.template($(
"#createfolderWindowTemplate"
).html());
var
wnd = $(
"#CreateFolderWindow"
).data(
"kendoWindow"
);
wnd.content(detailsTemplate(dataItem));
wnd.center().open();
}
Thanks for pushing me in the right direction!

Dears
There is any update upon this thread in the late release (i'm on 2022.2.802)
The scenario is ever the same.
Grid with ajax binding, custom icon button to edit a record, the need to pass the #id# to the controller
BR
Cristian
Hello Cristian,
Since is used a custom button it cannot be directly related to the Grid and a custom implementation similar to the ones shared above is required. With that said, may I ask you, is there a reason to use a custom Edit button instead of using the predefined one?
columns.Command(cmd => cmd.Edit());
Based on the description - "Grid with ajax binding, custom icon button to edit a record" I assume you want to display only the Edit Icon, if so you can hook up for the DataBound event of the Grid and remove the button text.
function onDataBound() {
$("td.k-command-cell > button > span.k-button-text").remove();
}
I hope this helps.