In alternative, I can also pass the dataSource.view to it, but in this case I don't know of which type I should declare the parameter in the controller method...
What I need in the end in the controller method is an IEnumerable<T> containing all the currently visible rows, possibly respecting the ordering shown but regardless of grouping.
Thanks for any suggestion,
Stefano
12 Answers, 1 is accepted
I would recommend serializing the dataSource and sending it to the server using AJAX request. Here is an example using MVC:
The View:
@(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.EmployeeViewModel>()
.Name(
"Grid"
)
.Columns(columns => {
...
columns.Command(command => command.Custom(
"Custom Command"
).Click(
"sendVisibleRows"
));
})
)
<script type=
"text/javascript"
>
function
sendVisibleRows(e) {
var
data = JSON.stringify(
this
.dataSource.view());
$.ajax({
type:
"POST"
,
dataType:
"json"
,
contentType:
"application/json; charset=utf-8"
,
url:
"CustomCommand_ModifyVisibleRows"
,
data: data
});
}
</script>
public
ActionResult CustomCommand_ModifyVisibleRows([DataSourceRequest] DataSourceRequest request, IEnumerable<EmployeeViewModel> employees)
{
...
}
Using this approach you will get the items in the same order they are displayed in the Grid.
Regards,
Alexander Popov
Telerik

I tried your code, but I am having some problems with it.
If the grid is grouped by any column, then in the server instead of getting all the rows I am getting an item for each grouping element, and with all the fields set to null.
Also the DataSourceRequest parameter has always all the fields set to null. This is not a problem as I do not really need it, but still it is strange.
Finally, I would need to put the button not as a custom command in the columns definitions, but in the toolbar (sorry, I was not very clear about this), which does not provide a Click event but only an Action event.
Regards,
Stefano
In case the data is grouped by one or more columns you will get an array of objects back from the view method. Each object represents a group and should contain an array of the dataItem objects in that group, named "items". This is the expected behavior of the DataSource view method, however you can create an array that combines the items from each group and pass it to the server.
The DataSourceRequest is always null, because we do not send it from the Ajax request.
You can set the toolbar command's Url to a JavaScript function, for example:
@(Html.Kendo().Grid<
Kendo.Mvc.Examples.Models.ProductViewModel
>()
.Name("Grid")
.ToolBar(toolbar => {
toolbar.Create();
toolbar.Save();
toolbar.Custom().Text("Custom command").Url("javascript:myFunction()");
})
...
)
<
script
type
=
"text/javascript"
>
function myFunction(e) {
alert("myFunction");
}
</
script
>
Regards,
Alexander Popov
Telerik

Hello Alexander,
I am trying to save the Filter criteria of the grid. But for some reason I am not able to send the DataSourceRequest to action method. This is what I am doing.
toolBar.Custom().Text("Save Filter").Url("javascript:SaveFilterClicked()");
function SaveFilterClicked(e)
{
var data = JSON.stringify(this.dataSource.view());
$.ajax({
url: '/MyController/SaveFilter',
type: 'POST',
data: data,
async: true,
processData: false
});
}
But this.dataSource is "undefined". Can you guide me through a better way of doing this
Thank you
This is expected, because the this keyword is not referring to the Grid's instance in the current context. Getting the Grid reference first should do the trick:
function
SaveFilterClicked(e){
var
grid = $(
"#myGridID"
).getKendoGrid();
var
data = JSON.stringify(grid.dataSource.view());
$.ajax({
url:
'/MyController/SaveFilter'
,
type:
'POST'
,
data: data,
async:
true
,
processData:
false
});
}
Regards,
Alexander Popov
Telerik

Thanks for your reply Alexander.
Your suggestion sends the data of the Grid.
I am actually trying to send the current DataSourceRequest so I can record current filters applied to the Grid in database. I tried the your suggestion but the filters are returning as null even though I have filters applied to the grid.
I appreciate your help!
In that case you can manually call the parameterMap function of the Grid's DataSource and pass it the currently applied filter. The result should be a JavaScript object that can be bound to a DataSourceRequest object on the server. For example:
var
request = grid.dataSource.transport.parameterMap({filter: grid.dataSource.filter()});
Regards,
Alexander Popov
Telerik

It works great! Thank you for the response Alexander.
It returns the current filter of the grid. For example if I have a filter on FirstName column with operator "contains" and value as "john" then it returns
"FirstName~contains~'john'"
For multiple filters, it returns as
"FirstName~contains~'john'~and~LastName~contains~'ander'"
For "Or" operator filters it returns as
"FirstName~contains~'john'~or~FirstName~contains~'abc'~and~LastName~contains~'ander'"
I am storing this filter string in database so that the user can apply the filters that he has saved later on. My question is, how can I use this filter string to apply filter back to the grid.
Thank you very much!
You can use those strings to create filter expressions using the FilterDescriptorFactory. For example:
var
filters = Kendo.Mvc.Infrastructure.FilterDescriptorFactory.Create(
"(ProductName~contains~'cha'~or~ProductName~eq~'Ikura')~and~UnitPrice~gt~1"
);
...
.DataSource(dataSource => dataSource
.Ajax()
.Filter(x=>x.AddRange(filters))
Regards,
Alexander Popov
Telerik

Thanks Alexander,
I have figured out an easier way to save and apply filter. Here is what I am doing...
For Saving the filter
var grid = $("#Grid").getKendoGrid();
var filterState = kendo.stringify({
filter: grid.dataSource.filter()
});
Now pass filterState to the action method and save it in database or session or cookie
I am passing it through an ajax call like this
$.ajax({
url: '/MyController/SaveFilter?filters=' + filterState,
type: 'POST',
async: true,
processData: false,
success:function(data) {
if (data > 0)
{
alert("Filter saved");
}
}
});
Now to apply the filter back to the grid:
var grid = $("#Grid").getKendoGrid();
// Some how pass the filter string that we have saved in database or session or cookie.
// Assuming 'filterState' is the variable with filter string. Do this
grid.dataSource.filter(JSON.parse(filterState).filter);
The filter will be applied to the string.

The recommended way for file download is to change the location.
It should be something along the lines of:
location.href = controllerName/actionName + dataSourceState;
Further information is available on the internet:
http://stackoverflow.com/questions/20830309/download-file-using-an-ajax-request
http://stackoverflow.com/questions/3749231/download-file-using-javascript-jquery
Regards,
Alex Hajigeorgieva
Telerik by Progress