Announcement

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

    ListGrid-editRow field.canEdit(true/false) during editing not visualised

    Hi Isomorphic,

    please see this BuiltInDS based testcase (v10.1p_2016-03-02).

    BuiltInDS.java:
    Code:
    package com.smartgwt.sample.client;
    
    import java.util.LinkedHashMap;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.smartgwt.client.core.KeyIdentifier;
    import com.smartgwt.client.data.AdvancedCriteria;
    import com.smartgwt.client.data.Criterion;
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.data.SortSpecifier;
    import com.smartgwt.client.types.OperatorId;
    import com.smartgwt.client.types.SortDirection;
    import com.smartgwt.client.util.Page;
    import com.smartgwt.client.util.PageKeyHandler;
    import com.smartgwt.client.util.SC;
    import com.smartgwt.client.widgets.IButton;
    import com.smartgwt.client.widgets.Window;
    import com.smartgwt.client.widgets.events.ClickEvent;
    import com.smartgwt.client.widgets.events.ClickHandler;
    import com.smartgwt.client.widgets.form.fields.SelectItem;
    import com.smartgwt.client.widgets.grid.ListGrid;
    import com.smartgwt.client.widgets.grid.ListGridField;
    import com.smartgwt.client.widgets.grid.events.ChangedEvent;
    import com.smartgwt.client.widgets.grid.events.ChangedHandler;
    import com.smartgwt.client.widgets.grid.events.RowEditorEnterEvent;
    import com.smartgwt.client.widgets.grid.events.RowEditorEnterHandler;
    import com.smartgwt.client.widgets.layout.VLayout;
    
    public class BuiltInDS implements EntryPoint {
        private VLayout mainLayout;
        private IButton recreateBtn;
    
        public void onModuleLoad() {
            KeyIdentifier debugKey = new KeyIdentifier();
            debugKey.setCtrlKey(true);
            debugKey.setKeyName("D");
    
            Page.registerKey(debugKey, new PageKeyHandler() {
                public void execute(String keyName) {
                    SC.showConsole();
                }
            });
    
            mainLayout = new VLayout(20);
            mainLayout.setWidth100();
            mainLayout.setHeight100();
    
            recreateBtn = new IButton("Recreate");
            recreateBtn.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    recreate();
                }
            });
            mainLayout.addMember(recreateBtn);
            recreate();
            mainLayout.draw();
        }
    
        private void recreate() {
            Window w = new Window();
            w.setWidth("95%");
            w.setHeight("95%");
            w.setMembersMargin(0);
            w.setModalMaskOpacity(70);
            w.setTitle("ListGrid-editRow FormItems with canEdit(true/false) depending on another FormItem-Change not updated on change.");
            w.setShowMinimizeButton(false);
            w.setIsModal(true);
            w.setShowModalMask(true);
            w.centerInPage();
    
            final ListGrid animalsGrid = new ListGrid();
            animalsGrid.setHeight100();
            animalsGrid.setAutoFetchData(false);
            animalsGrid.setCanEdit(true);
            animalsGrid.setDataSource(DataSource.get("animals"));
    
            ListGridField commonName = new ListGridField("commonName");
            ListGridField scientificName = new ListGridField("scientificName");
            LifeSpanLGF lifeSpan = new LifeSpanLGF("lifeSpan", animalsGrid);
            ListGridField status = new ListGridField("status");
            ListGridField diet = new ListGridField("diet");
    
            status.addChangedHandler(new ChangedHandler() {
                @Override
                public void onChanged(ChangedEvent event) {
    
                }
            });
    
            animalsGrid.addRowEditorEnterHandler(new RowEditorEnterHandler() {
                @Override
                public void onRowEditorEnter(RowEditorEnterEvent event) {
                    SC.logWarn("RowEditorEnterEvent");
                    Integer lifeSpan = event.getRecord().getAttributeAsInt("lifeSpan");
                    if (lifeSpan > 0 && lifeSpan <= 20) {
                        animalsGrid.getField("status").setCanEdit(true);
                        animalsGrid.getField("diet").setCanEdit(true);
                    }
                    if (lifeSpan > 20 && lifeSpan <= 50) {
                        animalsGrid.getField("status").setCanEdit(true);
                        animalsGrid.getField("diet").setCanEdit(false);
                        animalsGrid.setEditValue(event.getRowNum(), "diet", (String) null);
                    }
                    if (lifeSpan > 50 && lifeSpan <= 100) {
                        animalsGrid.getField("status").setCanEdit(false);
                        animalsGrid.setEditValue(event.getRowNum(), "status", (String) null);
                        animalsGrid.getField("diet").setCanEdit(true);
                    }
                    if (lifeSpan > 100) {
                        animalsGrid.getField("status").setCanEdit(false);
                        animalsGrid.setEditValue(event.getRowNum(), "status", (String) null);
                        animalsGrid.getField("diet").setCanEdit(false);
                        animalsGrid.setEditValue(event.getRowNum(), "diet", (String) null);
                    }
                }
            });
    
            animalsGrid.setFields(commonName, scientificName, lifeSpan, status, diet);
    
            animalsGrid.setSort(new SortSpecifier[] { new SortSpecifier(commonName.getName(), SortDirection.ASCENDING) });
            animalsGrid.fetchData(new AdvancedCriteria(new Criterion("commonName", OperatorId.LESS_OR_EQUAL, "D")));
            w.addItem(animalsGrid);
    
            IButton reloadBtn = new IButton("Reload data");
            reloadBtn.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    animalsGrid.invalidateCache();
                }
            });
            w.addItem(reloadBtn);
            w.show();
        }
    
        private class LifeSpanLGF extends ListGridField {
            public LifeSpanLGF(String name, final ListGrid parentListGrid) {
                super(name);
                LinkedHashMap<Integer, String> valueMap = new LinkedHashMap<Integer, String>();
                valueMap.put(1, "1 (edit both)");
                valueMap.put(5, "5 (edit both)");
                valueMap.put(10, "10 (edit both)");
                valueMap.put(20, "20 (edit both)");
                valueMap.put(50, "50 (edit status)");
                valueMap.put(100, "100 (edit diet)");
                valueMap.put(150, "150 (edit none)");
    
                SelectItem si = new SelectItem();
                si.setValueMap(valueMap);
                si.addChangedHandler(new com.smartgwt.client.widgets.form.fields.events.ChangedHandler() {
                    @Override
                    public void onChanged(com.smartgwt.client.widgets.form.fields.events.ChangedEvent event) {
                        SC.logWarn("SelectItem ChangedEvent");
                        Integer lifeSpan = (Integer) event.getValue();
                        if (lifeSpan > 0 && lifeSpan <= 20) {
                            parentListGrid.getField("status").setCanEdit(true);
                            parentListGrid.getField("diet").setCanEdit(true);
                        }
                        if (lifeSpan > 20 && lifeSpan <= 50) {
                            parentListGrid.getField("status").setCanEdit(true);
                            parentListGrid.getField("diet").setCanEdit(false);
                            parentListGrid.setEditValue(parentListGrid.getEditRow(), "diet", (String) null);
                        }
                        if (lifeSpan > 50 && lifeSpan <= 100) {
                            parentListGrid.getField("status").setCanEdit(false);
                            parentListGrid.setEditValue(parentListGrid.getEditRow(), "status", (String) null);
                            parentListGrid.getField("diet").setCanEdit(true);
                        }
                        if (lifeSpan > 100) {
                            parentListGrid.getField("status").setCanEdit(false);
                            parentListGrid.setEditValue(parentListGrid.getEditRow(), "status", (String) null);
                            parentListGrid.getField("diet").setCanEdit(false);
                            parentListGrid.setEditValue(parentListGrid.getEditRow(), "diet", (String) null);
                        }
                    }
                });
                LifeSpanLGF.this.setEditorProperties(si);
                LifeSpanLGF.this.setValueMap(valueMap);
            }
        }
    }[B][/B]


    Please then change the lifespan of all shown animals to a value from the SelectItem.
    If you do so like this
    Click image for larger version

