Announcement

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

    Confirmed: bug with SelectItem and ComboBoxItem

    SmartGWT Pro, version 2.1

    When putting two selectItems or two comboBoxItems on a form; backed by the same OptionDataSource; the data from the two selectItems/comboBoxItems interfers with each other in an unintended and unwanted fashion.

    Simplified code example:

    Code:
    import com.google.gwt.core.client.EntryPoint;
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.widgets.form.DynamicForm;
    import com.smartgwt.client.widgets.form.fields.SelectItem;
    import com.smartgwt.client.widgets.layout.HLayout;
    import com.smartgwt.client.widgets.layout.Layout;
    
    public class TomcatGWT implements EntryPoint {
    	
    	Layout layout;
    	
    	public TomcatGWT()
    	{
    		DataSource dataSource = DataSource.get("user");
    		
    		layout= new HLayout();
    		layout.setWidth(800);
    		
    		DynamicForm form = new DynamicForm();
    		SelectItem createdBy = new SelectItem();
    		createdBy.setTitle("Created By");
    		createdBy.setOptionDataSource(dataSource);
    		createdBy.setValueField("userId");
    		createdBy.setDisplayField("fullName");
    		
    		SelectItem assignedTo = new SelectItem();
    		assignedTo.setTitle("Assigned To");
    		assignedTo.setOptionDataSource(dataSource);
    		assignedTo.setValueField("userId");
    		assignedTo.setDisplayField("fullName");
    		
    		createdBy.setValue("john");
    		assignedTo.setValue("jane");
    		
    		form.setFields(createdBy, assignedTo);
    		
    		layout.addMember(form);
    	}
    
    	@Override
    	public void onModuleLoad() {
    		layout.draw();
    	}
    
    }
    DS.xml file:

    Code:
    <DataSource
    	ID="user"
    	serverType="generic">
    	<fields>
    		<field name="userId" type="text" hidden="false" primaryKey="true"/>
    		<field name="firstName" type="text" length="255"/>
    		<field name="lastName" type="text" length="255"/>
    		<field name="fullName" type="text" valueXPath="concat(firstName, ' ', lastName)"/>
    	</fields>
    	
    	<serverObject lookupStyle="spring" bean="userDAO"/>
    </DataSource>
    What happens:

    The two selectItems/comboBoxItems render fine, and populated correctly with the values from the dataSource. Also; they display, the correctly set user (i.e. in the example, createdBy displays the full name for user "john" and assignedTo displays the full name for user "jane".)

    However, when you open the drop-down, which ever selectItem/comboBoxItem is positioned SECOND in the form (in this case, assignedTo) will show the value from the FIRST dropdown as selected.

    So in this case, BOTH createdBy and assignedTo show "john" as being the selected value when the dropdown is opened, even though assignedTo correctly shows "jane" as selected when the dropdown is closed.

    #2
    As an addendum: creating two separate instances to the same server-side datasource doesn't work either; it still produces the same result:

    Code:
    import com.google.gwt.core.client.EntryPoint;
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.widgets.form.DynamicForm;
    import com.smartgwt.client.widgets.form.fields.SelectItem;
    import com.smartgwt.client.widgets.layout.HLayout;
    import com.smartgwt.client.widgets.layout.Layout;
    
    public class TomcatGWT implements EntryPoint {
    	
    	Layout layout;
    	
    	public TomcatGWT()
    	{
    		DataSource createdByDataSource = DataSource.get("user");
    		DataSource assignedToDataSource = DataSource.get("user");
    		
    		layout= new HLayout();
    		layout.setWidth(800);
    		
    		DynamicForm form = new DynamicForm();
    		SelectItem createdBy = new SelectItem();
    		createdBy.setTitle("Created By");
    		createdBy.setOptionDataSource(createdByDataSource);
    		createdBy.setValueField("userId");
    		createdBy.setDisplayField("fullName");
    		
    		SelectItem assignedTo = new SelectItem();
    		assignedTo.setTitle("Assigned To");
    		assignedTo.setOptionDataSource(assignedToDataSource);
    		assignedTo.setValueField("userId");
    		assignedTo.setDisplayField("fullName");
    		
    		createdBy.setValue("john");
    		assignedTo.setValue("jane");
    		
    		form.setFields(createdBy, assignedTo);
    		
    		layout.addMember(form);
    	}
    
    	@Override
    	public void onModuleLoad() {
    		layout.draw();
    	}
    
    }

    Comment


      #3
      In fact: the problem is worse than I thought; never mind the state of the first selectItem on load - subsequent changes, in the life application ALSO affect the dropdown of the second selectItem. For instance: change the first selectItem to any value (John, Jane, Smith, it doesn't matter) and the second selectItem shows the exact same value when the dropdown is opened. It also doesn't matter whether the two selectItems are on the same form or not:

      Code:
      public TomcatGWT()
      	{
      		DataSource createdByDataSource = DataSource.get("user");
      		DataSource assignedToDataSource = DataSource.get("user");
      		
      		layout= new HLayout();
      		layout.setWidth(800);
      		
      		DynamicForm form1 = new DynamicForm();
      		DynamicForm form2 = new DynamicForm();
      		SelectItem createdBy = new SelectItem();
      		createdBy.setTitle("Created By");
      		createdBy.setOptionDataSource(createdByDataSource);
      		createdBy.setValueField("userId");
      		createdBy.setDisplayField("fullName");
      		
      		SelectItem assignedTo = new SelectItem();
      		assignedTo.setTitle("Assigned To");
      		assignedTo.setOptionDataSource(assignedToDataSource);
      		assignedTo.setValueField("userId");
      		assignedTo.setDisplayField("fullName");
      		
      		createdBy.setValue("john");
      		assignedTo.setValue("jane");
      		
      		form1.setFields(createdBy);
      		form2.setFields(assignedTo);
      		
      		layout.addMember(form1);
      		layout.addMember(form2);
      	}
      This still generates the same behaviour.

      However, setting either one of the selectItem/ComboBoxItems to be allowed empty values; i.e.:

      Code:
      createdBy.setAllowEmptyValue(true);
      fixes the problem; so I suspect something is wrong either with the client dataSource logic itself; or in how the selectItem/comboBoxItem interfaces with that dataSource - presumably allowing empty-values creates a new valueMap on the fly and the two selectItems are no longer backed by the same variable set.

      Comment


        #4
        We're not reproducing this problem in the 2.1 release (I'm testing with the enterprise eval version rather than the Pro but that shouldn't make any difference).

        I tested by modifying the "built-in-ds" sample app to use essentially your code:
        Code:
            public  void onModuleLoad () {
            	DataSource dataSource =DataSource.get("supplyItem");
        	  	
        		DataSource createdByDataSource = dataSource;
        		DataSource assignedToDataSource = dataSource;
        		
        		HLayout layout= new HLayout();
        		layout.setWidth(800);
        		
        		DynamicForm form1 = new DynamicForm();
        		DynamicForm form2 = new DynamicForm();
        		SelectItem createdBy = new SelectItem();
        		createdBy.setTitle("Created By");
        		createdBy.setOptionDataSource(createdByDataSource);
        		createdBy.setValueField("SKU");
        		createdBy.setDisplayField("itemName");
        		form1.setItems(createdBy);
        		
        		SelectItem assignedTo = new SelectItem();
        		assignedTo.setTitle("Assigned To");
        		assignedTo.setOptionDataSource(assignedToDataSource);
        		assignedTo.setValueField("SKU");
        		assignedTo.setDisplayField("itemName");
        		form2.setItems(assignedTo);
        		
        		createdBy.setValue("724800");
        		assignedTo.setValue("135900");
        		
        		layout.addMember(form1);
        		layout.addMember(form2);
        		layout.setBackgroundColor("pink");
        		layout.draw();
            }
        The only real difference here is some tweaks to the display/value fields.
        I found when I loaded the page, the drop downs both showed the appropriate record selected, and modifying the selection at runtime on one drop down didn't effect the display on the other.

        Can you run that same test and confirm whether you're seeing the bug. If not the most likely candidate is something in your data (for example collisions on the primary key field, perhaps?)

        Let us know if you can narrow it down to a complete test case we can run (Probably easiest to try making the dataSource clientOnly and applying the data directly on the client - if you can reproduce the problem like that we can run exactly your code) and hopefully see it on our end.

        Comment


          #5
          I tried using the built-in-ds example.. for some reason the datasources aren't loading for me; but in order to make this really simple; I created a client-only datasource, as you suggested:

          Code:
          package com.smartgwt.sample.client;
          
          import com.smartgwt.client.core.DataClass;
          import com.smartgwt.client.data.DataSource;
          import com.smartgwt.client.data.fields.DataSourceTextField;
          
          public class ClientOnlyDataSource extends DataSource {
          	
          	private static ClientOnlyDataSource instance = null;
          	
          	public static ClientOnlyDataSource getInstance()
          	{
          		if(instance == null)
          		{
          			instance = new ClientOnlyDataSource("users");
          		}
          		
          		return instance;
          	}
          	
          	public ClientOnlyDataSource (String id)
          	{
          		setID(id);
          		
          		DataSourceTextField userId = new DataSourceTextField("userId", "User ID", 128, true);
          		userId.setHidden(false);
          		userId.setPrimaryKey(true);
          		
          		DataSourceTextField fullName = new DataSourceTextField("fullName", "Full Name", 128, true);
          		
          		setFields(userId, fullName);
          		setClientOnly(true);
          		setTestData(getTestRecords());
          	}
          
          	private DataClass[] getTestRecords() {
          		DataClass[] data = new DataClass[2];
          		data[0] = new DataClass();
          		data[0].setAttribute("userId", "Jane");
          		data[0].setAttribute("fullName", "Jane Doe");
          		
          		data[1] = new DataClass();
          		data[1].setAttribute("userId", "John");
          		data[1].setAttribute("fullName", "John Doe");
          		
          		return data;
          	}
          
          }
          I then modified the BuiltInDS example to reproduce the error; like so:

          Code:
          package com.smartgwt.sample.client;
          
          import com.google.gwt.core.client.EntryPoint;
          import com.smartgwt.client.data.DataSource;
          import com.smartgwt.client.widgets.form.DynamicForm;
          import com.smartgwt.client.widgets.form.fields.SelectItem;
          import com.smartgwt.client.widgets.layout.HLayout;
          import com.smartgwt.client.widgets.layout.Layout;
          
          /**
           * Entry point classes define <code>onModuleLoad()</code>.
           */
          public class BuiltInDS implements EntryPoint {
          	private Layout layout;
          
          
              public  void onModuleLoad () {
          	DataSource dataSource= ClientOnlyDataSource.getInstance();
          		
          		layout= new HLayout();
          		layout.setWidth(800);
          		
          		DynamicForm form = new DynamicForm();
          		SelectItem createdBy = new SelectItem();
          		createdBy.setTitle("Created By");
          		createdBy.setOptionDataSource(dataSource);
          		createdBy.setValueField("userId");
          		createdBy.setDisplayField("fullName");
          		
          		SelectItem assignedTo = new SelectItem();
          		assignedTo.setTitle("Assigned To");
          		assignedTo.setOptionDataSource(dataSource);
          		assignedTo.setValueField("userId");
          		assignedTo.setDisplayField("fullName");
          		
          		createdBy.setValue("Jane");
          		assignedTo.setValue("John");
          		
          		form.setFields(createdBy, assignedTo);
          	
          		layout.addMember(form);
          		
          		layout.draw();
              }
          }
          I am still seeing the problem; and I'm not sure why you're not seeing it. Perhaps I need an image to show what I mean, so: [link]http://yfrog.com/83smargwterrorp[/link]

          This shows the problem precisely: dropdown 1 is correctly showing Jane Doe as the value, dropdown 2 is correctly showing John Doe as the value; but the picklist of dropdown 2 INCORRECTLY shows Jane Doe as selected. Changing the selection in dropdown 1 will always also change the selection in the picklist of dropdown 2.

          I have the modified BuiltInDS example as a zip archive, if you want it. Just tell me where to upload it to
          Last edited by SiccoNaets; 7 Jul 2010, 06:33.

          Comment


            #6
            That blue highlight is not the selection, it's the default choice if you hit return, and it's where keyboard navigation starts from.

            Comment


              #7
              Sorry Iso, but I don't think that's correct. In fact, I discovered the problem exists in IE and Firefox but not in Chrome.

              I took a screen-cap of what's going on as it's hard to tell from a static screenshot. Please take a look at this video:

              http://www.mediafire.com/?0zc4feyydtt


              You can see that the blue-highlight changes in BOTH combo-boxes in Firefox as I select different options in the first dropdown. It's bugged in IE as well; but as you can see from my vide; it does not show this behavior in Chrome (which works as you would expect it to work).

              This is definitely not the default value kicking in - if that was the case, you'd expect it would always pick the first option in the picklist but you can see that as I click the second option in createdBy, the second option in assigned to is selected as well.


              This is definitely a bug.

              This is not an insignificant issue - if I have a dropdown with a lot of items (say a couple of hundred), you basically lose the current selection as soon as you open the drop-down.

              Comment


                #8
                Here's a youtube version of the video, if that's easier. The resolution isn't that great, but you can still kinda see it.

                http://www.youtube.com/watch?v=OqusQ-eeEeY

                Comment


                  #9
                  Ok - we finally reproduced this. Thanks for your help clarifying exactly what you are seeing.
                  This issue existed in the 2.1 build but has subsequently been resolved. SGWT Pro 2.2 is currently in final testing and should be released very soon. If you do not immediately plan to upgrade, adding this patch code to your bootstrap HTML file (*after* the Isomorphic SmartClient libraries have been loaded) should solve the problem.

                  Note - if this doesn't work for you, please let us know. You will probably see a log message detailing a version mismatch - copy and paste that in here and we can fix the code (just adjust the buildDate check to apply it to your specific build).
                  Code:
                      <script>
                      if (window.isc) {
                      	if (isc.buildDate == "2010-03-09") {
                      		if (isc.SelectItem) isc.SelectItem.addProperties({cachePickListResults:false});
                      	} else {
                      	    isc.Log.logWarn("Patch code for SGWT 2.1 (build date 2010/03/09) included in this application " +
                      	      "You are running version:" + isc.version + " built on " + isc.buildDate +
                      	       " - this patch will have no effect in this app and can be removed.");
                      	}
                       }
                       </script>

                  Comment

                  Working...
                  X