Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    When clicking on a certain row for the first time, a different row gets selected

    Hello Isomorphic Team,

    We are experiencing an issue when selecting rows in a ListGrid via mouse click:
    When clicking on a certain row for the first time, a different row gets selected.
    This occurs
    • with Chrome and Edge (Chromium) but not with Firefox.
    • when the ListGrid is partially not visible at the bottom i.e. it is partially scolled out of view in its parent layout. If the ListGrid is scrolled into view and completely visible the issue does not occur.

    We tried to follow the selection logic and documented the following behaviour:
    • 1. List is partially not visible at the bottom. First row is clicked.
      • element.getBoundingClientRect() for gridBody returns top = 765 (Breakpoint: Element.js:1421 getBoundingClientRect)
      • this.getOffsetY() for gridBody returns y = 97 (Breakpoint: GridRenderer.js:6464 getEventRow)
      • 4th row gets selected and parent layout is scrolled down slightly.
    • 2. First row is clicked again
      • element.getBoundingClientRect() for gridBody returns top = 765
      • this.getOffsetY() for gridBody returns y = 34
      • 1st row gets selected
    • 3. Scrolling the parent layout back up. First row is clicked.
      • element.getBoundingClientRect() for gridBody returns top = 830
      • this.getOffsetY() for gridBody returns y = 32
      • 1st row remains selected

    Note: When breakpoints are disabled the slight scrolling mentioned above does not happen. It seems the "Reset native scroll-on-focus" (Canvas.js:18173) does not get triggered when breakpoints are enabled.
    Yet the issue still occurs. When the first row is clicked the first time, a wrong row gets selected.

    Maybe the native scroll from Chrome is not properly taken into account when calculating the OffsetY?

    SmartGWT Version 6.1p-2017-09-27
    SmartClient Version v11.1p_2017-09-27

    Best regards!

    #2
    So to confirm, when you click in the target grid, the grid as a whole is moved, and then row that ends up selected is the row that is now under the mouse?

    If so, what you're seeing is a native browser behavior where whatever is focused is moved into view.

    For end user, this is a jarring thing to happen, and the browser doesn't really let us prevent it because it's there for accessibility reasons. So the best thing for end users would be: size the grid and surrounding components so it does not end up partially out of view. This may involve using a SectionStack or similar container where you were previously just throwing several widgets into a scrolling container.

    If that's intractable for some reason, we can give some other approaches.

    Comment


      #3
      Originally posted by Isomorphic View Post
      So to confirm, when you click in the target grid, the grid as a whole is moved, and then row that ends up selected is the row that is now under the mouse
      If breakpoints are enabled for the JavaScript functions mentioned above:
      • yes that's the behaviour, i.e. as described above under 1., 2., 3.

      If no breakpoints are enabled in the browser as a normal end user would have it:
      • in this case the grid is not moved, i.e. no scrolling is visible.
      • Still the wrong row gets selected. We assume the native scrolling happens too and then the "Reset native scroll-on-focus" of SmartGWT (Canvas.js:18173) logic gets triggered.
      • But from the code it looks like it's happening after the row selection. Shouldn't it maybe performed in advance of handling the mouse down event?

      Originally posted by Isomorphic View Post
      If that's intractable for some reason, we can give some other approaches.
      Yes, please elaborate. Reworking the layout would only be a secondary solution if at all possible in certain cases.


      Comment


        #4
        Further observation shows that both isc.Browser.isChrome and isc.Browser.isSafari are true for us with Chrome 93.

        Setting isc.Browser.isSafari to false through the developer console fixes the issue of the wrong row getting selected, but it results in visual artifacts (columns are incorrectly rendered).

        In addition isc.Browser.isSafari being true leads to the following focus() call being triggered with Chrome in doHandleMouseDown (EventHandler.js:1960)
        Code:
        } else if (isc.Browser.isMoz || isc.Browser.isSafari) {
                    target.focus("focus on mousedown");
        Using a workaround to prevent this call on the ListGrid object for Chrome seems to fix the issue. Further tests on our side pending.

        Comment


          #5
          Hello Isomorphic Team,

          may I bring your attention again to this thread? Please have a look at my last two postings.

          Best regards!

          Comment


            #6
            This is hard to get to as we basically have to "steal" time since we show you as having neither licenses nor support.

            If you'd like to speed up resolution, please either become a customer, or at the least, provide a test case where we can see this actually happening, one that works on a recent version (instead of something 4 years old!).

            Internal details may be fun to gather but don't really help with resolution.

            Comment


              #7
              Hello,

              This bug appears to be only affecting Webkit/Chromium web browsers (including deprecated Safari 5.1.7 on Windows.)
              Please let me know if you need any additional information.

              Regards,

              Frederic

              Chrome version: Version 109.0.5414.120 (Official Build) (64-bit)
              SmartClient Version: v12.0p_2023-01-20/Pro Deployment (built 2023-01-20)

              Simple test case to reproduce the issue - Clicking on any cell on the first row actually selects the third row.

              Code:
              package com.example.client;
              
              import com.google.gwt.core.client.EntryPoint;
              import com.google.gwt.user.client.ui.RootPanel;
              import com.smartgwt.client.data.RecordList;
              import com.smartgwt.client.types.AutoFitWidthApproach;
              import com.smartgwt.client.types.Overflow;
              import com.smartgwt.client.types.SelectionStyle;
              import com.smartgwt.client.widgets.grid.ListGrid;
              import com.smartgwt.client.widgets.grid.ListGridField;
              import com.smartgwt.client.widgets.grid.ListGridRecord;
              import com.smartgwt.client.widgets.layout.VLayout;
              
              
              public class TestGwt implements EntryPoint {
              
                  public void onModuleLoad() {
              
                      ListGrid listGrid = new ListGrid();
                      listGrid.setID("lgTestGrid");
                      listGrid.setAlternateRecordStyles(true);
                      listGrid.setAlternateFieldStyles(false);
                      listGrid.setShowHeaderContextMenu(false);
                      listGrid.setBorder("1px solid #A7ABB4");
                      listGrid.setSelectionType(SelectionStyle.SINGLE);
                      listGrid.setAutoFitFieldWidths(true);
                      listGrid.setAutoFitWidthApproach(AutoFitWidthApproach.BOTH);
                      listGrid.setAutoFitFieldsFillViewport(false);
                      listGrid.setEditOnF2Keypress(false);
                      listGrid.setShowHeaderSpanTitlesInSortEditor(false);
                      listGrid.setCanFreezeFields(false);
                      listGrid.setCanPickFields(false);
                      listGrid.setCanPickOmittedFields(false);
                      listGrid.setBodyOverflow(Overflow.AUTO);
                      listGrid.setLeaveScrollbarGap(true);
                      listGrid.setCanSort(false);
                      listGrid.setCanResizeFields(true);
                      listGrid.setFastCellUpdates(true);
              
                      ListGridField lgfField1 = new ListGridField("lgfField1", "lgfField1");
                      ListGridField lgfField2 = new ListGridField("lgfField2", "lgfField2");
                      ListGridField lgfField3 = new ListGridField("lgfField3", "lgfField3");
                      ListGridField lgfField4 = new ListGridField("lgfField4", "lgfField4");
                      ListGridField lgfField5 = new ListGridField("lgfField5", "lgfField5");
                      listGrid.setFields(lgfField1, lgfField2, lgfField3, lgfField4, lgfField5);
              
                      RecordList records = new RecordList();
                      for (int i = 1; i <= 50; i++) {
                          ListGridRecord aRecord = new ListGridRecord();
                          aRecord.setAttribute("lgfField1", "&nbsp;" + " Field1 Row" + i);
                          aRecord.setAttribute("lgfField2", "&nbsp;" + " Field2 Row" + i);
                          aRecord.setAttribute("lgfField3", "&nbsp;" + " Field3 Row" + i);
                          aRecord.setAttribute("lgfField4", "&nbsp;" + " Field4 Row" + i);
                          aRecord.setAttribute("lgfField5", "&nbsp;" + " Field5 Row" + i);
                          records.add(aRecord);
                      }
                      listGrid.setData(records);
              
                      VLayout vlayout = new VLayout();
                      vlayout.setWidth(700);
                      vlayout.setHeight(400);
                      vlayout.setBorder("1px solid #A7ABB4");
                      vlayout.setPadding(10);
                      vlayout.setOverflow(Overflow.AUTO);
              
                      listGrid.setWidth(600);
                      listGrid.setHeight(500);
                      vlayout.addMember(listGrid);
              
                      RootPanel.get("testGridContainer").add(vlayout);
              
                  }
              }
              Last edited by fkamthong; 30 Jan 2023, 11:13.

              Comment


                #8
                Please try this with a stock skin and no other CSS in the project at all. Also get rid of your attempt to set bodyOverflow in combination with asking for autofitting (invalid).

                If that doesn't fix the problem, please indicate what you see happening: the grid is taller than the surrounding Layout, so are you seeing the grid scroll up (such that the header is no longer visible)?

                Comment


                  #9
                  Using the Tahoe skin (default ?), no other CSS, and removed all the bodyOverflow and autoFit*.

                  Removed the following lines:
                  Code:
                          listGrid.setAutoFitFieldWidths(true);
                          listGrid.setAutoFitWidthApproach(AutoFitWidthApproach.BOTH);
                          listGrid.setAutoFitFieldsFillViewport(false);
                  
                          listGrid.setBodyOverflow(Overflow.AUTO);
                  The grid is taller than the surrounding layout on purpose. The grid headers are visible when the application and grid data is loaded.

                  In this specific example, clicking on any cell to select a row causes the incorrect row to be selected/highlighted (e.g.: clicking on any cell on row 1 causes row 3 to be selected, clicking on row 4 results in row 6 to be selected) - this only happens with the first selection; subsequent row selections work correctly.

                  Incorrect row selection after clicking on a cell in row 1:
                  Click image for larger version  Name:	FSCapture2023-01-31 002.png Views:	0 Size:	30.1 KB ID:	269507
                  Note: The incorrect row selection does not happen when the outer layout is scrolled first.
                  Additionally, the inner layout/grid is sometimes scrolled up after the first row selection. This does not happen all the time.

                  Incorrect row selection and scrolling after clicking on a cell in row 1:

                  Click image for larger version  Name:	FSCapture2023-01-31 001.png Views:	0 Size:	29.8 KB ID:	269508
                  Last edited by fkamthong; 31 Jan 2023, 08:25. Reason: The issue does not present itself if the outer layout is scrolled before making the first row selection.

                  Comment


                    #10
                    We're having trouble reproducing this issue in our testing.

                    You mention that you're seeing this issue in the following version of SmartGWT:

                    SmartGWT Version 6.1p-2017-09-27
                    SmartClient Version v11.1p_2017-09-27

                    We are unable to reproducing the problem in our testing on more recent versions of SmartGWT so this may be a case where you're looking at an already worked-around issue.
                    We'd definitely recommend that you try to reproduce this with a more recent version if you haven't already.

                    The current release version of SmartGWT is 13.0, so we'd recommend you see if the problem occurs there for you with the latest nightly build.
                    It is also worth checking against the latest 6.1p nightly build - especially if you are currently using a version from 2017

                    Having said that - fundamentally the issue here is that the browser auto-scrolls focused elements into view, and this happens before the events that normally kick off grid selection occur. By the time the event arrives the grid has moved, and selection is done on the row that the event, in fact hit.
                    The framework already have some logic to attempt to account for this - but it may be the case that in some environments the native scroll occurs before any events are received.
                    If this is the case there may be little that can be done to account for this.

                    One option might be to isc.setScreenReaderMode() on your app. By enabling screenReaderMode, we cause native focus to go into the target cell or row rather than the listGrid body as a whole, so this would make the possibility of it being scrolled out of view less likely.

                    However - overall, a grid scrolling inside of another scrolling container is not a great UI. A better pattern is that, if a scrolling grid needs to be combined with other panels, each panel scrolls as needed (including the grid) so we recommend you reconsider your design if this is a possibility

                    Regards
                    Isomorphic software

                    Comment


                      #11
                      Version 6.1p was from the OP.

                      Originally posted by Isomorphic View Post
                      We're having trouble reproducing this issue in our testing.

                      You mention that you're seeing this issue in the following version of SmartGWT:

                      SmartGWT Version 6.1p-2017-09-27
                      SmartClient Version v11.1p_2017-09-27
                      I had updated to v12.0p_2023-01-20/Pro Deployment (built 2023-01-20) before submitting this.
                      I will test in 12.1, and if necessary also in 13.x

                      Comment


                        #12
                        I re-tested my sample application and was able to reproduce the issue from my IDE (Eclipse) and on a production server.
                        Versions tested:
                        • v12.1p_2023-02-02/Pro Deployment (built 2023-02-02),
                        • v13.0p_2023-02-04/LGPL Development Only (built 2023-02-04)
                        • SNAPSHOT_v13.1d_2023-02-07/EVAL Deployment
                        The problem with the suggestion that the scrolling be implemented in the parent container/panel is that grid headers would no longer be visible if the whole grid is scrolled.


                        Comment


                          #13
                          Please revisit our suggestions above - we are suggesting that you do not put the grid in a scrollable area at all, as that's generally a poor UI (double scrollbars).

                          We've also provided a workaround if you want to keep the same UI.

                          Further, the claimed problem is not reproducible for us. So, there appears to be something different in your project relative to a standard project. As we mentioned previously, there is likely some additional CSS or event handling logic in your project that we don't have, likely coming from a GWT module you are including.

                          Comment


                            #14
                            The test case is not representative of the real-world applications but it does serve to reproduce the issue.
                            The real applications have many other panels in the same scrollable area; We have no other choice but to put the grid(s) in a scrollable area.

                            We have zero additional CSS or GWT modules in the test case.
                            For full transparency, here is the gwt.xml file we used for the test case:

                            Code:
                            <?xml version="1.0" encoding="UTF-8"?>
                            <!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.8.2//EN"
                              "http://gwtproject.org/doctype/2.8.2/gwt-module.dtd">
                            
                              <module rename-to='testgwt'>
                            
                              <inherits name='com.smartgwt.SmartGwt' />
                            
                              <entry-point class='com.example.client.TestGwt'/>
                            
                              <source path='client'/>
                            
                            </module>
                            SC.setScreenReaderMode(true) seems to fix the issue but this means that we will have to re-test every affected application to see if there are any adverse effects other than the row outline (which is simple CSS fix)

                            I now suspect that a newer version of GWT might be the fix because you are unable to reproduce the issue.
                            Also as a matter of transparency, we are using GWT 2.8.2 (I should have mentioned this from the onset, sorry) - if upgrading GWT is the actual fix, we will have to re-test ALL our applications, not those affected by this scrolling issue... so, for now (in a crunch...), setting the screenReaderMode property will be the least disruptive fix.

                            Regards,

                            Frederic

                            Comment


                              #15
                              Sorry you're ending up having to re-test in a crunch period.

                              While it is possible, we consider it extremely unlikely that the GWT version is the reason why only you are having this problem, and we can't reproduce it. If we were troubleshooting this, we would look closely at the host .html file, as well as rebuild the project from scratch, to try to find the difference.

                              Note it's also possible that you have some kind of browser plugin that's got a very subtle interaction with your app. So we'd recommend testing on a clean browser install.

                              Comment

                              Working...
                              X