Name:	1.PNG
Views:	407
Size:	9.0 KB
ID:	235459
    you'll see that if you start to edit rows, the desired effect (both, only status, only diet or none editable) is only there on the 2nd start of the row editor. The first start is always like the row edited before the current row.
    So if you e.g. keep moving from "only status" to "only diet" rows back and forth (without doing any changes), always the wrong column is editable.

    Additionally the ChangedHandler on the SelectItem does fire, but the effect of the change is not visible.

    From the visual effect this is what I was seeing here, although I don't know if it is related.

    Best regards
    Blama

    #2
    getField().setCanEdit() is an invalid call - you can't modify field objects after providing them to the ListGrid.

    Aside from this being invalid, it doesn't make basic sense to be toggling field editability at arbitrary times. For example, if the field is no longer editable, what should the grid be expected to do with existing edits? Especially since you are trying to switch editability while the row is still being edited?

    The correct way to implement this kind of scenario is an override of canEditCell(). This API is called by the ListGrid at appropriate times, such as right before navigating to a new cell.

    In general, to change field properties after the fields have been provided to the ListGrid, use setFieldProperties() - but again, for canEdit, an override of canEditCell() is what you should use.

    Comment


      #3
      Hi Isomorphic,

      thanks for the answer.

      Originally posted by Isomorphic View Post
      "You can't modify field objects after providing them to the ListGrid"
      and "In general, to change field properties after the fields have been provided to the ListGrid, use setFieldProperties()"
      are good to know.

      I revised my testcase (now using a ChangedHandler for setEditValue() and a canEditCell()-override for editability).
      Please note that in cases where a editability returned from canEditCell() changes from true to false, this works as expected.
      If it changes from false to true, the display is only updated after tabbing to the next field. Obviously it should be reflected directly as well.
      I could solve it with a ListGrid.redraw() in the ChangedHandler, but this seems wrong to me.

      Revised BuiltInDS.java:
      Code:
      package com.smartgwt.sample.client;
      
      import java.util.LinkedHashMap;
      
      import com.google.gwt.core.client.EntryPoint;
      import com.smartgwt.client.core.KeyIdentifier;
      import com.smartgwt.client.data.AdvancedCriteria;
      import com.smartgwt.client.data.Criterion;
      import com.smartgwt.client.data.DataSource;
      import com.smartgwt.client.data.SortSpecifier;
      import com.smartgwt.client.types.OperatorId;
      import com.smartgwt.client.types.SortDirection;
      import com.smartgwt.client.util.Page;
      import com.smartgwt.client.util.PageKeyHandler;
      import com.smartgwt.client.util.SC;
      import com.smartgwt.client.widgets.IButton;
      import com.smartgwt.client.widgets.Window;
      import com.smartgwt.client.widgets.events.ClickEvent;
      import com.smartgwt.client.widgets.events.ClickHandler;
      import com.smartgwt.client.widgets.form.fields.SelectItem;
      import com.smartgwt.client.widgets.grid.ListGrid;
      import com.smartgwt.client.widgets.grid.ListGridField;
      import com.smartgwt.client.widgets.grid.events.ChangedEvent;
      import com.smartgwt.client.widgets.grid.events.ChangedHandler;
      import com.smartgwt.client.widgets.layout.VLayout;
      
      public class BuiltInDS implements EntryPoint {
          private VLayout mainLayout;
          private IButton recreateBtn;
      
          public void onModuleLoad() {
              KeyIdentifier debugKey = new KeyIdentifier();
              debugKey.setCtrlKey(true);
              debugKey.setKeyName("D");
      
              Page.registerKey(debugKey, new PageKeyHandler() {
                  public void execute(String keyName) {
                      SC.showConsole();
                  }
              });
      
              mainLayout = new VLayout(20);
              mainLayout.setWidth100();
              mainLayout.setHeight100();
      
              recreateBtn = new IButton("Recreate");
              recreateBtn.addClickHandler(new ClickHandler() {
                  @Override
                  public void onClick(ClickEvent event) {
                      recreate();
                  }
              });
              mainLayout.addMember(recreateBtn);
              recreate();
              mainLayout.draw();
          }
      
          private void recreate() {
              Window w = new Window();
              w.setWidth("95%");
              w.setHeight("95%");
              w.setMembersMargin(0);
              w.setModalMaskOpacity(70);
              w.setTitle("ListGrid-editRow FormItems with canEdit(true/false) depending on another FormItem-Change not updated on change.");
              w.setShowMinimizeButton(false);
              w.setIsModal(true);
              w.setShowModalMask(true);
              w.centerInPage();
      
              final ListGrid animalsGrid = new ListGrid() {
                  public boolean canEditCell(int rowNum, int colNum) {
                      int statusColNum = this.getFieldNum("status");
                      int dietColNum = this.getFieldNum("diet");
                      if (colNum != statusColNum && colNum != dietColNum)
                          return super.canEditCell(rowNum, colNum);
      
                      Integer lifeSpan = this.getEditedRecord(rowNum).getAttributeAsInt("lifeSpan");
                      if (lifeSpan == null)
                          lifeSpan = 0;
      
                      if (lifeSpan <= 20) {
                          if (colNum == statusColNum)
                              return true;
                          if (colNum == dietColNum)
                              return true;
                      } else if (lifeSpan > 20 && lifeSpan <= 50) {
                          if (colNum == statusColNum)
                              return true;
                          if (colNum == dietColNum)
                              return false;
                      } else if (lifeSpan > 50 && lifeSpan <= 100) {
                          if (colNum == statusColNum)
                              return false;
                          if (colNum == dietColNum)
                              return true;
                      } else if (lifeSpan > 100) {
                          if (colNum == statusColNum)
                              return false;
                          if (colNum == dietColNum)
                              return false;
                      }
                      SC.warn("Hit default return in canEditCell override. Should not happen.");
                      return super.canEditCell(rowNum, colNum);
                  };
              };
              animalsGrid.setHeight100();
              animalsGrid.setAutoFetchData(false);
              animalsGrid.setCanEdit(true);
              animalsGrid.setDataSource(DataSource.get("animals"));
      
              ListGridField commonName = new ListGridField("commonName");
              ListGridField scientificName = new ListGridField("scientificName");
              LifeSpanLGF lifeSpan = new LifeSpanLGF("lifeSpan", animalsGrid);
              ListGridField status = new ListGridField("status");
              ListGridField diet = new ListGridField("diet");
      
              status.addChangedHandler(new ChangedHandler() {
                  @Override
                  public void onChanged(ChangedEvent event) {
      
                  }
              });
      
              animalsGrid.setFields(commonName, scientificName, lifeSpan, status, diet);
      
              animalsGrid.setSort(new SortSpecifier[] { new SortSpecifier(commonName.getName(), SortDirection.ASCENDING) });
              animalsGrid.fetchData(new AdvancedCriteria(new Criterion("commonName", OperatorId.LESS_OR_EQUAL, "D")));
              w.addItem(animalsGrid);
      
              IButton reloadBtn = new IButton("Reload data");
              reloadBtn.addClickHandler(new ClickHandler() {
                  @Override
                  public void onClick(ClickEvent event) {
                      animalsGrid.invalidateCache();
                  }
              });
              w.addItem(reloadBtn);
              w.show();
          }
      
          private class LifeSpanLGF extends ListGridField {
              public LifeSpanLGF(String name, final ListGrid parentListGrid) {
                  super(name);
                  LinkedHashMap<Integer, String> valueMap = new LinkedHashMap<Integer, String>();
                  valueMap.put(1, "1 (edit both)");
                  valueMap.put(5, "5 (edit both)");
                  valueMap.put(10, "10 (edit both)");
                  valueMap.put(20, "20 (edit both)");
                  valueMap.put(50, "50 (edit status)");
                  valueMap.put(100, "100 (edit diet)");
                  valueMap.put(150, "150 (edit none)");
      
                  SelectItem si = new SelectItem();
                  si.setValueMap(valueMap);
                  si.addChangedHandler(new com.smartgwt.client.widgets.form.fields.events.ChangedHandler() {
                      @Override
                      public void onChanged(com.smartgwt.client.widgets.form.fields.events.ChangedEvent event) {
                          SC.logWarn("SelectItem ChangedEvent");
                          Integer lifeSpan = (Integer) event.getValue();
                          if (lifeSpan <= 20) {
                          } else if (lifeSpan > 20 && lifeSpan <= 50) {
                              parentListGrid.setEditValue(parentListGrid.getEditRow(), "diet", (String) null);
                          } else if (lifeSpan > 50 && lifeSpan <= 100) {
                              parentListGrid.setEditValue(parentListGrid.getEditRow(), "status", (String) null);
                          } else if (lifeSpan > 100) {
                              parentListGrid.setEditValue(parentListGrid.getEditRow(), "status", (String) null);
                              parentListGrid.setEditValue(parentListGrid.getEditRow(), "diet", (String) null);
                          }
                          // Is this really needed?
                          // parentListGrid.redraw("Show changed field-editability.");
                      }
                  });
                  LifeSpanLGF.this.setEditorProperties(si);
                  LifeSpanLGF.this.setValueMap(valueMap);
              }
          }
      }[B][/B]


      A nice low priority enhancement would be a canEdit-determination based on Criteria, like you already do with getCellCSSText() and Hilites.

      Best regards
      Blama

      Comment


        #4
        Please note that in cases where a editability returned from canEditCell() changes from true to false, this works as expected.
        If it changes from false to true, the display is only updated after tabbing to the next field. Obviously it should be reflected directly as well.
        ...
        A nice low priority enhancement would be a canEdit-determination based on Criteria
        If there were an API for declaring editability based on criteria, we could potentially instantly switch the cell to editable *if* we further assume that we have perfect knowledge of any changes for the data that the criteria is applied to.

        With an override point like canEditCell(), obviously we have no way of knowing whether the result will potentially change at any given time. We can't reasonably call it several times a second just in case.

        Having the cell switch to editable state on blur is generally exactly what you'd want; if you needed it to happen faster for some reason, you can use just refreshCell(), no need for a full redraw().

        Comment


          #5
          Hi Isomorphic,

          thank you, with
          Code:
          parentListGrid.refreshCell(parentListGrid.getEditRow(), parentListGrid.getFieldNum("status"));
          parentListGrid.refreshCell(parentListGrid.getEditRow(), parentListGrid.getFieldNum("diet"));
          in the ChangedHandler it is working now.

          I of course didn't mean "call it several times a second just in case". but a change to the editValues is an event you could react to.

          Also note that for the switch canEdit:true to canEdit:false, it is already working without blur, but not vice versa.

          Best regards
          Blama

          Comment


            #6
            We don't plan to make a change to call canEditCell more frequently, because we might end up with the editor flipping back and forth between editable and uneditable state on a per-keystroke basis while the user was typing, causing poor usability and poor interactivity. The current behavior is the right default, and refreshCell() can be used to show an editor earlier if a given application has special needs.

            Comment


              #7
              Hi Isomorphic,

              OK thank you. No problem for me, as it is working as expected with refreshCell().

              Best regards
              Blama

              Comment


                #8
                Hi Isomorphic,

                I have another question in this area: If I'm not allowed to change a ListGridField instance after setFields(), how can I define a field as required for this row?
                There is no isRequired() I could override like canEditCell().

                I could think of these possible solutions:
                • RequiredIfValidator (but how do I get the row data for the RequiredIfFunction?)
                • ListGrid.setFieldProperties()
                • Server side validator
                What is the best way to solve this (the forums search did not help, I only found this very old thread)?

                Thank you & Best regards
                Blama

                Comment


                  #9
                  You can use a RequiredIfValidator and use a closure to be able to get access to the grid (a 'final' ListGrid can be accessed inside the RequiredIfFunction).

                  If it gets more complicated in some way and you need a custom behavior, use CustomValidator.

                  Comment


                    #10
                    Hi Isomorphic,

                    thank you for the recommendations. I wanted to go with RequiredIfValidator, but switched to CustomValidator, as it got more complicated.

                    I found three other issues in this area. Please see this testcase:
                    employees.ds.xml:
                    Code:
                    DataSource-addition: [B]useAnsiJoins="true"[/B]
                    Field changes:
                    [B]        <field name="ReportsTo"       title="Manager"         type="integer"  
                                   foreignKey="employees.EmployeeId" joinType="outer" displayField="ManagerName" rootValue="1" />
                            <field name="ManagerName" includeFrom="employees.Name" />[/B]
                    BuiltInDS.java:
                    Code:
                    package com.smartgwt.sample.client;
                    
                    import com.google.gwt.core.client.EntryPoint;
                    import com.smartgwt.client.core.KeyIdentifier;
                    import com.smartgwt.client.data.AdvancedCriteria;
                    import com.smartgwt.client.data.Criterion;
                    import com.smartgwt.client.data.DataSource;
                    import com.smartgwt.client.data.SortSpecifier;
                    import com.smartgwt.client.types.OperatorId;
                    import com.smartgwt.client.types.SortDirection;
                    import com.smartgwt.client.util.Page;
                    import com.smartgwt.client.util.PageKeyHandler;
                    import com.smartgwt.client.util.SC;
                    import com.smartgwt.client.widgets.IButton;
                    import com.smartgwt.client.widgets.Window;
                    import com.smartgwt.client.widgets.events.ClickEvent;
                    import com.smartgwt.client.widgets.events.ClickHandler;
                    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.ChangedEvent;
                    import com.smartgwt.client.widgets.grid.events.ChangedHandler;
                    import com.smartgwt.client.widgets.layout.VLayout;
                    
                    public class BuiltInDS implements EntryPoint {
                        private VLayout mainLayout;
                        private IButton recreateBtn;
                    
                        public void onModuleLoad() {
                            KeyIdentifier debugKey = new KeyIdentifier();
                            debugKey.setCtrlKey(true);
                            debugKey.setKeyName("D");
                    
                            Page.registerKey(debugKey, new PageKeyHandler() {
                                public void execute(String keyName) {
                                    SC.showConsole();
                                }
                            });
                    
                            mainLayout = new VLayout(20);
                            mainLayout.setWidth100();
                            mainLayout.setHeight100();
                    
                            recreateBtn = new IButton("Recreate");
                            recreateBtn.addClickHandler(new ClickHandler() {
                                @Override
                                public void onClick(ClickEvent event) {
                                    recreate();
                                }
                            });
                            mainLayout.addMember(recreateBtn);
                            recreate();
                            mainLayout.draw();
                        }
                    
                        private void recreate() {
                            Window w = new Window();
                            w.setWidth("95%");
                            w.setHeight("95%");
                            w.setMembersMargin(0);
                            w.setModalMaskOpacity(70);
                            w.setTitle("ListGrid-editRow FormItems get not cleared on setEditValue(null) if base item is a SelectItem or ComboBoxItem");
                            w.setShowMinimizeButton(false);
                            w.setIsModal(true);
                            w.setShowModalMask(true);
                            w.centerInPage();
                    
                            final ListGrid employeesGrid = new ListGrid() {
                                @Override
                                public boolean canEditCell(int rowNum, int colNum) {
                                    int reportsToColNum = this.getFieldNum("ReportsTo");
                                    int jobColNum = this.getFieldNum("Job");
                                    if (colNum != reportsToColNum && colNum != jobColNum)
                                        return super.canEditCell(rowNum, colNum);
                    
                                    String gender = this.getEditedRecord(rowNum).getAttribute("Gender");
                                    if (gender == null)
                                        gender = "female";
                    
                                    if ("female".equals(gender)) {
                                        return true;
                                    } else {
                                        return false;
                                    }
                                }
                            };
                    
                            employeesGrid.setHeight100();
                            employeesGrid.setAutoFetchData(false);
                            employeesGrid.setCanEdit(true);
                            employeesGrid.setDataSource(DataSource.get("employees"));
                            employeesGrid.setCanGroupBy(false);
                            employeesGrid.setShowRecordComponents(false);
                            employeesGrid.setShowRecordComponentsByCell(false);
                    
                            ListGridField employeeId = new ListGridField("EmployeeId");
                            employeeId.setCanEdit(false);
                    
                            ListGridField name = new ListGridField("Name");
                            name.setCanEdit(false);
                    
                            ListGridFieldGender gender = new ListGridFieldGender("Gender", employeesGrid);
                    
                            ListGridField reportsTo = new ListGridFieldReportsTo("ReportsTo");
                    
                            ListGridField job = new ListGridField("Job");
                    
                            employeesGrid.setFields(employeeId, name, gender, reportsTo, job);
                            employeesGrid.setSort(new SortSpecifier[] { new SortSpecifier(name.getName(), SortDirection.ASCENDING) });
                            employeesGrid.fetchData(new AdvancedCriteria(new Criterion(name.getName(), OperatorId.STARTS_WITH, "A")));
                            w.addItem(employeesGrid);
                            w.show();
                        }
                    
                        private class ListGridFieldGender extends ListGridField {
                            public ListGridFieldGender(String name, final ListGrid listGrid) {
                                super(name);
                    
                                addChangedHandler(new ChangedHandler() {
                                    public void onChanged(ChangedEvent event) {
                                        int rowNum = event.getRowNum();
                                        String gender = event.getValue().toString();
                                        if (!"female".equals(gender)) {
                                            listGrid.setEditValue(rowNum, "ReportsTo", (String) null);
                                            listGrid.setEditValue(rowNum, "Job", (String) null);
                                        }
                                        listGrid.refreshCell(listGrid.getEditRow(), listGrid.getFieldNum("ReportsTo"));
                                        listGrid.refreshCell(listGrid.getEditRow(), listGrid.getFieldNum("Job"));
                                    }
                                });
                            };
                        }
                    
                        private class ListGridFieldReportsTo extends ListGridField {
                            public ListGridFieldReportsTo(String name) {
                                super(name);
                                ComboBoxItem managerCBI = new ComboBoxItem();
                                managerCBI.setOptionDataSource(DataSource.get("employees"));
                                managerCBI.setOptionOperationId("foobar");
                                managerCBI.setValueField(DataSource.get("employees").getPrimaryKeyFieldName());
                                managerCBI.setDisplayField("Name");
                                managerCBI.setPickListSort(new SortSpecifier[] { new SortSpecifier("EmployeeId", SortDirection.ASCENDING),
                                        new SortSpecifier("Name", SortDirection.ASCENDING) });
                                ListGridField managerCBI_empIdLGF = new ListGridField("EmployeeId");
                                ListGridField managerCBI_nameLGF = new ListGridField("Name");
                                managerCBI.setPickListFields(managerCBI_empIdLGF, managerCBI_nameLGF);
                                managerCBI.setPickListHeaderHeight(0);
                                setEditorProperties(managerCBI);
                            }
                        }
                    }
                    Issue 1:
                    The problem is that the "setNull" in the changed handler does not work for databound SelectItems and ComboBoxItems like here for ReportsTo.
                    I thought that I might need to get the editCell-FormItem and do a setValue there as well, but it seems that this is not the way to go:
                    ListGrid.getEditFormItem()-docs:
                    The items' values are managed by the ListGrid through the edit-values subsystem. If you want to change an edit value for a field, call ListGrid.setEditValue and the grid will handle updating the value in the live item if necessary. You should not need to call setValue(); directly on the item and doing so will not always update the edit value for the grid.
                    Steps to reproduce:
                    1. Edit a gender="female" row and change to "male".
                    2. See that the Job-field is set to null, canEdit set to false and display refreshed by refreshCell()
                    3. See that the same happens for the ReportsTo-field (underlying value is set to null as well) but the field is displayed with an editValue of the old ComboBoxItem-value until the editRow is left.
                    Minor issue 2:
                    See that (especially noticeable in FF26 dev mode) if you start the editRow the 1st time for a row by double clicking "female", the ComboBoxItem shortly shows the underlying ID-value and not "Loading...".
                    This was fixed here once.

                    Minor issue 3:
                    See that if you start the editRow the 1st time for a row by double clicking "female", the ComboBoxItem for reportsTo looks disabled (light-grey font color).

                    Best regards
                    Blama

                    Comment


                      #11
                      Hi Isomorphic,

                      please note that I sometimes(?) get this warning in the Developer Console:
                      Code:
                      16:15:42.506:MUP2:WARN:ListGrid:isc_BuiltInDS_3_1:Edit value updated for field:ReportsTo. This field has 'displayField' attribute specified as 'ManagerName', and no unique optionDataSource, so display value is derived from the current record. In order to ensure the display value is updated to reflect the new edit-value for this field, developers can explicitly update the edit value for the display-field on this record. To avoid seeing this method set listGrid.warnOnUnmappedValueFieldChange to false.
                      Using additional listGrid.setEditValue(rowNum, "ManagerName", (String) null) in the ChangedHandler I can indeed get the display I want. So issue 1 isn't an issue (once again: impressive framework!).
                      If I get annoyed by the warning, I will disable it, but it currently does not appear anymore. Please note that in the warning, "method" in the last sentence should read "warning" most likely.

                      Best regards
                      Blama

                      Comment


                        #12
                        Hi Isomorphic,

                        reason for issue 3 is this:
                        Click image for larger version

