Announcement

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

    BUG: Filtering a grid after a column is shown, causes the grid to loose its criteria.

    I found a bug on the latest nightly build.
    I am currently using: SmartClient Version: v10.0p_2015-05-25/LGPL Development Only (built 2015-05-25), but I was able to reproduce it with the build from (2015-06-11)

    If we have a ListGrid with an initialCriteria, I expect that this criteria will be kept when I'm filtering the grid.
    Everything works as expected just until I show a column that is not originally shown when the grid is drawn.

    Example:
    Code:
    package org.test.client;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.user.client.ui.RootPanel;
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.data.fields.DataSourceTextField;
    import com.smartgwt.client.data.AdvancedCriteria;
    import com.smartgwt.client.data.Criterion;
    import com.smartgwt.client.types.OperatorId;
    import com.smartgwt.client.util.SC;
    import com.smartgwt.client.widgets.grid.ListGrid;
    import com.smartgwt.client.widgets.grid.events.FilterEditorSubmitEvent;
    import com.smartgwt.client.widgets.grid.events.FilterEditorSubmitHandler;
    
    
    public class MainEntryPoint implements EntryPoint {
    
        @Override
        public void onModuleLoad() {
    
            ListGrid grid = new ListGrid();
            grid.setShowFilterEditor(true);
            grid.setWidth100();
            grid.setHeight100();
            grid.addFilterEditorSubmitHandler(new FilterEditorSubmitHandler() {
    
                @Override
                public void onFilterEditorSubmit(FilterEditorSubmitEvent event) {
                    SC.logWarn("event.getCriteria(): " + event.getCriteria().getValues());
                }
            });
    
            DataSourceTextField f1 = new DataSourceTextField("f1", "Field 1");
            f1.setCanFilter(true);
            DataSourceTextField f2 = new DataSourceTextField("f2", "Field 2");
            f2.setCanFilter(true);
            DataSourceTextField f3 = new DataSourceTextField("f3", "Field 3");
            f3.setCanFilter(true);
            f3.setDetail(true);
    
            DataSource datasource = new DataSource();
            datasource.setClientOnly(true);
            datasource.setFields(f1, f2, f3);
            grid.setDataSource(datasource);
    
            grid.fetchData(new AdvancedCriteria(OperatorId.AND, new Criterion[]{new Criterion("f1", OperatorId.EQUALS, 1)}));
    
            RootPanel.get().add(grid);
        }
    }
    The following example is not showing any data, because I am trying to keep the example as simple as possible. The only issue is the filtering after the field 3 is shown.

    1) Because initially a grid.fetch is made, so the base criteria is set up:
    Code:
    grid.fetchData(new AdvancedCriteria(OperatorId.AND, new Criterion[]{new Criterion("f1", OperatorId.EQUALS, 1)}));
    2) If I filter the field 1 with a value = 6, this is the result:
    "event.getCriteria(): {operator=and, criteria=[{fieldName=f1, operator=equals, value=1}, {fieldName=f1, operator=iContains, value=6}], _constructor=AdvancedCriteria}"
    3) If I add another filter on filed 2 with value = 7:
    "event.getCriteria(): {operator=and, criteria=[{fieldName=f1, operator=equals, value=1}, {fieldName=f1, operator=iContains, value=6}, {fieldName=f2, operator=iContains, value=7}], _constructor=AdvancedCriteria}"
    4) Now if I show the field f3 and filter field 3 with value = 8:
    "event.getCriteria(): {f1=6, f2=7, f3=8}". This criteria is bogus and should not destroy the original criteria applied on the grid.

    Isomorphic, please advise if I am missing some property that I have not set or it is an unexpected behavior.

    System Details:
    Windows 7 64 bit.
    Browser: Chrome, IE11, maybe others.
    GWT 2.7, Smartgwt 5.0.
    SmartClient Version: v10.0p_2015-05-25/LGPL Development Only (built 2015-05-25).

    #2
    I have the exact same problem. Please suggest a solution!

    Best regards

    Comment


      #3
      It's being looked into - we'll update here when we have more information.

      Comment


        #4
        This is fixed for builds dated June 16 and later.

        Comment


          #5
          I can confirm that this is fixed in 2015-06-16's build.
          Further regression testing is to be done so if anything comes up I will feedback.
          Thank you for the quick fix.

          Comment


            #6
            So there are two issues here:

            1) The first has to do with this thread and it seems that when I right-click on the grid and press the clear filter menu item (see the image), the criteria gets lost the same way as in the bug described earlier.

            2) The ComboBoxItem does a strange initial autofetch by the displayValue. It searches in the database the value that matches the entered string and takes as value the first record (in my case there are multiple by 'name' but different 'ids') it founds.
            Those are the properties applied. I also use the setPickListProperties(pickListProperties); where the pickListProperties is a simple grid with one field I am styling (if it actually matters).
            Code:
                    setAddUnknownValues(false);
                    setAutoFetchData(true);
                    setOptionDataSource(datasource);
                    setDisplayField(TRPConstants.colName);
                    setValueField(TRPConstants.colId);
                    setSortField(TRPConstants.colName);
                    setTextMatchStyle(TextMatchStyle.SUBSTRING);
                    setCachePickListResults(false);
            This used to work in the build 5.0p: 2015-05-25. Would you like me to start a new thread?
            Attached Files

            Comment


              #7
              1) Thats by design - clearing criteria clears criteria - you seem to think that initialCriteria are there forever, but that isn't the case - we do have such a feature, implicitCriteria, but that is new to 5.1.

              2) We'll need a standalone test-case for this, and steps to reproduce the issue.

              Comment


                #8
                1) If this is by design - ok. I still think that loosing the initial grid criteria could be a potential security breach but I suppose I could handle the clear filter functionality.

                2) Regarding the standalone test-case, this is the code that I am reproducing the problem with. The issue seems to be when setting the setPickListFilterCriteriaFunction().
                What is happening here is that there are two records in the database that match the provided criteria ([id=61422, name=Auxiliary Drive Belt Kit] and [id=110047, name=Auxiliary Drive Belt Kit]) but when I set the default value to 110047, the combobox automatically makes a string search by the displayValue name. In my case it finds the record with id 61422 (because the ids are in ascending order, so this id is before the other) and this is the last value it stores.
                When I select a value from the dropdown list, it works fine.
                The problem is only when I use setValue during the initialization.
                Code:
                    private Label label = new Label(); 
                    
                    @Override
                    public void onModuleLoad() {
                
                        final ComboBoxItem item = new ComboBoxItem();
                        item.setWidth(300);
                        item.setAddUnknownValues(false);
                        item.setAutoFetchData(true);
                		// This is a GenericGwtRpcDataSource
                        item.setOptionDataSource(DataSourcesManager.getTestDS());
                        item.setDisplayField("name");
                        item.setValueField("id");
                        item.setSortField("name");
                        item.setTextMatchStyle(TextMatchStyle.SUBSTRING);
                        item.setPickListFilterCriteriaFunction(new FormItemCriteriaFunction() {
                
                            @Override
                            public Criteria getCriteria(FormItemFunctionContext itemContext) {
                                return new AdvancedCriteria(OperatorId.AND, new Criterion[]{new Criterion("some_criteria_id", OperatorId.EQUALS, 15)});
                            }
                        });
                
                        DynamicForm form = new DynamicForm();
                        form.setWidth100();
                        form.setItems(item);
                        
                        VLayout layout = new VLayout();
                        layout.addMember(form);
                        layout.addMember(label);
                        
                        IButton button = new IButton("Test");
                        button.addClickHandler(new ClickHandler() {
                
                            @Override
                            public void onClick(ClickEvent event) {
                                label.setContents("value: " + item.getValue());
                            }
                        });
                        layout.addMember(button);
                        
                	// id = 61422,  name = Auxiliary Drive Belt Kit
                	// id = 110047, name = Auxiliary Drive Belt Kit
                        item.setValue(110047L);
                
                        RootPanel.get().add(layout);
                    }
                Attached Files

                Comment


                  #9
                  1) no possibility of a security breach since this is client-side logic

                  2) we'll look at this one

                  Comment


                    #10
                    We can't run your sample because it's incomplete, and we don't see this issue in a test of our own.

                    We'll need to see a standalone, running sample that shows the issue, including a clientOnly dataSource with data.

                    Note that you should be using widget.draw() and not rootPanel.add().

                    Comment


                      #11
                      This is the simplest standalone that I was able to reproduce the issue with:
                      Code:
                      private Label label = new Label(); 
                          
                          @Override
                          public void onModuleLoad() {
                      
                              final ComboBoxItem item = new ComboBoxItem();
                              item.setWidth(300);
                              item.setAddUnknownValues(false);
                              item.setAutoFetchData(true);
                              item.setOptionDataSource(CountryDS.getInstance());
                              item.setDisplayField("countryName");
                              item.setValueField("id");
                              item.setSortField("countryName");
                              item.setTextMatchStyle(TextMatchStyle.SUBSTRING);
                              item.setPickListFilterCriteriaFunction(new FormItemCriteriaFunction() {
                      
                                  @Override
                                  public Criteria getCriteria(FormItemFunctionContext itemContext) {
                                      return new AdvancedCriteria(OperatorId.AND, new Criterion[]{new Criterion("id", OperatorId.GREATER_OR_EQUAL, 1)});
                                  }
                              });
                      
                              DynamicForm form = new DynamicForm();
                              form.setWidth100();
                              form.setItems(item);
                              
                              VLayout layout = new VLayout();
                              layout.addMember(form);
                              layout.addMember(label);
                              
                              IButton button = new IButton("Test");
                              button.addClickHandler(new ClickHandler() {
                      
                                  @Override
                                  public void onClick(ClickEvent event) {
                                      label.setContents("value: " + item.getValue());
                                  }
                              });
                              layout.addMember(button);
                              
                              item.setValue(2);
                             
                              layout.draw();
                          }
                          
                          private static class CountryDS extends DataSource {  
                              // The DataSource would normally be defined external to any classes that use it.  
                        
                              private static CountryDS instance = null;  
                                
                              public static CountryDS getInstance() {  
                                  if (instance == null) {  
                                    instance = new CountryDS("countryDS_DS");  
                                  }  
                                  return instance;  
                              }  
                        
                              public CountryDS(String id) {  
                                  setID(id);  
                                  setRecordXPath("/List/country");  
                                  DataSourceField idField = new DataSourceField("id", FieldType.INTEGER, "Id");  
                                  DataSourceField countryNameField = new DataSourceField("countryName", FieldType.TEXT, "Country");  
                        
                                  setFields(idField, countryNameField);  
                                  setDataURL("country_data.xml");  
                              }  
                        
                          }
                      This is the country_data.xml
                      Code:
                      <List>
                          <country>
                              <id>1</id>
                              <countryName>China</countryName>
                          </country>
                          <country>
                              <id>2</id>
                              <countryName>China</countryName>    
                          </country>
                      </List>
                      So when the widget is drawn, press the Test button and observe the value is 1 instead of 2 (which has been set).

                      Best Regards

                      Comment


                        #12
                        Hi kiril_bhd,

                        I don't know if this might cause the behavior you are seeing, but it seems your DS is lacking a primaryKey definition.

                        Best regards
                        Blama

                        Comment


                          #13
                          We'll take a look at your sample today - but Blama is correct, you need a primaryKey column on your DS.

                          Comment


                            #14
                            We do indeed see this behavior with your latest sample code, although what's happening is not quite what you described - the item being drawn issues a fetch for the record with id: 2, and then, because you've setAutoFetchData(true), a second fetch is made - the result of that is that the first item is selected.

                            We'll queue this up to be looked at, but your quickest fix is just not to setAutoFetchData(true) on the item, allowing the default behavior of fetching data automatically when the picklist is displayed.

                            Comment


                              #15
                              Blama, the primary key is not the issue here. I have it in my real environment and the issue is still there.

                              The problem lies somewhere in the setPickListFilterCriteriaFunction method. If I remove the setPickListFilterCriteriaFunction, then everything works as expected.

                              I disagree that the second fetch selects the first item.

                              Here a 3 scenarios with 3 datasets:

                              1) In this case if we set the value to 2, the value would be 1, because the first id that matches China is 1.
                              Code:
                              <List>
                                  <country>
                                      <id>1</id>
                                      <countryName>China</countryName>
                                  </country>
                                  <country>
                                      <id>2</id>
                                      <countryName>China</countryName>    
                                  </country>
                              </List>
                              2) In this case if we set the value to 2, the value would be 2, because it is the first China, that matches the displayValue China
                              Code:
                              <List>
                                  <country>
                                      <id>2</id>
                                      <countryName>China</countryName>    
                                  </country>
                                  <country>
                                      <id>1</id>
                                      <countryName>China</countryName>
                                  </country>
                              </List>
                              3) In this case if we set the value to 2, the value would be 1. Brasil does not match China string, so the first value is not selected.
                              Code:
                              <List>
                                   <country>
                                      <id>3</id>
                                      <countryName>Brasil</countryName>
                                  </country>
                                  <country>
                                      <id>1</id>
                                      <countryName>China</countryName>
                                  </country>
                                  <country>
                                      <id>2</id>
                                      <countryName>China</countryName>    
                                  </country>
                              </List>

                              Comment

                              Working...
                              X