View Full Version : Linked Combos Question

6 Nov 2009, 6:15 AM
I've implemented a solution for linked combo boxes by replacing the data store of the dependent combo within the SelectionChangedListener for the first combo (code below).

For reading about the store.filter functionality I was hoping to load all the data into the dependent combo and filter it with the key from the selected combo. I debugged using the filter method a bit to see that the filter function seems to be performing normally; but during the combo query operation to display it's data, filters are cleared. I've tried setting the trigger action to QUERY rather than ALL; but no help.

So my question is how can I use the ListStore.filter functionality to get the dependent combo to show the correct slice on the data its holding.


package com.chordiant.cxconstraint.client;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.chordiant.cxconstraint.remote.model.ConstrainedResource;
import com.chordiant.cxconstraint.remote.model.ConstrainedResourceDataModel;
import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.data.BaseTreeModel;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.FieldEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.RowEditorEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.StoreFilter;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonBar;
import com.extjs.gxt.ui.client.widget.form.CheckBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.form.LabelField;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.Validator;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.RowEditor;
import com.extjs.gxt.ui.client.widget.layout.AnchorLayout;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGrid;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGridCellRenderer;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;

* Entry point classes define <code>onModuleLoad()</code>.
public class Cxconstraint_web_app implements EntryPoint
private static final String KEY = "KEY";
private static final String ID = "ID";
private static final String NAME = "NAME";

* Populate values for headings, labels, etc. from .properties files
private ConstraintMgtConstants constants = GWT.create( ConstraintMgtConstants.class );

private static final String NAME_COLUMN = "name";
private static final String HAS_CONSTRAINT_COLUMN = "hasConstraint";
private static final String CONSTRAINT_VALUE_COLUMN = "constraintValue";

ContentPanel titlePanel = new ContentPanel();
ContentPanel treePanel = new ContentPanel();

final ComboBox< BaseModel > deCB = new ComboBox< BaseModel >();
final ComboBox< BaseModel > rtpCB = new ComboBox< BaseModel >();
final ListStore< BaseModel > deStore = new ListStore< BaseModel >();
final ListStore< BaseModel > rtpStore = new ListStore< BaseModel >();

private Map< String, List< BaseModel > >
keyMap = new HashMap< String, List< BaseModel > >();

private ConstrainedResourceDataModel dataModel;
private TreeStore<ModelData> store = new TreeStore<ModelData>();

private HashMap<String, List<ConstrainedResource>> resourceMap = new HashMap<String, List<ConstrainedResource>>();
private List<ConstrainedResource> constrainedResourcesList = new ArrayList<ConstrainedResource>(0);

final HTML serverResponseLabel = new HTML();
final HTML BR = new HTML( "<br/>" );

* Cxconstraint web app module entry point
public void onModuleLoad()
Viewport view = new Viewport();
view.setLayout( new AnchorLayout() );

serverResponseLabel.setHTML( "<br/>" );

titlePanel.setHeading( constants.pageTitle() );
titlePanel.addText( constants.deLabel() );
titlePanel.add( deCB );
titlePanel.addText( constants.rtpLabel() );
titlePanel.add( rtpCB );
titlePanel.add( BR );

titlePanel.addText( constants.instructionText() );
view.add( titlePanel );

RootPanel.get().add( view );


private void initializeComboBoxes()
// DataStores for DEs & RTPs (DEs map to RTPs)
String key, tag = "_KEY_";
int deIx = 0;
List< String > deList = getDeploymentEnvironments();
for( String de : deList )
key = de + tag + deIx++;
BaseModel deBM = new BaseModel();
deBM.setAllowNestedValues( false );
deBM.set( KEY, key );
deBM.set( ID, "DEIDVal" ); // TODO repl w/ actual value
deBM.set( NAME, de );
deStore.add( deBM );

// Here just keep the models in a list which is switched
// during a deCB selection changed. Filtering didn't work.
List< String > rtpList = getRealtimeProjects( de );
List< BaseModel > listBM = new ArrayList< BaseModel >();
for( String rtp : rtpList )
BaseModel rtpBM = new BaseModel();
rtpBM.setAllowNestedValues( false );
rtpBM.set( KEY, key );
rtpBM.set( ID, "RTPIDVal" ); // TODO repl w/ actual value
rtpBM.set( NAME, rtp );
listBM.add( rtpBM );
keyMap.put( key, listBM );

// Init ComboBoxes
// Deployment Environment
deCB.setEmptyText( constants.deEmptyText() );
deCB.setWidth( 300 );
deCB.setStore( deStore );
deCB.setDisplayField( NAME );
deCB.setValueField( KEY );
deCB.setForceSelection( true );

// Real-time project
rtpCB.setEmptyText( constants.rtpEmptyText() );
rtpCB.setWidth( 300 );
rtpCB.setStore( rtpStore );
rtpCB.setDisplayField( NAME );
rtpCB.setValueField( KEY );
rtpCB.setForceSelection( true );

// On Selection Changes, reset rtpCB and load key-mapped list of
// BaseModels. Should be able to load them all and just filter; but
// that's not working currently.
new SelectionChangedListener< BaseModel >()
public void selectionChanged( SelectionChangedEvent< BaseModel > sce )
rtpCB.setValue( null );
BaseModel selectedDE = sce.getSelectedItem();
String keyVal = selectedDE.get( KEY );
rtpCB.getStore().add( keyMap.get( keyVal ) );

private List< String > getDeploymentEnvironments()
List< String > testData = new ArrayList< String >();
testData.add( "dma64db" );
testData.add( "cxmdb" );
testData.add( "cxmperf" );
testData.add( "cxmint" );
return testData;

private List< String > getRealtimeProjects( String de )
List< String > testRTPs = new ArrayList< String >();
for( int i=0; i<3; i++ )
testRTPs.add( de + "_RTP" + i );
return testRTPs;