Name:	Issue3.png
Views:	402
Size:	94.0 KB
ID:	235597 On 1st start of the editor, the class is selectItemTextHint instead of selectItemText.

                        Best regards
                        Blama

                        Comment


                          #13
                          Do you get the warning about needing to update the displayField if you update the displayField *first*? That would be the correct way to do it.

                          Minor Issue 2: your displayField setting indicates the display value should be found in the ManagerName column, so your results suggest that you've left this field null (which is not allowed if you're setting displayField).

                          Minor Issue 3: you've set this field as non-editable via your canEditCell override, so aren't you expecting it to appear disabled?

                          Comment


                            #14
                            Also just a note on process:

                            1. this really should have been a new thread (too late now, just continue here)

                            2. it's much better to explain that problem first, *then* post the code, because no one would start reading the code before you've explained what the problem is.

                            Comment


                              #15
                              Hi Isomorphic,

                              ok, will open a new thread next time. I did not because all issues were in the editRow-area.

                              Issue 1:
                              I must update the value field first, otherwise I have the problem from post #10
                              Click image for larger version

Name:	Animation_issue1.gif
Views:	350
Size:	122.6 KB
ID:	235615



                              Minor issue 2:
                              Sorry, I don't follow.
                              The displayField from the .ds.xml is shown, when not editing - This is OK.
                              The displayField from the optionDataSource-settings is shown after a short time when editing - This is OK.
                              Not OK is that if you start the editRow, for a short time there is the ID to see:
                              Click image for larger version

Name:	Animation.gif
Views:	343
Size:	63.5 KB
ID:	235614
                              See that it is OK for manager="Rui Shu" and not OK for manager="Abigail Lippman". Sometimes it is also the other way around. Perhaps a timing issue?



                              Minor issue 3:
                              Gender=female rows do have the editors for Manager and Job/Title enabled. See the color change when entering the Manager-ComboBoxItem:
                              Click image for larger version

Name:	Animation_issue3.gif
Views:	349
Size:	75.7 KB
ID:	235616

                              Best regards
                              Blama

                              Comment

                              Working...
                              X