Announcement

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

    Adding extra options to a comboBox/selectItem

    Hi,

    well, this one has been giving me a lot of headache. I have a dropdown that shows a list of accounts from a dataSource. The dropdown is used repeatedly throughout the entire application - in some cases as a means of data-entry (i.e. assign this record to account x); in some cases as a filter (i.e. find all records belonging to account x).

    Now, in some of these drop-downs, I want to inject extra values; values like "Any" or "Unassigned". I've been experimenting with different techniques to make this happen, and I don't particularly like any of the solutions I've come up with.

    The best solution I found was to not back the dropdown directly with a datasource; but instead query the dataSource directly, get it to return all the results in a callback, store the results in a hashMap, add any extra entries I need and then use the hashMap as a value map for the dropdown. I.e.; like so:



    Code:
    DataSource accountDS = DataSource.get("account");
    
    ComboBoxItem account = new ComboBoxItem("account");
    account.setTitle("Account");
    
    public void populateAccounts()
    {
      accountDS.fetchData(new Criteria(), new AccountCallback());
    
    }
    
    
    
    private class AccountCallback implements DSCallback
    		{
    			@Override
    			public void execute(DSResponse response, Object rawData,
    					DSRequest request) 
    			{
    				LinkedHashMap<Serializable,String> valueMap = new LinkedHashMap<Serializable,String>();
    				valueMap.put("Any", "Any");
    				Record[] results = response.getData();
    				Log.debug("Found " + results.length + " accounts.");
    				
    				for(Record result : results)
    				{
    					valueMap.put(result.getAttributeAsInt("accountId", result.getAttribute("accountName"));
    				}
    				
    				account.setValueMap(valueMap);
    			}
    		}
    This works fine; but has performance problems - the dataSource of course has to return all results and I have the impression that the SmartGWT marshalling/unmarshalling code for translating java objects into dataSource responses doesn't handle large resultsets very well. From testing, I can tell my dataSource runs the actual query in 120 miliseconds; but somewhere between when I do dsResponse.setData(results) and when the callback happens, 4.5 seconds are lost. It's a very noticeable and very irritating delay in loading the interface; especially when the account dropdown has to be reloaded or when there's more than one dropdown that needs this type of logic on a page.

    The other solution is a bit of a hack - it works from a functional and performance point of view, but I don't like the code behind the solution - it's messy.

    This solution consists of binding the comboBoxItem directly to the dataSource; and having it ask the dataSource for extra "fake" items by passing data through the criteria. Like so:

    Code:
    DataSource accountDS = DataSource.get("account");
    
    ComboBoxItem account = new ComboBoxItem("account"){
    
    @Override
    protected Criteria getPickListCriteria()
    {
    Criteria criteria = new Criteria();
    criteria.add("extraOptionValues", new Integer[]{-1,-2});
    criteria.add("extraOptions", new String[]{"Any","Unassigned"};
    return criteria;
    
    }
    
    };
    account.setTitle("Account");
    account.setValueField("accountId");
    account.setDisplayField("accountName");
    The code for the dataSource then retrieves the extraOptionValues and extraOptions arrays, creates "fake" accounts populated with those values before returning them as part of the query. Because dropdowns and selectItems ask for dataSource results in slices, you also need to recalculate the total resultset size and what to actually query for. For instance, let's say I have 3000 accounts and I want two extra options. I now have to tell SmartGWT that there's actually 3002 accounts, insert the fake ones, then recalculate what to query for (SmartGWT asks for 0-75, so I need to give it 0-73), etc.

    I have the code for this, it works and it's peformant (since I'm not returning entire resultsets) but it's messy and a LOT of extra work for something so basic.

    Is there a third way that I'm missing? Both of these seem awfully complicated for a pretty basic requirement...

    #2
    ComboBoxItem adding extra records manually

    Hello.
    I am looking for exactly the same functionality.
    Like SiccoNaets has said, is there a way to do this without recurring to any special handling as was described in the post above?

    using:
    SmartGWT 3.1-p20130707

    Comment


      #3
      The approach above is still the correct approach. It's less complicated of course if you don't need paging. Also, there's always the possibility of adding buttons or other separate controls for special values. If you're interested in some kind of framework-level support for that would simplify adding non-data values, consider Feature Sponsorship.

      Comment


        #4
        there is a feature for that after all...

        For those wondering, this ended up being the approach I followed:

        Code:
        DataSource.getDataSource("myDs", null, new ResponseTransformer () {...})
        the ResponseTransformer allows you to modify the data returned from the DS, as needed.

        Comment

        Working...
        X