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

RadGrid Virtualization and Selction of Rows

1 Answer 348 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Christine
Top achievements
Rank 1
Christine asked on 07 Jan 2014, 05:46 PM
Hi All -

I just downloaded the latest version of Telerik (Q3 2103)to take advantage of the new Virtualization features in the radgrid.  The scrolling works perfectly for 300,000 records!  However, I have a GridClientSelectColumn in my grid so that user can chose to select rows by clicking on individual rows, as well as to click the header to "select all".  With the virtualization, it can't select all, but selects only those records in the current view.  I did notice that the new version does support persisting row selections across pages.  I assume this is happening client side (because when I set the items per view to 500+, the performance goes way down). 

What's the best way to implement a select all and de-select all for a grid that is virtualized?


Thanks!

Christy
Avi
Top achievements
Rank 1
commented on 12 Mar 2014, 12:16 PM

Hi, with virtualization we are not able to get either of these working:
1. We can't get Select All to select any more than the records loaded in the current view.
2. We can't get persisting row selections across pages to work.  If I select a record on page 1, then virtually scroll down and choose another record on page 20, when I try to do an action on those two records it only affects one of them.
Please advise!  We're really looking forward to using virtualization! :)
Thanks,
Adam
Antonio Stoilkov
Telerik team
commented on 17 Mar 2014, 09:17 AM

Hi Adam,

I have assembled a sample project showing how the selection of all rows could be achieved. Note that that implementing such behavior is out of the default RadGrid behavior and it workarounds a common virtualization problem. 

Regarding your second question: The second behavior is expected because the items on the first and on page 20 are the same (they only change their cell data). You could achieve the desired behavior. However the implementation will be specific to your exact scenario which is not clear from your description. You could try implementing it and if you have any questions related to RadControls to contact us.

Regards,
Antonio Stoilkov
Telerik
 

DevCraft Q1'14 is here! Watch the online conference to see how this release solves your top-5 .NET challenges. Watch on demand now.

 
Avi
Top achievements
Rank 1
commented on 24 Mar 2014, 08:19 AM

Thanks Antonio!  Here are some more specifics regarding my second question:

We are trying to implement scroll and virtualization functionalities on a RadGrid with paging.  We are trying to do this by getting all the records at one time and by implementing paging on the master table view.

Scrolling Issue:

1. We implemented scroll functionality on the RadGrid like the example below with client side events for row persistance on mulitple pages.  It's working as expected, but while scrolling down it's taking few seconds to display the records for the next page:

 <Scrolling AllowScroll="true" UseStaticHeaders="true" ScrollHeight="300px" EnableVirtualScrollPaging="true" />
 <ClientEvents OnRowCreated="RadGrid1_RowCreated" OnRowSelected="RadGrid1_RowSelected" OnRowDeselected="RadGrid1_RowDeselected" />


Virtualization Issue:

2. We implemented virtualization on the same grid like the example below, but here the issue is the grid is not working as expected: the scroller is not moving to the next page when we scroll down.  If we comment the clientevents tag, then it works, but we are unable to persist the records on multiple pages and we are unable to select all records (fully all records on all pages not just all records on the current page): 

<Scrolling AllowScroll="true" UseStaticHeaders="true" ScrollHeight="300px"  />
<Virtualization EnableVirtualization="true" ItemsPerView="50" MaxCacheSize="300"  />
<ClientEvents OnRowCreated="RadGrid1_RowCreated" OnRowSelected="RadGrid1_RowSelected" OnRowDeselected="RadGrid1_RowDeselected" />
Antonio Stoilkov
Telerik team
commented on 27 Mar 2014, 07:05 AM

Hi Adam,

Regarding the scrolling behavior: It is expected to have performance problems when loading a big amount of records for which we have created the Virtualization mechanism.

Regarding the Virtualization issue: The experienced problem is caused from the subscription to the RowCreated event. We are aware of the issue and will fix it as soon as possible. Until then you could subscribe to the RowCreated from the pageLoad event as shown in the example below.
<ClientSettings>
    <Scrolling AllowScroll="true" UseStaticHeaders="true" />
    <Virtualization EnableVirtualization="true" />
    <ClientEvents OnGridCreated="GridCreated" />
</ClientSettings>
function GridCreated(sender) {
    sender.add_rowCreated(RowCreated);
}
 
function RowCreated() {
 
}

