This is a migrated thread and some comments may be shown as answers.

Passing current DataSourceRequest to a custom command

12 Answers 884 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
Stefano
Top achievements
Rank 1
Stefano asked on 26 Sep 2013, 09:54 AM
In a grid I have a custom command which must call a controller method in Asp.Net Mvc and pass to it the same DataSourceRequest that originated the currently shown grid rows. How can I achieve it?
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

Sort by
0
Alexander Popov
Telerik team
answered on 30 Sep 2013, 07:38 AM
Hello Stefano,

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>
The Controller:
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
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Stefano
Top achievements
Rank 1
answered on 30 Sep 2013, 01:44 PM
Thank you Alexander for your answer.
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
0
Alexander Popov
Telerik team
answered on 02 Oct 2013, 10:01 AM
Hi 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
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Saquib
Top achievements
Rank 1
answered on 01 May 2015, 08:53 PM

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

 

 

0
Alexander Popov
Telerik team
answered on 05 May 2015, 10:30 AM
Hello Saquib,

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
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Saquib
Top achievements
Rank 1
answered on 06 May 2015, 12:36 AM

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!

0
Alexander Popov
Telerik team
answered on 07 May 2015, 12:03 PM
Hello Saquib,

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
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Saquib
Top achievements
Rank 1
answered on 07 May 2015, 08:32 PM

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!

0
Alexander Popov
Telerik team
answered on 11 May 2015, 12:35 PM
Hi Saquib,

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
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Saquib
Top achievements
Rank 1
answered on 11 May 2015, 01:40 PM

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. 

0
Raj
Top achievements
Rank 1
answered on 21 Apr 2017, 01:37 PM
How can i achieve this (pass DataSourceRequest) without using AJAX. Because i am using it for file download where AJAX would not work?
0
Alex Hajigeorgieva
Telerik team
answered on 25 Apr 2017, 09:45 AM
Hello Raj,

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
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data (charts) and form elements.
Tags
Data Source
Asked by
Stefano
Top achievements
Rank 1
Answers by
Alexander Popov
Telerik team
Stefano
Top achievements
Rank 1
Saquib
Top achievements
Rank 1
Raj
Top achievements
Rank 1
Alex Hajigeorgieva
Telerik team
Share this question
or