Announcement

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

    ListGrid filters unexpectedly when two columns show same data source field

    I have a grid with two columns, showing the values of only one, shared data source field. Filtering the grid is not working as expected.

    If I enter a value into the filter of the first column the focus gets lost after I type one character.

    If I enter a value into the filter of the second column the filter works better - but as soon as you switch the order of the columns by using drag and drop strange filter behaviour occurs.

    Is there any workaround for this problem?

    Thanks in advance!

    1. Versions:
    my SmartGWT version: 5.0p.0.0 09/14/2014 13:46 +0000 LGPL
    my SmartClient version: v10.0p_2014-09-14

    2. browser(s) and version(s) involved:
    Firefox 31 on Windows 7 Professional

    3. source code:
    Code:
    public class Main7 implements EntryPoint {
    
    	private VLayout layout = new VLayout(20) {{
    		setHeight(400);
    		setWidth(400);
    	}};
    
    	@Override
    	public void onModuleLoad() {
    		createConstellation( true, true, "The filter in the first column is not working:");
    		createConstellation( true, false, "The filter is not working:");
    		createConstellation(false, true, "The filter is working:");
    		layout.show();
    	}
    	
    	public void createConstellation(boolean filterable1, boolean filterable2, String title) {
    		
    		Label titleLabel = new Label(title);
    		titleLabel.setHeight(20);
    		layout.addMember(titleLabel);
    		
    		DataSourceField dataSourceField = new DataSourceField("value", FieldType.INTEGER);
    
    		Record record = new Record();
    		record.setAttribute(dataSourceField.getName(), 17);
    
    		DataSource dataSource = new DataSource();
    		dataSource.setFields(dataSourceField);
    		dataSource.setClientOnly(true);
    		dataSource.setCacheData(record);
    
    		ListGridField listGridField = new ListGridField("value1", "value1 " + (filterable1 ? "filterable" : ""));
    		listGridField.setDataPath(dataSourceField.getName());
    		listGridField.setCanFilter(filterable1);
    
    		ListGridField listGridField2 = new ListGridField("value2", "value2 " + (filterable2 ? "filterable" : ""));
    		listGridField2.setDataPath(dataSourceField.getName());
    		listGridField2.setCanFilter(filterable2);
    
    		ListGrid listGrid = new ListGrid();
    		listGrid.setFields(listGridField, listGridField2);
    		listGrid.setDataSource(dataSource);
    		listGrid.setAutoFetchData(true);
    		listGrid.setShowFilterEditor(true);
    		listGrid.setFilterOnKeypress(true);
    		layout.addMember(listGrid);
    	}
    
    }

    #2
    Try not using dataPath, which is at best redundant here (in the way you are using it), and might create this issue.

    Comment


      #3
      Thanks Isomorphic for the immediate reply!

      We are using dataPath in our Project to display one value in two different ways. We are defining one dataSource field and two list grid fields. We than can use valueMap or optionDataSource to individually render the two grid fields.

      Is there any other way to show the values of only one, shared data source field in two separate columns?

      Comment


        #4
        Hi slartidan,

        how about a 2nd .ds.xml field with name="fieldTwo" and nativeName="firstFieldname"?

        Best regards,
        Blama

        Comment


          #5
          @Blama: sadly "nativeName" is only available in SQLDataSources. My example is a clientOnly datasource, in our production code we mainly use RestDataSources.

          We also want changes on one field to be instantaniously be shown in the other field as well. The "dataPath"-method seems to be able to do that...

          Comment


            #6
            UPDATE: When using nested records the behaviour is less strange, but still unexpected:

            In this example only every second column is filterable...

            Code:
            public class Main7 implements EntryPoint {
            
            	private VLayout layout = new VLayout(20) {{
            		setHeight(400);
            		setWidth(400);
            	}};
            
            	@Override
            	public void onModuleLoad() {
            		createConstellation( true, true, "The filter in the first column is not working:");
            		createConstellation( true, false, "The filter is not working:");
            		createConstellation(false, true, "The filter is working:");
            		layout.show();
            	}
            	
            	public void createConstellation(boolean filterable1, boolean filterable2, String title) {
            		
            		Label titleLabel = new Label(title);
            		titleLabel.setHeight(20);
            		layout.addMember(titleLabel);
            		
            		DataSourceField dataSourceField = new DataSourceField("value", FieldType.INTEGER);
            
            		Record nestedRecord = new Record();
            		nestedRecord.setAttribute("innerValue", 17);
            		
            		Record record = nestedRecord;
            		record.setAttribute(dataSourceField.getName(), nestedRecord);
            
            		DataSource dataSource = new DataSource();
            		dataSource.setFields(dataSourceField);
            		dataSource.setClientOnly(true);
            		dataSource.setCacheData(record);
            
            		ListGridField listGridField = new ListGridField("value1", "value1 " + (filterable1 ? "filterable" : ""));
            		listGridField.setDataPath(dataSourceField.getName()+"/innerValue");
            		listGridField.setCanFilter(filterable1);
            
            		ListGridField listGridField2 = new ListGridField("value2", "value2 " + (filterable2 ? "filterable" : ""));
            		listGridField2.setDataPath(dataSourceField.getName()+"/innerValue");
            		listGridField2.setCanFilter(filterable2);
            
            		ListGrid listGrid = new ListGrid();
            		listGrid.setFields(listGridField, listGridField2);
            		listGrid.setDataSource(dataSource);
            		listGrid.setAutoFetchData(true);
            		listGrid.setShowFilterEditor(true);
            		listGrid.setFilterOnKeypress(true);
            		layout.addMember(listGrid);
            	}
            
            }

            Comment


              #7
              We're having trouble understanding what the purpose or expected behavior is here. Why would you display identical data in two columns and have two input areas for entering search criteria that apply to the same underlying data value? That seems redundant and confusing for the user.

              If you are looking for something like applying criteria to a single field but with multiple different search operators, the FilterBuilder is a good UI for that.

              Comment


                #8
                I have to appologize: I tried to make the example code as simple as possible - it seems like i reduced the example too much.

                This code uses different value maps for both columns:
                Code:
                public class Main7 implements EntryPoint {
                	
                	private static final Map<String, String> valueMap = new HashMap<String, String>() {{
                		put("17", "Anthony Benoit");
                		put("23", "Chris Fisher");
                	}};
                	
                	private static final Map<String, String> valueMap2 = new HashMap<String, String>() {{
                		put("17", "17 Cliff Avenue");
                		put("23", "23 Water Street");
                	}};
                	
                	private VLayout layout = new VLayout(20) {{
                		setHeight(600);
                		setWidth(400);
                	}};
                
                	@Override
                	public void onModuleLoad() {
                		createConstellation( true, true, "The filter in the first column is not working:");
                		createConstellation( true, false, "The filter is not working:");
                		createConstellation(false, true, "The filter is working:");
                		layout.show();
                	}
                	
                	public void createConstellation(boolean filterable1, boolean filterable2, String title) {
                		
                		Label titleLabel = new Label(title);
                		titleLabel.setHeight(20);
                		layout.addMember(titleLabel);
                		
                		DataSourceField dataSourceField = new DataSourceField("value", FieldType.INTEGER);
                
                		Record record = new Record();
                		record.setAttribute(dataSourceField.getName(), 17);
                
                		DataSource dataSource = new DataSource();
                		dataSource.setFields(dataSourceField);
                		dataSource.setClientOnly(true);
                		dataSource.setCacheData(record);
                
                		ListGridField listGridField = new ListGridField("value1", "value1 " + (filterable1 ? "filterable" : ""));
                		listGridField.setDataPath(dataSourceField.getName());
                		listGridField.setValueMap(valueMap);
                		listGridField.setCanFilter(filterable1);
                
                		ListGridField listGridField2 = new ListGridField("value2", "value2 " + (filterable2 ? "filterable" : ""));
                		listGridField2.setDataPath(dataSourceField.getName());
                		listGridField2.setValueMap(valueMap2);
                		listGridField2.setCanFilter(filterable2);
                
                		ListGrid listGrid = new ListGrid();
                		listGrid.setFields(listGridField, listGridField2);
                		listGrid.setDataSource(dataSource);
                		listGrid.setAutoFetchData(true);
                		listGrid.setShowFilterEditor(true);
                		listGrid.setFilterOnKeypress(true);
                		layout.addMember(listGrid);
                	}
                }

                Comment


                  #9
                  Sorry, but this makes even less sense now. You're taking a single underlying data value and displaying it in two columns with different value maps?

                  This sort of looks like you are doing what dataSourceField.includeFrom is intended to address (getting display values from related records), except you're doing it in a bizarre way with valueMaps. This approach has fundamental problems: you're basically trying to turn one DataSourceField field into two fields at the ListGrid level, but you have no way to define validators, editors and other behaviors which are distinct between the fields, and which are data-centric, not display centric (so they can't and should not be defined at the ListGridField level).

                  Instead, you should set up two DataSourceFields.

                  Comment


                    #10
                    dataSourceField.includeFrom is not an option in my project, because (as far as I know) it can only be used with a SmartGWT server. Due to the infrastructure in our company, server parts have to be implemented in .net.

                    Is there any way to show "related" columns, when using SmartGWT just for the client side?

                    Comment


                      #11
                      Yes. Just deliver the data in the same way as we describe for DataSourceField.includeFrom (it looks like you must have stopped reading this doc halfway or less of the way through).

                      Comment


                        #12
                        After reading a lot of documentation I started a separate Thread to this topic ( see http://forums.smartclient.com/showthread.php?t=31906 )

                        There I was told from Isomorphic ( http://forums.smartclient.com/showpost.php?p=127284&postcount=2 11th Dec 2014, 12:10 ) that includeFrom is not currently supported for clientOnly DataSources.

                        Comment

                        Working...
                        X