Passing current DataSourceRequest to a custom command

11 posts, 0 answers
  1. Stefano
    Stefano avatar
    8 posts
    Member since:
    Jan 2013

    Posted 26 Sep 2013 Link to this post

    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
  2. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 30 Sep 2013 Link to this post

    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!
  3. Kendo UI is VS 2017 Ready
  4. Stefano
    Stefano avatar
    8 posts
    Member since:
    Jan 2013

    Posted 30 Sep 2013 Link to this post

    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
  5. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 02 Oct 2013 Link to this post

    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!
  6. Saquib
    Saquib avatar
    15 posts
    Member since:
    Mar 2015

    Posted 01 May 2015 in reply to Alexander Popov Link to this post

    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

     

     

  7. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 05 May 2015 Link to this post

    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!
     
  8. Saquib
    Saquib avatar
    15 posts
    Member since:
    Mar 2015

    Posted 05 May 2015 in reply to Alexander Popov Link to this post

    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!

  9. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 07 May 2015 Link to this post

    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!
     
  10. Saquib
    Saquib avatar
    15 posts
    Member since:
    Mar 2015

    Posted 07 May 2015 in reply to Alexander Popov Link to this post

    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!

  11. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 11 May 2015 Link to this post

    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!
     
  12. Saquib
    Saquib avatar
    15 posts
    Member since:
    Mar 2015

    Posted 11 May 2015 in reply to Alexander Popov Link to this post

    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. 

Back to Top
Kendo UI is VS 2017 Ready