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

Passing default filter, sort, and group values to a grid via QueryString URL paramaters

2 Answers 1300 Views
Grid
This is a migrated thread and some comments may be shown as answers.
William
Top achievements
Rank 1
Iron
William asked on 28 Nov 2012, 11:00 PM
Hello,

I'm using (and loving) the KendoUI Complete for ASP.NET MVC.  I am trying to pass parameters to a page to indicate the filters, sorts, groups, etc. for the grid via the querystring; e.g., http://localhost/MyPage?sort=DatePlaced-desc&page=1&pageSize=15&group=&filter=Id~gte~1719300~and~Id~lte~1800000~and~UserFirstName~eq~'Edward'

When these parameters are passed, I'm wanting the grid on the page to reflect these parameters when it gets created; i.e., the grid should be initially filtered by Id and UserFirstName in accordance with the filters passed to the page.

I'm hoping for something as simple as:

    .DataSource(dataSource => dataSource
        .Ajax()
        .Read(read => read.Action("MyAction", "MyController"))
        .Filter(Request.QueryString["filter"])
        .Sort(Request.QueryString["sort"])
        .PageSize(Request.QueryString["pageSize"])
    )

I assume you get the idea of what I'm going for.  The motivation for this is as follows:  I'd like to give the user a few buttons, each to a different "canned" report, which is nothing more than the same grid with different filters, sorts, groups, etc.  So if the user clicked one of the buttons, they'd be taken to the page containing the grid, and the filters, sorts, etc. would be passed in as QueryString parameters.

Your assistance on this would be much appreciated.

Thank you,
Billy McCafferty

2 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 30 Nov 2012, 04:32 PM
Hello Billy McCafferty,

The Grid will automatically apply the state values if they are in the correct format - Grid Name +"-" + parameter name = value. For example if your Grid is named "Grid" - "http://localhost/MyPage?Grid-sort=DatePlaced-desc". You could also use your current parameters names but you will also need to use the PrefixUrlParameters to disable the prefix e.g.

.PrefixUrlParameters(false)
Regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Mario
Top achievements
Rank 1
commented on 09 Dec 2022, 06:08 PM

Hi there,

We were using this awesome functionality for years (throughout several versions of Telerik suite) in all the grids, like:

/Products?ProductsGrid-sort=ProductID-desc&ProductsGrid-filter=PartnerID~eq~116~and~Active~eq~true

Also, with multiple combinations of fields and logic operators, always we got this working fine.

But now we are migrating from ASP.NET MVC to ASP.NET Core, version 2022.2.510.

And this feature is not working in Core, just the grids won't recognize the parameters in the Url.

Is there a way to restore this functionality in Core like previous versions?

Thanks.

Neli
Telerik team
commented on 13 Dec 2022, 01:30 PM

Hi Mario,

Could you please provide more information about the Grid configuration and the read endpoint? Are you using the Kendo UI for jquery Grid in ASP.NET Core project or you are using the Telerik Asp.Net Core wrappers?

If you need to pass addditional parameters to the remote end point you can use the Data method:

 .DataSource(dataSource => dataSource
            .Ajax()
            .Read(read => read
                .Action("Products_Read", "Home") // Set the action method which will return the data in JSON format.
                .Data("productsReadData") // Specify the JavaScript function which will return the data.
            )
        )

And sample values:

 <script>
        function productsReadData() {
            return {
                firstName: "John",
                lastName: "Doe"
            };
        }
    </script>

Regards,

Neli

Dan Mortimer
Top achievements
Rank 1
commented on 13 Dec 2022, 11:16 PM

Hi Neli, 

We were using Kendo UI v2022.2.510 in the client and Kendo ASP.NET MVC on the server.

And when we pass grid configuration in the querystring to a page containing a grid it'll apply those parameters, for example:

/Products?ProductsGrid-sort=ProductID-desc&ProductsGrid-filter=PartnerID~eq~116~and~Active~eq~true

This is done by kendo libraries, and doesn't have anything to do with the "Data method" at all.

In Daniel's answer he said:

"The Grid will automatically apply the state values if they are in the correct format - Grid Name +"-" + parameter name = value. For example if your Grid is named "Grid" - "http://localhost/MyPage?Grid-sort=DatePlaced-desc"."

That is the functionality we need.

Unfortunately, this no longer works using Kendo UI v2022.2.510 in the client and Kendo ASP.NET Core on the server.

We will appreciate any help on this issue.

Thanks.

Stoyan
Telerik team
commented on 15 Dec 2022, 12:52 PM

Hi Dan,

Thе format of the request shared by Daniel 

ProductID-desc&ProductsGrid-filter=PartnerID~eq~116~and~Active~eq~true