Regards,
Antonio Stoilkov
Telerik
 

Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

 
Allen
Top achievements
Rank 2
Iron
Veteran
commented on 20 May 2022, 06:20 PM

It seems like this thread does not really address the issue of selecting rows that are not yet 'in scope'. 

This I have accomplished  so far only by stopping paging altogether and rebinding, then reselecting. 

At that point, of course, the selections are in the selectedItems collection for that unpaginated MasterTableView, but as soon as pagination is reasserted, any items not on the current page are not there any longer. 

So I have implemented the several workarounds from Telerik that have been offered for persisting row selections across postbacks and that seems to be behaving. 

What I have done now to generate the selection of all rows on the fly is to

  • generate a cache of the entire dataset, which I am concerned will blow up the server ( I am only working with ~20,000 total records though)
  • when 'Select All' (on all pages) is invoked from a menu, traverse the cache and persist enough of the identifiers to allow the aforementioned re-selection on PostBack to show the rows all selected when changing pages.  In here I am using the NeedsDataSource event.
  • This seems KLUTZY.  Is there any better alternative?
  • All of this selection happens as a 'batch' process.
Attila Antal
Telerik team
commented on 25 May 2022, 01:05 PM

Hi Allen,

I have already answered your Support Ticket, but I will share my answer in this forum thread as well.

There are two ways you can display 20K records in the Grid. 

First way

The first would be to render all 20K at once. If you do not use Pagination all items will be displayed, however, this would greatly impact the performance because the Server has to render that many items, as well as the Users' browser, has to display them. Both of them take time and are memory hungry.

If you had only 100 items, that would be no problem, and you could have all items selected at once.

 

Second way

The second way to display items would be by enabling pagination. This is the most optimal approach since the Grid will only render/display the number of items that were set through the PageSize property.

For instance, if you bind 100 records to the Grid, but the page size is set to 10, it will filter the data source by picking 10 records starting from the index of 0 up to the index of 10 and display them. When the second page is selected, the Grid will then use the index of 11 as a starting point and pick 10 more items that will be displayed accordingly. 

When filtering, the keywords are used against all 100 items, so it filters the data based on the keywords, but then it will again split that into 10 item pages and render only 10 items at once.

Having that in mind, even if there was an option to select all items across all pages, only the items on the actual page would be rendered and physically selected. The rest of the items would be waiting to be rendered.

By disabling the paging, you tell the Grid to render all the items, however, enabling it again, will only render a portion of it. That is the reason you cannot select all items across all pages without rendering them.

The way you would select all items across all pages would be by setting a global flag in the Session, Cookie, or as a Value to a HidenField that will persist across postbacks. Following the approach from the Persisting the Selected Rows Server-side on Sorting/Paging/Filtering/Grouping to select the Items in the PreRender, you can create a new condition that will check if the Global flag is set, and if so, select the items.

From this point on, regardless of which page you select in the Grid, the items that are to be rendered for that page will be selected anyways. It will behave as if you had all items selected virtually, but only really get selected when rendered.

With the current Grid's implementation, this would be the most efficient and straightforward option to select all items across all pages.

Allen
Top achievements
Rank 2
Iron
Veteran
commented on 31 May 2022, 12:16 PM

Attila, the hidden field / session variable idea is terrific.  I think that will be the way to go.  I should have thought to use the flag. I will post feedback. Thx.

1 Answer, 1 is accepted

Sort by
0
Antonio Stoilkov
Telerik team
answered on 10 Jan 2014, 08:07 AM
Hello Christy,

The experienced behavior is expected because you are trying to select rows that are not yet created. This behavior is one of the limitations of the virtualization mechanism. However, I can ensure you I have contacted our dev team in order to take a look at it and investigate if there is an option how to resolve the current behavior.

Regards,
Antonio Stoilkov
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
Christine
Top achievements
Rank 1
commented on 10 Jan 2014, 12:55 PM

Thanks!  My work around for now was to hide the select all button in the header row.  I created a checkbox button right above the grid, that when checked, does a post back to hide the GridClientSelectColumn and then change the CSS style of all the rows to make it "look" selected. It seems to work nicely, though obviously with larger datasets, it takes longer on the postback.  I'm guessing there is no way to do this outside of a postback (i.e. change the CSS of the entire grid, not just loop through each row and change the CSS?)?
Antonio Stoilkov
Telerik team
commented on 15 Jan 2014, 06:50 AM

