[CLOSED] Problem with checkbox selection

  1. #1

    [CLOSED] Problem with checkbox selection

    Hello

    I'm facing strange problem with checkbox selection in the grid.
    Its reproducible only "sometimes" but on example below you can reproduce
    steps
    1) select two records on page 1
    2) select one record on page 2
    3) return to page 1 and just call .getSelected() method - 2 is returned, while expected is 3

    example below ( I tried to do the same think programatically and it works fine)
    I tried to record video as well



    Thanks
    Jiri

    <%@ Page Language="C#" %>
    
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Xml.Xsl" %>
    <%@ Import Namespace="System.Xml" %>
    <%@ Import Namespace="System.Linq" %>
    
    <script runat="server">
    	
    </script>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
    </head>
    <body>
    <script>
    
        function getSelectedRecords() {
    		var store = <%= GridPanel1.ClientID %>.store;
            var grid = <%= GridPanel1.ClientID %>;
            var selModel = grid.selModel;
    
    
            console.info('Selected: ' + selModel.getSelection().length)
        }
    
    	function processEror() {
            var store = <%= GridPanel1.ClientID %>.store;
            var grid = <%= GridPanel1.ClientID %>;
            var selModel = grid.selModel;
    
            selModel.select(store.getById(1),true);
            selModel.select(store.getById(2),true);
    
            console.info('Selected: ' + selModel.getSelection().length)
    
            selModel.select(store.getById(8),true);
    		console.info('Selected: ' + selModel.getSelection().length)
    
    		store.loadPage(1);
            console.info('Selected: ' + selModel.getSelection().length)
        }
    
    	Ext.onReady(function () {
    		var ret = [];
    		var store = <%= GridPanel1.ClientID %>.store;
          
    
            for (var i = 0; i < 100; i++) {
                ret.push({
                    Id: i,
                    Text: 'Text' + i
                });
            }
    
           
          //  store.loadPage(2);
    
            store.loadData(ret);
        });
    
    
    </script>
        <form runat="server">
            <ext:ResourceManager runat="server" Theme="Gray" Namespace="" RethrowAjaxExceptions="true"/>
    
    		
    		<ext:Button runat="server"  Text="GetSelected Records" OnClientClick="getSelectedRecords()"></ext:Button>
    		
            <ext:Button runat="server"  Text="Process Error programatically" OnClientClick="processEror()"></ext:Button>
    		
    	   
    		
    	    <ext:GridPanel
    		    id="GridPanel1"
    		    runat="server"
    		    
    		    Title="DataTable Grid"
    		    Stateful="True"
    		    StateID="gridState"
    		    
    		    >
    			<Store>
    				<ext:Store runat="server" ID="Store1"
    				           PageSize="10" AutoLoad="true" RemoteSort="false" RemotePaging="false">
    					<Sorters>
    						<ext:DataSorter Property="Text"/>
    					</Sorters>
    					<Model>
    						<ext:Model runat="server" IDProperty="Id">
    							<Fields>
    								<ext:ModelField Name="Id"/>
    								<ext:ModelField Name="Text"/>
    								<ext:ModelField Name="VersionStamp" />
    								<ext:ModelField Name="IsRetired" Type="Boolean" AllowNull="False"/>
    								<ext:ModelField Name="IsSaved" Type="Boolean" AllowNull="False"/>
    								<ext:ModelField Name="IsDeleted" Type="Boolean" AllowNull="False"/>
    							</Fields>
    						</ext:Model>
    					</Model>
    				</ext:Store>
    			</Store>
    		    <ColumnModel runat="server">
    			    <Columns>
    				    <ext:Column runat="server" Text="Id" DataIndex="Id" Flex="1"/>
    				    <ext:ComponentColumn runat="server" Text="Text" DataIndex="Text" Flex="1" Editor="True">
    						<Component>
    							<ext:TextField runat="server"></ext:TextField>
    						</Component>
    				    </ext:ComponentColumn>
    					
    				 
    			    </Columns>
    		    </ColumnModel>
    			
    		    <SelectionModel>
    			    <ext:CheckboxSelectionModel runat="server" Mode="Simple">
    			    </ext:CheckboxSelectionModel>
    		    </SelectionModel>
    		    <BottomBar>
    			    <ext:PagingToolbar runat="server" StoreID="Store1" />
    		    </BottomBar>
    	    </ext:GridPanel>
        </form>
    </body>
    </html>
    Last edited by fabricio.murta; Mar 22, 2023 at 7:26 PM.
  2. #2
    Hello Jiri!

    The following thread's second post works for me:
    - Gridpanel - client side selected rows with paging example

    ...even though that was an Ext.NET 1 question! :-)

    So, is <%= GridPanel1.ClientID %>.getRowsValues({selectedOnly : true}); good enough for your problem?

    Looking forward to your follow-up!
    Fabrício Murta
    Developer & Support Expert
  3. #3
    Ok

    just wondering what is the reason why

    selModel.getSelection()

    does not work - should we replace all our selmodel.getSelection() by the getRowsValues({selectedOnly : true}); ?
  4. #4
    Hello again, Jiri!

    Quote Originally Posted by jirihost
    selModel.getSelection()

    does not work
    It works. Please don't get the wrong idea. It does work and does what it is meant to. The thing is, once you load a page, it may lose track of the (potential) dozens other pages, with its noble intention to keep the page fast in the browser.

    There are means, known as SelectionMemory that might just do what you need and keep selModel.getSelection() up-to-date. One way or another, I believe that if you are only having this problem now, your grids weren't paging ones before, were they?

    Here, take a look at this example using Selection Memory plugin, it is another approach, but then you'd need to use grid.getSelectionMemory().selectedIds, which will probably be just extra code and logic for your needs.

    Quote Originally Posted by jirihost
    should we replace all our selmodel.getSelection() by the getRowsValues({selectedOnly : true}); ?
    One way or another, I don't really see how to get the selected records in a paging grid without changes. If keeping selmodel.getSelection() really is preferably, all you'd need to do is an override and include that wherever you use the paging grid.

    Basically the selection model would need to (rough code draft):

    if (selmodel.getStore().isPaging) {
      records = selmodel.view.ownerGrid.getRowsValues({selectedOnly: true});
      // then wrap the records into a model instance like getSelection() normally does and return it
    } else {
      this.callParent(arguments);
    }
    Just a rough idea if you want to explore it. If you want to go for it, we can delve into the inner workings. Again, one way or another, the current approach of getSelected() and paging grids is not working and something will have to change for it to; what exactly changes, is up to you.

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  5. #5
    Hello

    if I uderstand correctly I should use onr of meethodss
    - grid.getSelectionMemory().selectedIds
    -getRowsValues


    I'm still confused by two things
    1) what the getSelection method does and what it is meant to

    maybe can you little bit ellaborate on " It does work and does what it is meant to. The thing is, once you load a page, it may lose track of the (potential) dozens other pages, with its noble intention to keep the page fast in the browser."

    so - does it mean when I load another page (whole this thread is about client side paging, not server side), the selection is always empty? (it's not according my observation)

    for example
    on page 1 I select 1 record
    on page 2 I select 1 record
    and finally on page 3 I select 1 record
    -> getSelection returns me (as I expect) 3 records

    then I just return to page 2 without modifying anything or selecting anything
    and now the getSelection returns me 1 record (the one on page 2)
    what is logic bethind that please?

    2) when I do similar thing programatically it works
    (using sample from begining of thread and this snippet:

    
    	function processEror() {
            var store = <%= GridPanel1.ClientID %>.store;
            var grid = <%= GridPanel1.ClientID %>;
            var selModel = grid.selModel;
    
            selModel.select(store.getById(1),true);
            
    		store.loadPage(2);
    
            selModel.select(store.getById(2), true);
            console.info('Selected: ' + selModel.getSelection().length)
    
    		selModel.select(store.getById(8), true);
    
    		console.info('Selected: ' + selModel.getSelection().length)
    
    		store.loadPage(1);
            console.info('Selected: ' + selModel.getSelection().length)
        }
  6. #6
    Hello again, Jiri!

    Quote Originally Posted by jirihost
    1) what the getSelection method does and what it is meant to
    It gets the selection from the SelectionModel. It's scope is limited to what the current view has. It's tied to the view, not to the store nor the grid. So when you have grid paging, it should only return selection of the current loaded page.

    Quote Originally Posted by jirihost
    for example
    on page 1 I select 1 record
    on page 2 I select 1 record
    and finally on page 3 I select 1 record
    -> getSelection returns me (as I expect) 3 records

    then I just return to page 2 without modifying anything or selecting anything
    and now the getSelection returns me 1 record (the one on page 2)
    what is logic bethind that please?
    This simply means that grid paging was not designed with the view's selection model in mind. The grid.getRowsValues() is an Ext.NET specific extension to the Grid Panel that takes the grid's SelectionMemory into account (thus, basically a shortcut to pull grid.getSelectionMemory().selectedIds when appropriate).

    The grid.getSeleciton() in turn, is but a shortcut for grid.getSelectionModel().getSelection(). And while we are at it, grid.getSelectionModel() is a shortcut for grid.getView().getSelectionModel().

    In the sample you shown, it shows how view selection is not updated if the next page has no selection, and if the loaded page has any selection, it is rewritten with just the selection to that page you just loaded. Paging does not guarantee the view selection is accurate, so when you use paging, you shouldn't rely in querying the view's selection.

    Quote Originally Posted by jirihost
    2) when I do similar thing programatically it works
    (using sample from begining of thread and this snippet:
    And after you just run and programmatically got 3 selected records, just click again to query getSelection().length. You get 1 now, right? That's because the code-driven calls are done before layout processing, and the selection update comes as a side effect of every page's load -- which is skipped when you quickly programmatically switch pages back and forth. Internally, Ext JS keeps deferring layout updates until the running method finishes, so that it only does the expensive layout update with the state the function left, not every time.

    So when it's running line by line, it still didn't refresh the layout to load the view. It does flicker once done, and that's just when the selection gets updated to 1.

    If, instead, you set processEror() to load a page without selection, say store.loadPage(5), you'd still read 3 as the result of getSelection(). Again, this value is only updated when you load a page that has a selection, because the paging grid wants to show selected items as selected when a given page is brought into view, and it simply doesn't update the view's selection count if there's no selection in the page. This selection update is a side effect of loading a view with selection, but neither the view or paging feature know each other, and you won't get reliable results from the view's SelectionModel.

    Simply, when the paging feature was implemented, there was a choice to be made:
    a) change every current and future selection model to support and carry on selection when paging is enabled
    b) have a specific and centralized means to fetch selection when using paging.

    (b) was the choice back then, as much as it brought users confusion not just now, but over time, it was less susceptible to failures across Ext JS upgrades.

    If you really want to use the view's getSelection(), you can always override the method to check whether the view's grid's store is a paging one and use the selection memory or getRowsValues() approach. It's just not suitable to all use cases, so perhaps it's not a good idea to patch it mainstream.

    Hope this clarifies the matter for you. Let us know if you still need more clarification or have further questions about it.
    Fabrício Murta
    Developer & Support Expert
  7. #7
    Ok perfect

    things starts to make sence now

    feel free to close this thread ( and write your last post to some stone as it contains more info then I found myself during last week :-))
  8. #8
    Hello again, Jiri!

    Glad we could clarify your questions, thanks for the feedback!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. Replies: 2
    Last Post: Dec 01, 2017, 6:04 PM
  2. [CLOSED] Problem with Checkbox Selection in GridPanel
    By opendat2000 in forum 4.x Legacy Premium Help
    Replies: 2
    Last Post: Aug 05, 2016, 12:27 PM
  3. [CLOSED] Facing problem with checkbox selection problem in gridpanel.
    By arjunrvasisht in forum 2.x Legacy Premium Help
    Replies: 1
    Last Post: May 06, 2015, 3:55 PM
  4. Replies: 0
    Last Post: Apr 06, 2015, 1:43 PM
  5. Replies: 2
    Last Post: Dec 07, 2011, 7:00 PM

Posting Permissions