is only usable when the type of the DataSource is Ajax. Custom or WebAPI DataSources won't be able to use requests formatted in this way.

That being said you can utilize the query method of the DataSource on the client-side to apply grouping, filtering, sorting, paging, etc with the Read request.

I hope the information above is useful.

If the issue persists, please consider sharing more details about the implementation on your side or an isolated sample project that showcases the experienced behavior.

Mario
Top achievements
Rank 1
commented on 15 Dec 2022, 11:33 PM

Hi Stoyan, thanks for your answer. I think an example will help clarify the problem.

This is a simple page with a grid listing some employees:

See Image1.png

And this is the MVC code:

Model
-----
    public class EmployeesGridViewModel
    {
        public EmployeesGridViewModel(Employee employee)
        {
            EmployeeID = employee.EmployeeID;
            Name = employee.Name;
            Active = employee.Active;
            Extension = employee.Extension;
            BuildingAccessIds = employee.BuildingAccessIds;
            ExpectedEndDate = employee.ExpectedEndDate;
        }

        public int EmployeeID { get; set; }

        [Required]
        public string Name { get; set; }

        public bool Active { get; set; }

        public string Extension { get; set; }

        public string BuildingAccessIds { get; set; }

        [DataType(DataType.Date)]
        public DateTime? ExpectedEndDate { get; set; }

    }
View
----

<div>
    @(Html.Kendo().Grid<EmployeesGridViewModel>()
        .Name("employees")
        .Columns(cols =>
        {
            cols.Bound(e => e.EmployeeID).Title("ID").Width(80);
            cols.Bound(e => e.Name).DefaultFilterableString();
            cols.Bound(e => e.Active).Width(100);
            cols.Bound(e => e.Extension).Title("Ext").Width(80);
            cols.Bound(e => e.BuildingAccessIds);
            cols.Bound(e => e.ExpectedEndDate).Title("Exp. end date");
            cols.Command(command =>
            {
                command.Edit();
            }).Width(150);
        })
        .Editable(editable => editable.Mode(GridEditMode.InLine))
        .Filterable()
        .Sortable()
        .ColumnMenu()
        .Resizable(resize => resize.Columns(true))
        .Pageable(pageable => pageable
              .Refresh(true)
              .PageSizes(new int[] { 1, 10, 25, 50, 100, 200 })
              .Input(true)
              .ButtonCount(5)
        )
        .DataSource(dataSource => dataSource
              .Ajax()
              .Model(model =>
              {
                  model.Id(e => e.EmployeeID);
                  model.Field(e => e.EmployeeID).Editable(false);
              })
              .PageSize(10)
              .Filter(filter => filter.Add(e => e.Active).IsEqualTo(true))
              .Sort(sort => sort.Add(e => e.Name))
              .Read(read => read.Action("Employees_Read", "Admin"))
        ))
</div>
Controller
----------

        public ActionResult Employees_Read([DataSourceRequest]DataSourceRequest request)
        {
            IQueryable<Employee> employees = db.Employees.Where(e => e.EmployeeID > 0);

            return Json(employees.ToDataSourceResult(request, employee => new EmployeesGridViewModel(employee)));
        }

In the next picture you can see the request object on the controller in debug mode with the default parameters defined in the view:

See Image2.png

And just modifying the Url we can apply a different filter, for instance if we do:

http://localhost:51068/Admin/Employees?employees-filter=EmployeeID~eq~714

We will get the following result:

See Image3.png

And the filters in the request object now have the new values from the Url:

See Image4.png

This functionality is what we need, and you can notice that we are not using any piece of JavaScript.

These pictures are from our real portal deployed using Telerik ASP.NET MVC v2022.2.510

But now we are migrating to Telerik ASP.NET Core v2022.2.510, and that functionality is not working.

We use this facility extensively and are heavily dependent on it, so any help you can give us will be greatly appreciated.

Thanks,

Mario.

 

Stoyan
Telerik team
commented on 19 Dec 2022, 05:19 PM

Hi Mario,

Thank you for the clarification.

Based on the provided information the approach you use should work in ASP.NET Core as long as the Action method of the Controller is configured to be called by a GET request.

In addition you need to ensure that the URL indeed calls the Action method.

For example 

http://localhost:51068/Admin/Employees?employees-filter=EmployeeID~eq~714

will pass the filter parameters to a method called Employees in the AdminController. However it seems that the method in the Controller is called Employees_Read.

Could you please try using 

http://localhost:51068/Admin/Employees_Read?employees-filter=EmployeeID~eq~714

and let me know whether the issue persists.

 

Mario
Top achievements
Rank 1
commented on 21 Dec 2022, 10:49 PM

Hi Stoyan,

The Employees is actually an Action in the controller, like:

        public ActionResult Employees()
        {
            return View();
        }

