Announcement

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

    "Select All" with OptionDataSource

    Hi,

    this is probably a dumb question; but I'm wondering how to do this.

    I have a form with a ComboBoxItem which is supposed to display a list of accounts. The contents of the ComboBoxItem is based on a DataSource (via .setOptionDataSource) and the datasource is backed by Spring/Hibernate via DMI.

    All this works fine; however the ComboBoxItem is part of a search form. What I would like to do is add an "All" value to the ComboBoxItem; in addition to what it's getting back from the datasource (this allows users to NOT filter the search by account, basically).

    I know that I can set the DefaultValue of the ComboBoxItem by calling ComboBoxItem.setDefaultValue("All"); however, as soon as a user picks some other value, "All" disappears from the list and there's no way to set the ComboBoxItem back to it's starting value.

    So, how do you add a permantent option to a ComboBoxItem (or SelectItem or whatever) that's not part of the original DataSource?

    #2
    Ok, so I've been experimenting with different solutions to get this to work; and I've found something that works; but it's fairly convoluted.

    My reasoning was that I could use .setValueMap instead of setOptionDataSource, manually construct the valueMap from a datasource; combining the datasource data with any other options I want to add:

    Code:
    	ComboBoxItem accountField = new ComboBoxItem();
    	DataSource accountDS = DataSource.get("account");
    	ResultSet accountResults = new ResultSet();
    	accountResults.setDataSource(accountDS);
    	accountResults.setFetchMode(FetchMode.LOCAL);
    	
    
    	accountResults.addDataArrivedHandler(new DataArrivedHandler(){
    
    		@Override
    		public void onDataArrived(DataArrivedEvent event) {
    			Log.debug("Data arrived.");
    
    			Map accountMap = accountResults.getValueMap("id", "company");
    			Log.debug("accountMap contains " + accountMap.size() +" results");
    
    			LinkedHashMap<String,String> linkedAccountMap = (LinkedHashMap<String,String>)accountMap;
    			LinkedHashMap<String,String> valueMap = new LinkedHashMap<String,String>();
    			valueMap.put("Any", "ANY");
    			valueMap.putAll(linkedAccountMap);
    			accountField.setAccountValueMap(valueMap);
    
    		}
    
    
    
    	});
    	
    	accountResults.getRange(0, -1);

    Code summary: I'm manually creating a resultset on top of the account datasource and setting the FetchMode to LOCAL so that it retrieves all the accounts in one go.
    I then add a DataArrivedHandler to the resultset; the call to resultset.getValueMap() WOULD trigger a fetch but AFTER the method completes; so the initial valueMap would be empty.
    I finish by calling getRange(0, -1) (signifying: "get everything") on the resultset. When this completes; the dataArrivedHandler is invoked; I get the result set as a valueMap, create a new valueMap, add my "ANY" option to it,
    and then copy all the datasource values on top of it.

    This works; but it's pretty lengthy and convoluted, is this really the only way to do this?
    Last edited by SiccoNaets; 19 May 2010, 10:52.

    Comment


      #3
      No need to involve a ResultSet - call DataSource.fetchData and derivethe valueMap when the callback fires.

      Comment


        #4
        Originally posted by Isomorphic
        No need to involve a ResultSet - call DataSource.fetchData and derivethe valueMap when the callback fires.
        Actually, I tried that originally; but when I called DataSource.fetchData(); the dataArrivedHandler() on the ResultSet never triggered.

        Comment


          #5
          Actually, I misunderstood; I think.

          You mean like this, right?

          Code:
          ComboBoxItem accountField = new ComboBoxItem();
          DataSource accountDS = DataSource.get("account");
          accountDS.fetchData(null, new DSCallback(){
          
          			@Override
          			public void execute(DSResponse response, Object rawData,
          					DSRequest request) 
          			{
          				LinkedHashMap<String,String> valueMap = new LinkedHashMap<String,String>();
          				valueMap.put("Any", "Any");
          				Record[] results = response.getData();
          				Log.debug("Found " + results.length + " accounts.");
          				
          				for(Record result : results)
          				{
          					valueMap.put(result.getAttribute("id"), result.getAttribute("company"));
          				}
          				
          				accountField.setValueMap(valueMap);
          			}
          			
          			
          		});
          That's a lot simpler; you're right.

          Comment


            #6
            I want to achieve the same, setting a emptyDisplayValue like for the SelectItem, but for a combobox item.

            When I use the code of SiccoNaets, there is no change of the displayed values of the dropdown.

            Is there still a better approach for this with the newest version?

            Comment


              #7
              You probably took the (correct) approach shown by SiccoNaets but then also provided an optionDataSource. The approach shown should be used *without* setting optionDataSource.

              Comment


                #8
                My code is nearly the same like in the example on http://www.smartclient.com/smartgwt/...bobox_category for the custom search and select dialog. For this, I want to add the "ANY" header at the beginning of the dropdown list.

                public void onDataArrived(DataArrivedEvent event)
                is used with an optionDataSource.

                So what would you suggest to make this working with an optionDatasource ?

                Where to set the vertical header size?



                As an alternative I tried to use setHint("Any") and setShowHintInField(true) ,
                to display a emptydisplay value for the dropdown.
                This is not working properly: It is displayed after page load.
                On IE 8 if these two properties are set, you can't even select an entry from list.
                But if you choose an entry and remove content again, the hint is not displayed again, instead of empty space. Is this a known bug?
                Last edited by damend; 12 May 2011, 06:18.

                Comment


                  #9
                  You don't make it work with optionDataSource, you make it work by *removing* optionDataSource and calling DataSource.fetchData() directly, followed by setValueMap(). Take a second look at SiccoNaets code and follow it closely.

                  Comment


                    #10
                    You are talking about overriding the fetchData method on the datasource,
                    not the optiondatasource, where the dynamic values come from to be displayed in the comboboxItem ?

                    This is not working for me. No Any is added to the drop down list.

                    Do you have an idea why this happens and how to solve it?
                    Is it maybe because of the used setCellFormatter like in the smartGWT example

                    Comment


                      #11
                      No, we said nothing about overriding fetchData on the DataSource.

                      Please go over previous responses very very carefully. Again, just to be really explicit:

                      1. stop using optionDataSource for this use case

                      2. call (do *not* override) DataSource.fetchData() and use the callback to create and set a valueMap on the item. See SiccoNaets code example

                      Comment


                        #12
                        Hi,
                        Thanks for reply.

                        I am not using optionDataSource in the Java-code, but in the ds.xml .
                        I am also not overriding the fetchData method, but the execute method within like in SiccoNaets code.
                        So your suggestion is, not to use optionDataSource in the ds.xml on this form item?

                        Comment


                          #13
                          Right, stop using optionDataSource for this case.

                          Comment


                            #14
                            I get the same problem with a simpler code:
                            Code:
                            ListGridField code = new ListGridField("code");
                                    code.setAutoFitWidth(true);
                                    ListGridField status = new ListGridField("status");
                                    status.setAutoFitWidth(true);
                            
                                    SelectItem item = new SelectItem(statusone);
                                    item.setPickListFields(status, code);
                                    item.setPickListWidth(520);
                                    item.setPickListHeaderHeight(0);
                                    item.setAllowEmptyValue(true);
                                    item.setEmptyDisplayValue("All");
                                    item.setOptionCriteria(new Criterion("statusid", OperatorId.EQUALS, 10));
                            So, the space for the displayvalue is there, but the All will not be part of the dropdown-box.

                            Can this be fixed by you?

                            Comment


                              #15
                              Just to be sure we are clear: In this latest example you have a SelectItem, bound to an optionDataSource [presumably handled through the DataSource field definition, either in Java or in the .ds.xml file], and you have 'allowEmptyValue' set to true, and an emptyDisplayValue set.
                              And the bug is that while an empty option is present in the drop down list of options, it doesn't show the empty display value - right?

                              The issue here is that you have explicitly specified PickList fields for this item. In this case the system does not attempt to guess which field should show the empty display value for the special empty record at the top of the drop down - they're all left unset.
                              To make this work you can call 'setEmptyCellValue("All")' on the ListGridField you want the empty display value to show up in.

                              Comment

                              Working...
                              X