[CLOSED] Getting and setting the current page of a grid panel based on the selected row.

  1. #1

    [CLOSED] Getting and setting the current page of a grid panel based on the selected row.

    I have a grid panel that is loaded with say 40 items and the page size is set to 10. In code behind I am selecting a row based on a value from the database. As an example lets assume it is on page 3. I can set the grid to show page 3 in code behind using nameOfStore.LoadPage(3) which works. The problem is I can't figure out how to programatically determine the record index or page on which the selected row resides.
    This is the code behind that sets the selected row based on a rowID:
     Dim rowID As String = Nothing
         rowID = String.Format("{0}|{1}", "textKey", ID_in)
         Dim sm As CheckboxSelectionModel = grdComposite.GetSelectionModel
         sm.ClearSelection()
         sm.SelectedRows.Add(New SelectedRow(rowID))
    In all cases sm.SelectedIndex and sm.SelectedRow.RowIndex are always -1 and I don't see any other property that would tell me the row number of the record I selected. Once I have that I can use that and the PageSize to determine which page to load.

    This is some of the grid markup:
                <ext:GridPanel
                                            runat="server"
                                            ID="grdComposite"
                                            Title="Select a Composite Allocation"
                                            BodyPadding="15"
                                            Padding="10"
                                            HeightSpec="100%">
    
                                            <Store>
                                                <ext:Store
                                                    runat="server"
                                                    ID="strComposite"
                                                    PageSize="10">
                                                    <Model>
                                                        <ext:Model runat="server" IDProperty="RowID">
                                                            <Fields>
                                                                <ext:ModelField Name="RowID" Type="String" />
                                                                <ext:ModelField Name="CompositeID" Type="String" />
                                                                <ext:ModelField Name="CompositeName" />
                                                            </Fields>
                                                        </ext:Model>
                                                    </Model>
                                                       
                                                </ext:Store>
                                            </Store>
    
                                            <View>
                                                <ext:GridView
                                                        runat="server"
                                                        TrackOver="false"
                                                        EmptyText="No composites available.">
                                                    <GetRowClass Handler="return record.get('RangeClass');" />
                                                </ext:GridView>
                                            </View>
    
                                            <ColumnModel>
                                                <Columns>
                                                    <ext:Column
                                                            runat="server"
                                                            ColumnID="colCompositeName"
                                                            Header="Composite"
                                                            DataIndex="CompositeName"
                                                             
                                                            Flex="1"
                                                            MenuDisabled="true">
                                                    </ext:Column>
    
                                                </Columns>
                                            </ColumnModel>
                                                
                                            <SelectionModel>
                                                <ext:CheckboxSelectionModel
                                                        runat="server"
                                                        ID="grdCompositeSelectionModel"
                                                        AllowDeselect="false"
                                                        Mode="Single">
                                                    <DirectEvents>
                                                        <Select
                                                            OnEvent="grdCompositeSelectionModel_RowSelect" Before="maskInsightPanels(true)">
                                                            <ExtraParams>
                                                                <ext:Parameter Name="investmentid"  Value="record.getId()" Mode="Raw" />
                                                                <ext:Parameter Name="productminimums"  Value="record.productminimums" Mode="Raw" />
                                                                <ext:Parameter Name="Values" Value="Ext.encode(#{grdComposite}.getRowsValues({selectedOnly : true}))" Mode="Raw" />
                                                            </ExtraParams>
                                                        </Select>
                                                    </DirectEvents>
                                                </ext:CheckboxSelectionModel>
                                            </SelectionModel>
                                            <BottomBar>
                                                <ext:PagingToolbar runat="server" />
                                            </BottomBar>
                                        </ext:GridPanel>
    Last edited by fabricio.murta; Aug 11, 2017 at 7:56 PM.
  2. #2
    Hello @rmelancon!

    In code behind, specially if this is during a page loading procedure, there won't be any record index or row as the grid simply is not rendered yet. It would depend on the ordered column and other factors.

    If you are not enforcing any sorting in the grid, then row index would just be the current entry and you could rely on that for first grid panel display, assuming you are not saving client-side state on the page.

    If you are sorting, saving client-side state, then you would have to recover that information somehow, and sort the entries from server side to infer their positions and call for the right page.

    But you can also do it from client-side.

    Assuming you have just one selection, you can get the selected item with Ext.view.View.getSelection(). Then, assuming you call this after the page is rendered and all ready to be worked with, you can call the store's Ext.data.PagingStore.findPage(), which is exclusive to Ext.NET and, the result of that can be fed to Ext.data.Store.loadPage().

    Code-wise, assuming you already have a variable pointing to your grid's view and store (selection model can be used in place of the view in this case), here's a pragmatic way of what you should do (you may want to check if there's any selection beforehand).

    store.loadPage(store.findPage(view.getSelection()[0]))
    I hope this helps!
    Fabrício Murta
    Developer & Support Expert
  3. #3
    So the row is being selected in code behind during PageLoad event. On the client side what event can I use that will have the selected row set where I can use the client side code you provided? I tried putting a listener on the views "AfterRender" but the selection models getSelection has no items selected, so I guess I'm not understanding the sequence of events.
  4. #4
    Hello @rmelancon!

    Well, for one option you could add the client side call just after the line you set the selected value. I mean, one option would be:

    sm.SelectedRows.Add(New SelectedRow(rowID))
    X.AddScript("App.grdComposite.getStore().loadPage(App.grdComposite.getStore().findPage(App.grdComposite.getView().getSelection()[0])")
    So that right after sending the client-side equivalent command to select the row you want, it will then call the grid pager to move on.
    But this could be too early (if the grid is not rendered, for example). If that's the case, you can add the same code in resource manager's DocumentReady event, or on the grid view's AfterRender or maybe ViewReady. Well, there are several options, and some may not work.

    If you need a more precise solution, join your code snippets above in a runnable and simplified test case that reproduces your scenario and we can tell with precision one or more options you have to have it working the way you need.

    Some templates of runnable, one-page test code here: More Information Required.

    Tips on trimming out unnecessary/unrelated code from your real-world code, cutting it down to a simplified test case that illustrates your scenario without sharing proprietary code: Tips for creating simplified code samples.

    I assure you it will be worth your while reviewing the two topics above. Not for this specific inquiry only, but for all future ones.

    Don't worry, you can provide the "put-together" test case code behind code on VB.NET.

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  5. #5
    Put together an example, the selected row is on the second page and the javascript that attempts to set the page causes the grid to empty as it is setting to a page that doesn't exist because getSelection() is still empty.

    <%@ Page Language="vb" %>
    
    <!DOCTYPE html>
    
    <script runat="server">
        Private ReadOnly Property TestData() As Object()
            Get
                Dim now As DateTime = DateTime.Now
    
                Return New Object() {New Object() {"PC5a8AdEsKHJssf0dQSY0yq+YbvdbZh5gKZkr9oGZcI10gcqXrzw+fN6otHwujgdYpe8+6M/AEParkzJIvI3mPLG4Unt2mo0p370OuZUTpQbFaRU2NpWjQ==", "3m Co", 71.72, 0.02, 0.03, now},
                    New Object() {"Vzsg+QuKvBT+YrxSc4Fjo4PbnXc30rhsQyRK0V2fnRzYx1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QubnXc30rhsQyRK0V2fnRzYx1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsgnXc30rhsQyRK0V2fnRzYx1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+Y0V2fnRzYx1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+YK0V2fnRzYx1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+YrxSc4Fjo4PbnXc30rhsQyRKP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+YrxSc4Fjo4PbnXc30rhsQyRK0V2fnRzYx1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+YrxK0V2fnRzYx1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+YrxScK0V2fnRzYx1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+YrxSc4FnRzYx1JedUuIbn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+YrxSc4Fjo4Px1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+YrxSc4Fjo4Pn1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+YrxSc4Fjo4PbnXUu2Ibn5uVP68cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ==", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"jWDvWMKf+WEkV9o+y/n5XiajTQtE2Hzv0VguMIxWRbbHkFtWKmkx4e3eFwGeLs7T7BrVxfHglj05sWJ8G7+MkaPdQHIoPdQP0KfLvSngH9BANF3EV1bwzA==", "Government Motors Corporation", 30.27, 1.09, 3.74, now}}
            End Get
        End Property
    
        Protected Sub Page_Load(sender As Object, e As EventArgs)
            If Not Ext.Net.X.IsAjaxRequest Then
                Me.Store1.DataSource = Me.TestData
    
                'attempt to select second row
                Dim rowID As String = "Vz+EvcgoZ2PjG8HeRGsg+QuKvBT+YrxSc4Fjo4PbnXc30rhsQyRK0V2fnRzYx1JedUu2Ibn5uVP6a4G8cpltKVZz4kasruS0oSxq+GqxA1mhzS6kPE/2rQ=="
                Dim sm As CheckboxSelectionModel = grdComposite.GetSelectionModel
                sm.ClearSelection()
                sm.SelectedRows.Add(New SelectedRow(rowID))
                Ext.Net.X.AddScript("setGridPage();")
            End If
        End Sub
    
        Protected Sub MyData_Refresh(sender As Object, e As StoreReadDataEventArgs)
            Me.Store1.DataSource = Me.TestData
            Me.Store1.DataBind()
        End Sub
    </script>
    
    <html>
    <head runat="server">
        <title></title>
        <script type="text/javascript">
            var overIt = function () {
                console.log('over handler');
            }
    
            var setGridPage = function() {
                var grd = <%= grdComposite.ClientID%>;
                grd.getStore().loadPage(grd.getStore().findPage(grd.getView().getSelection()[0]));
            }
    
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <ext:ResourceManager runat="server" />
            <ext:Viewport ID="vp1" runat="server" Layout="FitLayout" Scrollable="Both">
                <Items>
                    <ext:GridPanel
                        ID="grdComposite"
                        runat="server"
                        Title="Grid"
                        BodyPadding="15"
                        Padding="10"
                        HeightSpec="100%"
                        >
                        <Store>
                            <ext:Store
                                ID="Store1"
                                runat="server"
                                RemoteSort="false"
                                OnReadData="MyData_Refresh"
                                PageSize="5">
                                <Model>
                                    <ext:Model runat="server" IDProperty="EncryptedID">
                                        <Fields>
                                            <ext:ModelField Name="EncryptedID" />
                                            <ext:ModelField Name="company" Type="string" />
                                            <ext:ModelField Name="price" Type="Float" />
                                            <ext:ModelField Name="change" Type="Float" />
                                            <ext:ModelField Name="pctChange" Type="Float" />
                                            <ext:ModelField Name="lastChange" Type="Date" />
                                        </Fields>
                                    </ext:Model>
                                </Model>
                            </ext:Store>
                        </Store>
                        <ColumnModel runat="server">
                            <Columns>
                                <ext:Column runat="server" Text="Company" DataIndex="company" Flex="1">
                                    <Editor>
                                        <ext:TextField runat="server" />
                                    </Editor>
                                </ext:Column>
                                <ext:Column runat="server" Text="Price" Width="75" DataIndex="price">
                                    <Editor>
                                        <ext:TextField runat="server" />
                                    </Editor>
                                </ext:Column>
                                <ext:Column runat="server" Text="Change" Width="75" DataIndex="change" />
                                <ext:Column runat="server" Text="Change" Width="75" DataIndex="pctChange" />
                                <ext:DateColumn
                                    runat="server"
                                    Text="Last Updated"
                                    Width="120"
                                    DataIndex="lastChange"
                                    Format="HH:mm:ss" />
                            </Columns>
                        </ColumnModel>
                        <SelectionModel>
                            <ext:CheckboxSelectionModel
                                    runat="server"
                                    ID="grdCompositeSelectionModel"
                                    AllowDeselect="false"
                                    Mode="Single">
                            </ext:CheckboxSelectionModel>
                        </SelectionModel>
                        <BottomBar>
                            <ext:PagingToolbar runat="server" />
                        </BottomBar>
                    </ext:GridPanel>
                </Items>
            </ext:Viewport>
        </div>
        </form>
    </body>
    </html>
    Last edited by rmelancon; Aug 09, 2017 at 5:39 PM.
  6. #6
    Hello @rmelancon!

    I see, now I see that there's some race issues going on. Here I'll show you three alternatives to get to the page you have it selected, from the most server-bound approach to the most client-bound approach. I hope you don't mind me changing your long long keys into shorter ones, I believe it does not lose the point with that.

    It may happen the different approaches works better or worse depending on your actual use case. I believe the #2 and #3 would be more robust in case you have custom sorting.

    The issue that was happening is that the selection model's selection only fills up once you navigate to the page. Well, the idea of paging in first place is not preloading data up front so the selection also follows and should be pulled off 'selection memory' which is checked every time you switch to a new page in the paging grid.

    Here's the code:

    <%@ Page Language="vb" %>
    
    <!DOCTYPE html>
    
    <script runat="server">
        Private ReadOnly Property TestData() As Object()
            Get
                Dim now As DateTime = DateTime.Now
    
                Return New Object() {New Object() {"uuid01", "3m Co", 71.72, 0.02, 0.03, now},
                    New Object() {"uuid02", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid03", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid04", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid05", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid06", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid07", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid08", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid09", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid10", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid11", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid12", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid13", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid14", "Boeing Co.", 75.43, 0.53, 0.71, now},
                    New Object() {"uuid15", "Government Motors Corporation", 30.27, 1.09, 3.74, now}}
            End Get
        End Property
    
        Protected Sub Page_Load(sender As Object, e As EventArgs)
            If Not Ext.Net.X.IsAjaxRequest Then
                Me.Store1.DataSource = Me.TestData
    
                ' select a row by its ID (model's IdProperty field value)
                Dim rowID As String = "uuid12"
                Dim sm As CheckboxSelectionModel = grdComposite.GetSelectionModel
                sm.ClearSelection()
                sm.SelectedRows.Add(New SelectedRow(rowID))
    
                ' Approach #1: set page by making math from server side
                Store1.LoadPage(getRecordPage(rowID))
    
                ' Approach #2: pass (again) the selected record ID so that the
                '              client-side code moves to that page
                'Ext.Net.X.Call("setGridPageById", rowID)
    
                ' Approach #3: let client-side handle it, by using unsupported
                '              client-side code (may break in future releases
                '              without notice)
                'Ext.Net.X.AddScript("setGridPage();")
            End If
        End Sub
    
        ' Approach #1: set page by making math from server side.
        Private Function getRecordPage(id As String) As Integer
            Dim row As Integer
            Dim page As Integer
            grdComposite.SetTitle("Grid [" & id.Substring(4, 2) & "]")
            If Integer.TryParse(id.Substring(4, 2), row) Then
                page = row / Store1.PageSize
    
                If (row Mod Store1.PageSize) > 0 Then
                    page += 1
                End If
            Else
                page = 1
                Ext.Net.X.Msg.Alert("No selection", "Unable to switch pages to selection if there's no selection at all.").Show()
            End If
    
            Return page
        End Function
    
        Protected Sub refreshData(sender As Object, e As StoreReadDataEventArgs)
            Store1.DataSource = Me.TestData
            Store1.DataBind()
        End Sub
    </script>
    
    <html>
    <head runat="server">
        <title></title>
        <script type="text/javascript">
            var overIt = function () {
                console.log('over handler');
            }
    
            // Approach #2: pass (again) the selected record ID so that the
            //              client-side code moves to that page
            var setGridPageById = function (recordId) {
                var grd = <%= grdComposite.ClientID %>,
                    store = grd.getStore(),
                    idProperty = grd.getStore().getModel().idProperty,
                    record = store.findRecord(idProperty, recordId);
    
                if (record) {
                    store.loadPage(store.findPage(record));
                }
            }
    
            // Approach #3: let client-side handle it, by using unsupported
            //              client-side code (may break in future releases
            //              without notice)
            var setGridPage = function() {
                var grd = <%= grdComposite.ClientID %>,
                    selModel = grd.getSelectionModel(),
                    store = grd.getStore(),
                    model = store.getModel(),
                    idProperty = model.idProperty,
                    recordId;
    
                if (selModel.selectedData !== undefined) {
                    recordId = selModel.selectedData[0].recordID;
                } else if (selModel.selectedIds !== undefined) {
                    recordId = Object.keys(selModel.selectedIds)[0];
                }
    
                if (recordId === undefined) {
                    Ext.Msg.alert("No selection", "Unable to switch pages to selection if there's no selection at all.");
                } else {
                    var record = store.findRecord(idProperty, recordId);
                    store.loadPage(store.findPage(record));
                }
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <ext:ResourceManager runat="server" />
            <ext:Viewport ID="vp1" runat="server" Layout="FitLayout" Scrollable="Both">
                <Items>
                    <ext:GridPanel
                        ID="grdComposite"
                        runat="server"
                        Title="Grid"
                        BodyPadding="15"
                        Padding="10"
                        HeightSpec="100%"
                        >
                        <Store>
                            <ext:Store
                                ID="Store1"
                                runat="server"
                                RemoteSort="false"
                                OnReadData="refreshData"
                                RemotePaging="false"
                                PageSize="5">
                                <Model>
                                    <ext:Model runat="server" IDProperty="EncryptedID">
                                        <Fields>
                                            <ext:ModelField Name="EncryptedID" />
                                            <ext:ModelField Name="company" Type="string" />
                                            <ext:ModelField Name="price" Type="Float" />
                                            <ext:ModelField Name="change" Type="Float" />
                                            <ext:ModelField Name="pctChange" Type="Float" />
                                            <ext:ModelField Name="lastChange" Type="Date" />
                                        </Fields>
                                    </ext:Model>
                                </Model>
                            </ext:Store>
                        </Store>
                        <ColumnModel runat="server">
                            <Columns>
                                <ext:Column runat="server" Text="Company" DataIndex="company" Flex="1">
                                    <Editor>
                                        <ext:TextField runat="server" />
                                    </Editor>
                                </ext:Column>
                                <ext:Column runat="server" Text="Price" Width="75" DataIndex="price">
                                    <Editor>
                                        <ext:TextField runat="server" />
                                    </Editor>
                                </ext:Column>
                                <ext:Column runat="server" Text="Change" Width="75" DataIndex="change" />
                                <ext:Column runat="server" Text="Change" Width="75" DataIndex="pctChange" />
                                <ext:DateColumn
                                    runat="server"
                                    Text="Last Updated"
                                    Width="120"
                                    DataIndex="lastChange"
                                    Format="HH:mm:ss" />
                            </Columns>
                        </ColumnModel>
                        <SelectionModel>
                            <ext:CheckboxSelectionModel
                                    runat="server"
                                    ID="grdCompositeSelectionModel"
                                    AllowDeselect="false"
                                    Mode="Single">
                            </ext:CheckboxSelectionModel>
                        </SelectionModel>
                        <BottomBar>
                            <ext:PagingToolbar runat="server" />
                        </BottomBar>
                    </ext:GridPanel>
                </Items>
            </ext:Viewport>
        </div>
        </form>
    </body>
    </html>
    I hope this helps and at least one of the options fits your scenario!

    (notice: you want to switch commented/uncommented leaving only one of these three lines uncommented at a time: 39, 43 or 48, each triggering the different "approach")
    Fabrício Murta
    Developer & Support Expert
  7. #7
    Thanks so much for the help! Went with Approach 2 and it works well.
  8. #8
    Hello!

    Thanks for the feedback, and glad one approach worked well for you!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. Replies: 11
    Last Post: Feb 29, 2012, 3:57 PM
  2. Replies: 1
    Last Post: Nov 18, 2010, 5:21 AM
  3. Replies: 1
    Last Post: Nov 10, 2010, 8:47 PM
  4. [CLOSED] How to get the current node selected in a tree panel?
    By flormariafr in forum 1.x Legacy Premium Help
    Replies: 4
    Last Post: Aug 13, 2010, 4:43 PM
  5. [CLOSED] Grouping doesn't group entire grid data...just current page.
    By rthiney in forum 1.x Legacy Premium Help
    Replies: 5
    Last Post: Mar 05, 2010, 2:34 PM

Posting Permissions