I would like to update my grid using datasourceurl, but allow local sorting that is maintained after the datasourceurl is updated. Is this possible?
Here's a basic scenario of what I'd like to happen:
-Grid is initially loaded.
-User sorts grid by clicking on a column header.
-User selects a different option from some dropdown.
-Grid's data is updated, but the sorting of the column is retained.
Here's what I've tried so far:
client-side:
var url = getNewUrlFromSomeDropDown();
$myGrid.igGrid('option', 'dataSource', url);
...which causes that url to be hit, which does something like this (MVC / C#):
server:
Example 1 (doesn't work at all, grid is blank):
public ActionResult _Employee_Grid(int someFilteringInt)
{ List<Employee> employees = GetEmployees(someFilteringInt); return Json(employees, JsonRequestBehavior.AllowGet);
}
Example 2 (Populates grid with new data, but the data is not sorted in any particular way, and the sorting arrows are lost.)
public ActionResult _Employee_Grid(int someFilteringInt) { List<Employee> employees = GetEmployees(someFilteringInt);
GridModel model = new GridModel(); GridSorting sorting = new GridSorting(); sorting.Mode = SortingMode.Single; model.Features.Add(sorting); model.DataSource = employees.AsQueryable<Employee>(); return model.GetData(); }
Also, in the 2nd example, I must add the sorting feature to the model, or else sorting is lost all together. This means that the GetData() method generates different JSON data depending on the features and properties of the grid? If so, this doesn't make sense IMO. GetData should have nothing to do with the grid's setup. It sort of defeats the purpose of only reloading the data instead of the entire grid.
Thanks in advance for any help!
hi,
if you'd like to just rebind the grid, you should do:
$("#grid1").igGrid("dataBind");
your code tries to change the data source url, after the grid has been created. i am not sure why you need to do this and i wouldn't advise to do this at runtime. a New data source may imply new columns schema, etc. there is no guarantee your grid will function correctly.
regarding the second scenario, this is related to the fact that MVC is stateless. When you define your grid in the View, and do a subsequent remote request to a controller action, there is no info on the server about how your grid is configured, therefore GetData can only infer features and parameters from the URL. i mean that local sorting is not preserved when you do remote paging/filtering, etc. So if you have local sorting, and remote paging enabled, this is how the url could look like:
http://localhost:14991/samplesbrowser/grid/PagingGetData?controller=GridLocalSorting?page=1&pageSize=25
there is no sorting information encoded in the url. If it was set to remote, then the sorted columns would have been encoded in the URL, and GetData would apply sorting, apart from paging, on the server side.
What you can do, as a workaround, is to manually call sortColumn from the sorting API, after the response comes . You can do this by handling the dataRendered event. here is how you can sort a column programatically:
$("#grid1").igGridSorting("sortColumn", "SomeColumnKey");
Hope it helps. Thanks,
Angel
Thanks Angel. The reason I'm updating the datasource is because the grid is filtered by a dropdown, and I would like to retrieve new data based on this filtering. The only way I've seen how to accomplish this using the datasourceUrl is to change the parameter in my querystring to retrieve new results. I'm not changing the entire address, just the querystring parameter. What is the correct way to handle this, to update my grid's data based on a dropdown value?
Regarding the second scenario, I'm not doing a page refresh, I'm doing an AJAX call, so the browser keeps it's state, MVC is irrelevant. Of course the server is not aware of the grid's display properties, but why should it need to be if it's just returning data? All the server should need to do is return the data, and the IG Grid should update it's data, it's filtering and sorting properties are already there on the client. The fact that it's also updating it's sorting, filtering, and other display information when it gets new data must be because I'm not going about updating the data correctly, because it would be illogical to update the grid's properties every time you update the data.
So, how should I handle this? What is the correct way to handle this, to update my grid's data based on a dropdown value?
I think maybe you're missing the point. Given what you've said, here's what I have to do in order to refresh the grid's data from an AJAX call that takes a value from my dropdown: (this took hours of reading, again, ugh)
-Enable remote filtering.
-Somehow hide the filtering textboxes below the column headers, because I don't actually want our users to be able to filter by columns, but this is the only way the IgGrid can refresh it's data apparently.
-When my dropdown changes, call the method igGridFiltering('filter', etc.). The "fieldName" here is just used so the grid will put it in the querystring, it doesn't actually have to exist in the grid, it's just a "workaround" to be able to pass querystring data.
-Either setup my MVC action to accept and parse OData, or parse it into a querystring in the $myGrid.data('igGrid').dataSource.settings.urlParamsEncoded event on the client, because that's what MVC accepts, querystrings.
-As before, my MVC action receives a querystring I can use, hits our Repository to get the updated data, and returns it in JSON.
-Voila, the grid is updated.
However, this REALLY smells. We're bastardizing the IgGrid's filtering functionality. Something as simple as refreshing the grid given a new dropdown selection is a common business need. There must be a better way to accomplish this?
I guess just using the datagridurl is not an option, but is there a way to update the grid's data without completely re-rendering the grid or losing it's features? Should I use the dataSourceObject option? I'm open to anything at this point.
Hi Josh,
Thanks for the detailed feedback. So you basically have the grid and filtering enabled, but you don't want any filter row inputs to be displayed, instead you'd like to re-render the grid based on a dropdown selection - and the dropdown is outside of the grid, something similar to this sample, i assume:
http://ko.infragistics.com/products/aspnet/sample/drop-down/sync-components
Please let me know if i understood correctly.
In this case you don't necessarily need to enable filtering and modify any URL parameters. you can bind the grid to JSON data, that comes from the server - you can call $.ajax({url: <your controller url>}) manually, and then set the data source like this and then rebind:
$("#grid").igGrid("dataSourceObject", json);$("#grid").igGrid("dataBind");
you can invoke this in your success callback.
So you need to handle the selection change event for your dropdown, and then invoke your controller, get the data and set it in the grid. I would prefer this approach.
Let me know if this helps. Thanks,
Thanks Angel. Same issue though, the grid loses all of it's display features despite the fact that we're only updating the data. Once I call dataBind, I can no longer sort the grid by clicking on the column headers.
hi Josh,
if you have initially bound the grid to an URL, and then to an in-memory json object, in the way you've described it, i suggest to re-set the dataSource after the grid is rebound, in the following way:
$("#grid1").data("igGrid").options.dataSource = <url>;
so that next time you sort a column, it calls your initial URL.
If you can send me some of your code i can check it out and give other suggestions.
Thanks,
I'm using local sorting. I don't want my URL to be called to sort. I take it you're suggesting this because using dataSourceUrl automatically sets sorting to remote? That's an unexpected and undocumented (or at least not obviously documented) side-effect if so.
At this point I've ruled out using dataSourceUrl, I don't think it was intended to be used if you want to update the data in the grid unless you use the built-in filtering, which I cannot in this case.
That being said, the alternative I'm now trying to use is this:
-Set the datasource in the MVC Helper on the intial page load
-When the dropdown is changed, get new JSON data from my server using an ajax request
-Update the grid using the method you suggested:
$("#grid").igGrid("dataSourceObject", json);
$("#grid").igGrid("dataBind");
However, the grid still loses its sorting ability. If I click on the column headers at after dataBind is called, nothing happens. It seems like the dataBind method causes all of the grid's features, including sorting, to reset? Is this correct? If so, is there another workaround for this other than manually storing the grid's features on the client and then resetting them after every dataBind? This won't be too much work, I'll abstract it away and just never call databind directly, but I just want to check because it seems illogical that dataBind would behave this way. Side-effects are bad.
Hello Josh,
I am following up to see if the service release has resolved this matter for you. Please let me know if you have any further questions concerning this matter.
Sincerely,Mike P.Developer Support EngineerInfragistics, Inc.www.infragistics.com
Thank you for the update. I have done some further looking into this matter and have the following information. With the sample you have provided with the service release 1010 I have been able to reproduce this issue. When I update to the latest service release of 2090 I am no longer able to reproduce this issue. I recommend you update to the latest service release for v12.1 of the jQuery product. You can do so by using the following steps:
1) Go to https://ko.infragistics.com/my-account/keys-and-downloads/2) Click on the Product Name for the 2012 Vol. 1 product you have. 3) Click the Service Releases section.4) Click and download the NetAdvantage jQuery 2012 Vol. 1 – Service Release.
Please let me know if you have any questions concerning this matter.
I took your project and made the first column hidden, and the issue occurs:
http://www.joshnoe.com/igGrid_Rebind_HiddenColumn.zip
My only guess is that we have different versions of Infragistics and mine (3.12.1.1010) has the issue whereas yours doesn't?
Thank you for the update. I am glad to hear you have been able to find a work around. I have done some modification of my own sample to set the first column to be hidden; I am still unable to reproduce this issue. Do you have an isolated sample that reproduces this issue? As I would like to look further into it and if necessary log it in our systems so it can be looked into by our development team.
Here's the TLDR for anyone who gets to here with the same issue:
Bug: If you set a column to be hidden, all columns defined after it will lose their sorting ability when dataBind is called.
Workaround: Define all hidden columns last, after all your other columns.
Mike, Thanks! Your example had a runtime error because you didn't include the Infragistics files, but I added them to the project and it worked. After comparing the javascript rendered from your example to our code, I eventually found the issue as stated above. In my case my first column was hidden, so none of the columns defined after it were sortable. There are some other points of weirdness about your example (returning the entire view in the dataSourceUrl???), but I'll try and research them and post in another thread if I have any questions. Much appreciated!