Announcement

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

    Inconsistency in ListGrid.rowEditorEnter between desktop and mobile

    Hi,

    I have got a problem with event ListGrid.rowEditorEnter not triggered in some circumstances on mobile device (also observed in browser's responsive mode).

    In the following example there is a ListGrid with person field of type ComboBoxItem as a first column. If you run this example and double click first row and first column (person) to enter grid's edit mode, you will see a notification as a result of rowEditorEnter event.

    Here is video of example running in desktop browser:
    Click image for larger version

Name:	rowEditorEnterOnDesktop.gif
Views:	211
Size:	372.9 KB
ID:	263061

    Now, if you switch to browser's responsive mode and run the same example again, you will not get a notification - rowEditorEvent is not triggered this time:
    Click image for larger version

Name:	rowEditorEnterOnMobile.gif
Views:	94
Size:	200.8 KB
ID:	263062
    There are no warnings or errors on the developers console.


    Example code is:

    Code:
    package pl.com.tech4.client;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.data.DataSourceField;
    import com.smartgwt.client.data.OperationBinding;
    import com.smartgwt.client.data.fields.DataSourceTextField;
    import com.smartgwt.client.types.AutoFitWidthApproach;
    import com.smartgwt.client.types.DSDataFormat;
    import com.smartgwt.client.types.DSOperationType;
    import com.smartgwt.client.types.DSProtocol;
    import com.smartgwt.client.util.SC;
    import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
    import com.smartgwt.client.widgets.grid.ListGrid;
    import com.smartgwt.client.widgets.grid.ListGridField;
    import com.smartgwt.client.widgets.grid.events.RowEditorEnterEvent;
    import com.smartgwt.client.widgets.grid.events.RowEditorEnterHandler;
    import com.smartgwt.client.widgets.grid.events.RowEditorExitEvent;
    import com.smartgwt.client.widgets.grid.events.RowEditorExitHandler;
    
    public class MainEntryPoint implements EntryPoint {
    
        public void onModuleLoad() {
    
            layout();
    //        SC.showConsole();
        }
    
        private void layout() {
    
            DataSource departmentDS = new DataSource();
            departmentDS.setID("Department");
            departmentDS.setClientOnly(true);
            OperationBinding fetchBinding = new OperationBinding();
            fetchBinding.setOperationType(DSOperationType.FETCH);
            fetchBinding.setDataFormat(DSDataFormat.XML);
            fetchBinding.setDataProtocol(DSProtocol.POSTXML);
            departmentDS.setOperationBindings(fetchBinding);
            departmentDS.setDataURL("Department.xml");
    
            DataSource personDS = new DataSource();
            personDS.setID("Person");
            personDS.setClientOnly(true);
            personDS.setOperationBindings(fetchBinding);
            personDS.setDataURL("Person.xml");
    
            DataSourceField idField = new DataSourceField();
            idField.setName("id");
            idField.setPrimaryKey(true);
            idField.setHidden(true);
            DataSourceTextField codeField = new DataSourceTextField();
            codeField.setName("code");
            DataSourceTextField descriptionField = new DataSourceTextField();
            descriptionField.setName("description");
            personDS.setFields(idField, codeField, descriptionField);
    
            DataSourceField idDepField = new DataSourceField();
            idDepField.setName("id");
            idDepField.setPrimaryKey(true);
            idDepField.setHidden(true);
            DataSourceField personField = new DataSourceField();
            DataSourceField person_idField = new DataSourceField();
            DataSourceTextField person_codeField = new DataSourceTextField();
            DataSourceTextField person_descriptionField = new DataSourceTextField();
            personField = new DataSourceField();
            personField.setName("person");
            personField.setForeignKey("Person.id");
            personField.setValueXPath("person/id");
            ComboBoxItem personItem = new ComboBoxItem("person");
            personItem.setOptionDataSource(personDS);
            personItem.setValueField("id");
            personItem.setDisplayField("code");
            personItem.setPickListFields(new ListGridField("id"), new ListGridField("code"));
            personField.setEditorProperties(personItem);
            personField.setFilterEditorProperties(personItem);
            departmentDS.addField(personField);
            person_idField = new DataSourceField();
            person_idField.setName("person" + "_id");
            person_idField.setPrimaryKey(true);
            person_idField.setValueXPath("person/id");
            departmentDS.addField(person_idField);
            person_codeField = new DataSourceTextField();
            person_codeField.setName("person" + "_code");
            person_codeField.setValueXPath("person/code");
            departmentDS.addField(person_codeField);
            person_descriptionField = new DataSourceTextField();
            person_descriptionField.setName("person" + "_description");
            person_descriptionField.setValueXPath("person/description");
            departmentDS.addField(person_descriptionField);
    
            ListGrid lg = new ListGrid();
            lg.setDataSource(departmentDS);
            lg.setShowFilterEditor(true);
            lg.setAllowFilterOperators(true);
            lg.setCanEdit(true);
            lg.setAutoSaveEdits(false);
            lg.setWidth100();
            lg.setHeight100();
            lg.setAutoFitFieldWidths(true);
            lg.setAutoFitWidthApproach(AutoFitWidthApproach.BOTH);
            lg.setAutoFitExpandField("description");
            lg.setConfirmDiscardEdits(false);
            lg.setStopOnErrors(true);
            lg.setModalEditing(false);
            lg.addRowEditorEnterHandler(new RowEditorEnterHandler() {
                @Override
                public void onRowEditorEnter(RowEditorEnterEvent event) {
                    SC.notify("RowEditorEnter");
                }
            });
            lg.addRowEditorExitHandler(new RowEditorExitHandler() {
                @Override
                public void onRowEditorExit(RowEditorExitEvent event) {
                    SC.notify("RowEditorExit");
                }
            });
            lg.draw();
            lg.fetchData();
        }
    
    }
    Latest SmartClient Version: v12.1p_2020-07-10/LGPL Development Only (built 2020-07-10)
    Browser: Chromium 80.0.3987.162 (Build) (64-bit)

    Thanks,
    MichalG


    #2
    We've tested your sample code, but we couldn't reproduce the issue. Tested on Google Chrome 83 and Chromium 83 and 86.

    Also, we've used a local clientOnly DataSource to populate the ListGrid, since the Department.xml and Person.xml files were not posted and the issue seems to be related to addRowEditorEnterHandler and addRowEditorExitHandler.

    Also, please test on the latest version of Chromium, and if you still see the issue, please provide the missing files and indicate what OS you are testing in.

    Regards
    Isomorphic Software

    Comment


      #3
      Sorry for missing data xml files.

      I simplified test case by using lg.rowDoubleClick() to simulate user interaction, so you just run it in browser's responsive mode and can see that even although grid is in edit mode and person comboBox value is selected, there is no editorEnter event notification.
      Click image for larger version

Name:	noRowEditorEnter.gif
Views:	205
Size:	53.4 KB
ID:	263077

      The same example works (shows notification) in browser desktop mode.

      About browser and version: I did check (the same result) the following example in Windows 7 Pro with Chrome 83.0.4103.116 (64-bit) and also with up-to-date Firefox (both in responsive mode!). Also tried on some Android devices using Chrome as browser - same thing. Previously tested with Chromium 80.0.3987.162 on Gentoo Linux 5.4.28.

      Code:
      package pl.com.tech4.client;
      
      import com.google.gwt.core.client.EntryPoint;
      import com.smartgwt.client.data.DSCallback;
      import com.smartgwt.client.data.DSRequest;
      import com.smartgwt.client.data.DSResponse;
      import com.smartgwt.client.data.DataSource;
      import com.smartgwt.client.data.DataSourceField;
      import com.smartgwt.client.data.OperationBinding;
      import com.smartgwt.client.data.fields.DataSourceTextField;
      import com.smartgwt.client.types.DSDataFormat;
      import com.smartgwt.client.types.DSOperationType;
      import com.smartgwt.client.types.DSProtocol;
      import com.smartgwt.client.util.SC;
      import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
      import com.smartgwt.client.widgets.grid.ListGrid;
      import com.smartgwt.client.widgets.grid.ListGridField;
      import com.smartgwt.client.widgets.grid.events.RowEditorEnterEvent;
      import com.smartgwt.client.widgets.grid.events.RowEditorEnterHandler;
      import com.smartgwt.client.widgets.grid.events.RowEditorExitEvent;
      import com.smartgwt.client.widgets.grid.events.RowEditorExitHandler;
      
      public class MainEntryPoint implements EntryPoint {
      
          public void onModuleLoad() {
      
              layout();
      //        SC.showConsole();
          }
      
          private void layout() {
      
              DataSource departmentDS = new DataSource();
              departmentDS.setID("Department");
              departmentDS.setClientOnly(true);
              OperationBinding fetchBinding = new OperationBinding();
              fetchBinding.setOperationType(DSOperationType.FETCH);
              fetchBinding.setDataFormat(DSDataFormat.XML);
              fetchBinding.setDataProtocol(DSProtocol.POSTXML);
              departmentDS.setOperationBindings(fetchBinding);
              departmentDS.setDataURL("Department.xml");
      
              DataSource personDS = new DataSource();
              personDS.setID("Person");
              personDS.setClientOnly(true);
              personDS.setOperationBindings(fetchBinding);
              personDS.setDataURL("Person.xml");
      
              DataSourceField idField = new DataSourceField();
              idField.setName("id");
              idField.setPrimaryKey(true);
              idField.setHidden(true);
              DataSourceTextField codeField = new DataSourceTextField();
              codeField.setName("code");
              DataSourceTextField descriptionField = new DataSourceTextField();
              descriptionField.setName("description");
              personDS.setFields(idField, codeField, descriptionField);
      
              DataSourceField idDepField = new DataSourceField();
              idDepField.setName("id");
              idDepField.setPrimaryKey(true);
              idDepField.setHidden(true);
              DataSourceField personField = new DataSourceField();
              personField = new DataSourceField();
              personField.setName("person");
              personField.setForeignKey("Person.id");
              personField.setValueXPath("person/id");
              ComboBoxItem personItem = new ComboBoxItem("person");
              personItem.setOptionDataSource(personDS);
              personItem.setValueField("id");
              personItem.setDisplayField("code");
              personItem.setPickListFields(new ListGridField("id"), new ListGridField("code"));
              personField.setEditorProperties(personItem);
              personField.setFilterEditorProperties(personItem);
              departmentDS.addField(personField);
      
              final ListGrid lg = new ListGrid();
              lg.setDataSource(departmentDS);
              lg.setCanEdit(true);
              lg.setWidth100();
              lg.setHeight100();
              lg.addRowEditorEnterHandler(new RowEditorEnterHandler() {
                  @Override
                  public void onRowEditorEnter(RowEditorEnterEvent event) {
                      SC.notify("RowEditorEnter");
                  }
              });
              lg.addRowEditorExitHandler(new RowEditorExitHandler() {
                  @Override
                  public void onRowEditorExit(RowEditorExitEvent event) {
                      SC.notify("RowEditorExit");
                  }
              });
      
              lg.draw();
              lg.fetchData(null, new DSCallback() {
                  @Override
                  public void execute(DSResponse dsResponse, Object data, DSRequest dsRequest) {
                      lg.selectRecord(0);
                      lg.rowDoubleClick(lg.getSelectedRecord(), 0, 0);
                  }
              });
          }
      }
      Person.xml
      Code:
      <response>
          <status>STATUS_SUCCESS</status>
          <startRow>0</startRow>
          <endRow>0</endRow>
          <totalRows>1</totalRows>
          <data>
              <Person>
                  <id>11</id>
                  <code>Larry</code>
                  <description>The boss</description>
              </Person>
          </data>
      </response>
      Department.xml
      Code:
      <response>
          <status>STATUS_SUCCESS</status>
          <startRow>0</startRow>
          <endRow>0</endRow>
          <totalRows>1</totalRows>
          <data>
              <Department>
                  <id>1</id>
                  <code>Oracle</code>
                  <description>Database production</description>
                  <person>
                      <id>11</id>
                      <code>Larry</code>
                      <description>The boss</description>
                  </person>
              </Department>
          </data>
      </response>
      Thanks,
      MichalG

      Comment


        #4
        Hi,
        Is it reproducible now? Should I provide any more info?
        Thanks,
        MichalG

        Comment


          #5
          We’re seeing it reproduce for some developers but not others, which unfortunately means it’s probably a weird browser bug that could take time to untangle.

          For now, we’d suggest changing your code to use other handlers, such as editorEnter installed via editorProperties.

          Comment


            #6
            Thank you for information.
            As far as your suggestion to use editorEnter of editorProperties I have modified test case:
            Code:
            package pl.com.tech4.client;
            
            import com.google.gwt.core.client.EntryPoint;
            import com.smartgwt.client.data.DSCallback;
            import com.smartgwt.client.data.DSRequest;
            import com.smartgwt.client.data.DSResponse;
            import com.smartgwt.client.data.DataSource;
            import com.smartgwt.client.data.DataSourceField;
            import com.smartgwt.client.data.OperationBinding;
            import com.smartgwt.client.data.fields.DataSourceTextField;
            import com.smartgwt.client.types.DSDataFormat;
            import com.smartgwt.client.types.DSOperationType;
            import com.smartgwt.client.types.DSProtocol;
            import com.smartgwt.client.util.SC;
            import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
            import com.smartgwt.client.widgets.grid.ListGrid;
            import com.smartgwt.client.widgets.grid.ListGridField;
            import com.smartgwt.client.widgets.grid.events.RowEditorEnterEvent;
            import com.smartgwt.client.widgets.grid.events.RowEditorEnterHandler;
            import com.smartgwt.client.widgets.grid.events.RowEditorExitEvent;
            import com.smartgwt.client.widgets.grid.events.RowEditorExitHandler;
            
            public class MainEntryPoint implements EntryPoint {
            
                public void onModuleLoad() {
            
                    layout();
            //        SC.showConsole();
                }
            
                private void layout() {
            
                    DataSource departmentDS = new DataSource();
                    departmentDS.setID("Department");
                    departmentDS.setClientOnly(true);
                    OperationBinding fetchBinding = new OperationBinding();
                    fetchBinding.setOperationType(DSOperationType.FETCH);
                    fetchBinding.setDataFormat(DSDataFormat.XML);
                    fetchBinding.setDataProtocol(DSProtocol.POSTXML);
                    departmentDS.setOperationBindings(fetchBinding);
                    departmentDS.setDataURL("Department.xml");
            
                    DataSource personDS = new DataSource();
                    personDS.setID("Person");
                    personDS.setClientOnly(true);
                    personDS.setOperationBindings(fetchBinding);
                    personDS.setDataURL("Person.xml");
            
                    DataSourceField idField = new DataSourceField();
                    idField.setName("id");
                    idField.setPrimaryKey(true);
                    idField.setHidden(true);
                    DataSourceTextField codeField = new DataSourceTextField();
                    codeField.setName("code");
                    DataSourceTextField descriptionField = new DataSourceTextField();
                    descriptionField.setName("description");
                    personDS.setFields(idField, codeField, descriptionField);
            
                    DataSourceField idDepField = new DataSourceField();
                    idDepField.setName("id");
                    idDepField.setPrimaryKey(true);
                    idDepField.setHidden(true);
                    DataSourceField personField = new DataSourceField();
                    personField = new DataSourceField();
                    personField.setName("person");
                    personField.setForeignKey("Person.id");
                    personField.setValueXPath("person/id");
                    ComboBoxItem personItem = new ComboBoxItem("person");
                    personItem.setOptionDataSource(personDS);
                    personItem.setValueField("id");
                    personItem.setDisplayField("code");
                    personItem.setPickListFields(new ListGridField("id"), new ListGridField("code"));
            [B]        personItem.addEditorEnterHandler(new com.smartgwt.client.widgets.form.fields.events.EditorEnterHandler() {
                        @Override
                        public void onEditorEnter(com.smartgwt.client.widgets.form.fields.events.EditorEnterEvent event) {
                            SC.notify("EditorEnter");
                        }
                    });[/B]
                    personField.setEditorProperties(personItem);
                    personField.setFilterEditorProperties(personItem);
                    departmentDS.addField(personField);
            
                    final ListGrid lg = new ListGrid();
                    lg.setDataSource(departmentDS);
                    lg.setCanEdit(true);
                    lg.setWidth100();
                    lg.setHeight100();
                    lg.addRowEditorEnterHandler(new RowEditorEnterHandler() {
                        @Override
                        public void onRowEditorEnter(RowEditorEnterEvent event) {
                            SC.notify("RowEditorEnter");
                        }
                    });
                    lg.addRowEditorExitHandler(new RowEditorExitHandler() {
                        @Override
                        public void onRowEditorExit(RowEditorExitEvent event) {
                            SC.notify("RowEditorExit");
                        }
                    });
            
                    lg.draw();
                    lg.fetchData(null, new DSCallback() {
                        @Override
                        public void execute(DSResponse dsResponse, Object data, DSRequest dsRequest) {
                            lg.selectRecord(0);
                            lg.rowDoubleClick(lg.getSelectedRecord(), 0, 0);
                        }
                    });
                }
            }
            but no luck. Again, additional notification shows in desktop mode, but not in responsive mode.
            MichalG

            Comment

            Working...
            X