Hello Christy,

You could achieve your scenario by using the GridTableView hideColumn client-side method to hide the select column. 
$find("RadGrid1").get_masterTableView().hideColumn(0);

To simulate selection of all rows you could add a className to the GridTableView element and define a CSS style that targets the tr elements and copy the styles for the .rgSelectedRow.
$find("RadGrid1").get_masterTableView().get_element().className += " allSelected";
.allSelected tbody > tr {
    background: red !important;
}

Regards,
Antonio Stoilkov
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
Allen
Top achievements
Rank 2
Iron
Veteran
commented on 08 Jun 2022, 02:08 PM

Relative to all this, I have mostly succeeded with  the following approach (as inspired by the helpful Attila et all from Telerik).  This is for client-side selection.

1) use the sessionStorage approach discussed under persisting row selections client-side to create a collection of selected items from the grid that stick through postback.  This works as advertised.

2) I augment this, probably NEEDLESSLY, with a collection of key-value pairs corresponding to the DataKeyValues (there are 2) of my selection list so that I can use that list elsewhere in my application.  I have been unable or too lazy to figure out how to access the sessionStorage object from the server directly, so I pass the selections through a hidden field as jSon.  I also have a hidden textbox inside an update panel which has its text changed whenever the selection changes, using a guid for the text value to ensure the text is in fact different (overkill, probably) and the textchanged event is fired.  That causes the postback and the hidden field contents are then available on the server-side.

QUESTION - if this flag textbox,   of size hw= 0 and invisible, is inside an Asp Panel, does it also need to be set to AutoPostBack?  

3) For SELECT ALL, I have a true false flag in a hidden field, also paired with a textbox, which sets a boolean by a menu click.  as the user pages through the grid, the rowCreated event (client-side) sees this indicator as true and consequently selects every row on render.  This stays in effect un UNSELECT ALL is clicked or the grid is rebound explicitly or other conditions....

4) I need these selections in hashtable form because the rest of this old application assumes selections are provided in a hashtable, so when requested, I generate the ht on the fly from the selections in the hidden field.

QUESTION -  the selectedItems collection internal to the radgrid seems to provide for simple <string>, <bool> key-value pairs (KVP), where the bool is true if the row is selected and null if not. But it does not appear to permit two-part keys.  That is why I am maintaining a largely redundant list in the hiddenfield, albeit only containing as many entries as are actually selected. 

Is that limitation of the selectedItems collection to simple KVP true?

Attila states above: 

"From this point on, regardless of which page you select in the Grid, the items that are to be rendered for that page will be selected anyways. It will behave as if you had all items selected virtually, but only really get selected when rendered."

So if the item selections over all pages are needed server-side e.g. for some batch operation, can I get around the need to maintain a separate list, or is this hidden field approach storing the two-part (n-part) keys for the selected rows as described above in fact the only way to go?

 

Attila Antal
Telerik team
commented on 13 Jun 2022, 01:57 PM

Hi Allen,

Addressing Question 1

Any element that is set to run at the server will be available on the server-side regardless of their height/width.

Example

<input type="text" runat="server" id="MyInputElement" value="myValue" />

<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />

protected void Button1_Click(object sender, EventArgs e)
{
    HtmlInputText myInput = MyInputElement;

    string inputValue = myInput.Value;
}

 

ViewState is responsible for tracking any changes made to these elements on the client-side and submitting that information to the server. There is no need to make the TextBox do PostBack unless you need that moment in time to capture the change event on the server.

The AutoPostBack will make this control submit the information. If you are using a Button (e.g. Submit) to collect the info from all Controls on the server, only the Button has to do PostBack, while the TextBox is still available to access.

 

Addressing Question 2

Regarding the SelectedItems internal, can you tell us which collection are you referring to? Currently, there are two methods you can use both on the Server and Client.

On the server, there are SelectedItems and SelectedIndexes methods. One returns a collection of data items and the other one is an array of String objects.

 

 

 

The Client-Side method "get_selectedItems()" returns an array of JavaScript objects (Telerik.Web.UI.GridDataItem).

The Client-Side method "get_selectedItemsInternal()" returns an array of JavaScript objects containing the ItemIndex (string) and the server ID (string) of that item/row.

 

 

 

Tags
Grid
Asked by
Christine
Top achievements
Rank 1
Answers by
Antonio Stoilkov
Telerik team
Share this question
or