Which will render the view that contains the grid. So, we are calling the correct action method.

And using the method "Employees_Read" from the url doesn't work.

So, the issue still persists.

Any other idea? Thanks.

Stoyan
Telerik team
commented on 23 Dec 2022, 01:35 PM

Hi Mario,

The Controller indeed has an Action method called Employees however that method is doesn't return data but it returns a View instead. Therefore it won't be able to process the GET request's parameters and respond with the filtered data.

That being said could you please share the errors that you get when you send a request to the Employees_Read method and possibly the headers that can be observed in the Network tab of the browser's Developer Tools?

Currently I suspect that there is mismatch between the type of the request - for example the server might expect a POST request and rejects a GET request to the same endpoint.

Dan Mortimer
Top achievements
Rank 1
commented on 23 Dec 2022, 07:16 PM | edited

Stoyan, 

You are completely missing the point of the issue. It actually seems like you don't even understand the basic functionality of the grid and how it operates.

This is VERY simple to recreate. With UI for ASP.NET you can put the filter in the url for a page that displays a grid (not in the datasource url for the grid). The filter will be applied automatically. Do the EXACT same thing with UI for ASP.NET Core and the filter will not be applied.

The earlier response from Telerik in this thread references the method ".PrefixUrlParameters(false)" which will change how the URL parameters are applied. That method does not exist in UI for ASP.NET Core, which is believe is because that functionality simply doesn't exist there. It looks like that functionality wasn't properly ported to .net core.

I found one thing that does work. In UI for ASP.NET MVC the querystring param would be "{gridname}-sort=" and in Core it only works WITHOUT the grid name. The problem with that is it will not work for pages with multiple grids.

Is there a way to configure it to prefix the URL params like was the default in ASP.NET MVC?

-Dan

Aleksandar
Telerik team
commented on 26 Dec 2022, 07:44 AM

Hello Mario,

The PrefixUrlParameters method is indeed available only for UI for ASP.NET MVC. As documented in the API if set to true the grid will prefix the query string parameters with its name during server binding. By default the grid will prefix the query string parameters. The key here is the server binding configuration. Server binding for the Grid is available only for Telerik UI for ASP.NET MVC suite, but this functionality is not available in the Telerik UI for ASP.NET Core Grid. This is one of the main differences between both suites and is documented in the Helpers Overview section(fourth point). 

By default, when Ajax binding is used the Grid will make a POST request - you can verify this both in the MVC and Core examples for Remote Data Binding of the Grid. With Server Binding the Grid will make a GET request to the action method which initially renders the view and if the PrefixUrlParameters is set to true the query string will contain the Grid's name. The Grid page, sort, filter, and group information is passed as query string parameters in that particular scenario.

If for some reason you need to make a GET request to a Grid's endpoint in ASP.NET Core than you can do so by setting the Type of the request. for example:

.DataSource(dataSource => dataSource
        .Ajax()
        .PageSize(20)
        .Read(read => read.Action("Orders_Read", "Grid").Type(HttpVerbs.Get))
        .Filter(filters =>
            {
                filters.Add(itm => itm.ShipName).Contains("C");
            })
     )

The above will make a GET ajax request that will look like this: https://demos.telerik.com/aspnet-core/grid/orders_read?sort=&page=1&pageSize=20&group=&filter=ShipName~contains~%27C%27

Here is a sample REPL where you can observe the above. Inspect the network tab and note the query string. 

Finally, if you need to pass the Grid Id as an additional parameter the workaround I can suggest is the following:

@(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.OrderViewModel>()    
    .Name("grid")
    .DataSource(dataSource => dataSource
        .Ajax()
        .PageSize(20)
        .Read(read => read.Action("Orders_Read", "Grid").Type(HttpVerbs.Get).Data("function(options) { return additionalData(options, 'grid')}"))
     )
)
<script>
    function additionalData(e,gridId){
        return{
            myParam:123,
            gridId:gridId
        }
    }
</script>

Here is a sample REPL demonstrating the above. The query string generated contains the data on sorting, filtering, etc, along with the additional data, including the Grid's id(though not added as a prefix):
https://demos.telerik.com/aspnet-core/grid/orders_read?sort=&page=2&pageSize=20&group=&filter=ShipName~contains~%27C%27&myParam=123&gridId=grid

I hope this helps.

0
Accepted
Chanaka
Top achievements
Rank 2
answered on 01 Jan 2013, 12:16 PM
Take a look @ my Reply
Do this 

Grid Sorting,Filtering,Group Save


Tags
Grid
Asked by
William
Top achievements
Rank 1
Iron
Answers by
Daniel
Telerik team
Chanaka
Top achievements
Rank 2
Share this question
or