PDA

View Full Version : combo box doesn't display items



giovanni.puliti
1 Feb 2010, 9:44 AM
hi all


i'm using GXT 2.1.0 and trying to show some values in a combobox. When i'm adding some simple text values like this:



evrything is ok, item are showed correctly.
When i use a listStore to load some more structured data, the combo box appear blank (no values showed, even if in the combo are 4 rows). Look a the attacched image for more detail.

this is the code




ComboBox typesCombo = new ComboBox();
typesCombo.setEmptyText("Seleziona tipo di corso...");

final ListStore<CourseType> courseTypesStore = new ListStore<CourseType>();
ArrayList<CourseType> courseTypesList = new ArrayList();

courseTypesList.add(new CourseType("first",1));
courseTypesList.add(new CourseType("second",2));
courseTypesList.add(new CourseType("third 2",3));
courseTypesList.add(new CourseType("fourth",4));
courseTypesStore.add(courseTypesList);

typesCombo.setStore(courseTypesStore);
typesCombo.setFieldLabel("Elements");
typesCombo.setDisplayField("typeName");



type name is the value i was trying to show. Is an attribute of the class CourseType used as a model: here there is the code:



public class CourseType extends BaseModel{

private String typeName;
private Integer typeValue;

public CourseType(){}

public CourseType(String name, Integer value) {
super();
this.typeName = name;
this.typeValue = value;
}

public String getTypeName() {
return typeName;
}

public void setTypeName(String typeName) {
this.typeName = typeName;
}

public Integer getTypeValue() {
return typeValue;
}

public void setTypeValue(Integer typeValue) {
this.typeValue = typeValue;
}
}




if i print the store dimension, it get me back = 4... that's ok.
what the hell i need to do to show this 4 items?

me2
1 Feb 2010, 11:21 AM
The CourseType class needs a tweak - see below:


public class CourseType extends BaseModel{

private String typeName;
private Integer typeValue;

public CourseType(){}

public CourseType(String name, Integer value) {
super();

setTypeName(name);
setTypeValue(value);
}

public String getTypeName() {
return typeName;
}

public void setTypeName(String typeName) {
this.typeName = typeName;
set("typeName", typeName);
}

public Integer getTypeValue() {
return typeValue;
}

public void setTypeValue(Integer typeValue) {
this.typeValue = typeValue;
set("typeValue", typeValue);
}
}



That should get you in the right direction...

ejmenendez
2 Mar 2010, 4:51 AM
I have the same problem, my model (ModeloDatoCombo) extends BaseModelData and I call the set method on every ocasion, but still I get the combo list without text.


public class ModeloDatoCombo extends BaseModelData{

/**
*
*/
private static final long serialVersionUID = 1690468797424147454L;


public ModeloDatoCombo(){}

/**
* Constructor con un solo key-value en dos String
*
* @param key
* @param value
*/
public ModeloDatoCombo(String key, String value)
{
super();
this.set(key, value);
}

/**
* Agrega un mapa al modelo de dato separándolo por pares key - value
*
* @param record Un mapa key - value
*/

public ModeloDatoCombo(LinkedHashMap<String, String> record)
{
Set<String> campos = record.keySet();
Iterator<String> ite = campos.iterator();
while(ite.hasNext())
{
String key = ite.next();
String value = record.get(key);
this.agregar(key, value);
}
}

/**
* Devuelve un valor correspondiente a la clave enviada
*
* @param key la clave del campo
* @return String el valor del campo
*/
public String dame(String key)
{
return this.get(key);
}


/**
* Agrega un nuevo par key - value a los ya existentes
*
* @param key El nombre del campo
* @param value El valor del campo
*/
public void agregar(String key, String value)
{
this.set(key, value);
}


@Override
public String toString()
{
return this.getProperties().toString();
}

Any news on this subject?
thanks

sven
2 Mar 2010, 5:30 AM
ejmenendez - Can you please post a fully working testcase for this?

ejmenendez
2 Mar 2010, 5:43 AM
Sven: ok, just let me do the code and will upload ASAP. There's one post from me referring to this subject with the relevant - or was, I can't seem to find it now, but I'll assemble one simple referred to the problem.

Thanks for your time.

ejmenendez
2 Mar 2010, 6:34 AM
Sorry - found the thread:
http://www.extjs.com/forum/showthread.php?t=93051

still will set up a working example, but maybe there's something you can see there, since I'm stuck. As there a re many classes in my project, it will take me some time to set up a correct test.
Again, thanks.

ejmenendez
9 Mar 2010, 5:22 AM
Working example:

Class 1 - entry point class


/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class Foro2 implements EntryPoint {

// this combo has "fixed" options
M_ComboBox combo1 = new M_ComboBox();
// this combo will wait for the first to populate options from database. empty store to prevent exception
M_ComboBox combo2 = new M_ComboBox();


@Override
public void onModuleLoad()
{
Window w = new Window();

// manually add options to combo1
combo1.setClavesRegistro("label", "value");

for(int x = 0; x < 5; x++)
{
combo1.setValoresRegistro("Option "+x, String.valueOf(x));
}

combo1.cargarRegistros("label", "value");
combo1.setTriggerAction(TriggerAction.ALL);

// combo 2 with empty store
ListStore<ModeloDatoCombo> store = new ListStore<ModeloDatoCombo>();
combo2.setStore(store);
combo2.setEnabled(false);

// listener to combo 1 to affect combo 2
combo1.addListener(Events.SelectionChange, new Listener<SelectionChangedEvent<ModeloDatoCombo>>() {
@Override
public void handleEvent(SelectionChangedEvent<ModeloDatoCombo> be)
{
// string with the value of combo1 selected item
String valor = be.getSelectedItem().dame("value");
LinkedHashMap<String, LinkedHashMap<String, String>> mapa = new LinkedHashMap<String, LinkedHashMap<String,String>>();
LinkedHashMap<String, String> record1 = new LinkedHashMap<String, String>();
record1.put("etiq", "opción seleccionada "+valor);
record1.put("valor", "1");

LinkedHashMap<String, String> record2 = new LinkedHashMap<String, String>();
record1.put("etiq", "opción seleccionada "+valor);
record1.put("valor", "2");

mapa.put("1", record1);
mapa.put("2", record2);

combo2.setMapa(mapa, "valor", "etiq");


}
});

w.add(combo1);
w.add(combo2);
w.show();
}

}

Class 2 - Extends ComboBox


public class M_ComboBox extends ComboBox<ModeloDatoCombo> {

private String selectedLabel;
private String selectedItem;

private String key;
private String valor;


private String[] clavesRegistro;
private LinkedHashMap<String, LinkedHashMap<String, String>> registro;

private String mapaClave, mapaValor;

private boolean datosCargados = false;

/**
* Constructor vacío
*/
public M_ComboBox()
{
super();
}

/**
*
* @param mapa Con la estructura de record que devuelve el servicio de base de datos
* @param displayField El campo a mostrar como opción en el combo
* @param key El nombre del campo que va a devolver el combo en la selección
*/

public M_ComboBox(LinkedHashMap<String,LinkedHashMap<String, String>> mapa, String displayField, final String key)
{
super();
this.setMapa(mapa, displayField, key);
this.setTriggerAction(TriggerAction.ALL);
this.loadListeners();
}


/**
* Agrega un listener al combobox para el evento Events.SelectionChange
* Almacena los valores para recuperar con:
* getSelectedItem() - el valor del ítem seleccionado
* getSelectedLabel() - la etiqueta del valor seleccionado.
*
*/
private void loadListeners ()
{
this.addListener(Events.SelectionChange, new Listener<SelectionChangedEvent<ModeloDatoCombo>>()
{

@Override
public void handleEvent(SelectionChangedEvent<ModeloDatoCombo> be)
{
String valor = be.getSelectedItem().dame(getKey());
String dField = be.getSelectedItem().dame(mapaValor);
setSelectedItem(valor);
setSelectedLabel(dField);
}
});
}

/**
*
* @return El valor del campo 'key' del item seleccionado
*/
public String getSelectedItem()
{
return this.selectedItem;
}

/**
*
* @param selectedItem
*/
public void setSelectedItem(String selectedItem)
{
this.selectedItem = selectedItem;
}

/**
*
* @return El nombre del campo 'key' que define el campo que el combo devuelve como valor en el evento onChange
*/
public String getKey()
{
return this.key;
}

/**
* Setea los campos claves para armar el registro.
* @param keys
*/
public void setClavesRegistro(String... keys) {
this.clavesRegistro = keys;
}

/**
*
* @param values
*/
public void setValoresRegistro(String... values)
{
if(this.clavesRegistro != null) {

if(this.registro == null)
{
this.registro = new LinkedHashMap<String, LinkedHashMap<String,String>>();
}

int largo = this.registro.size();

LinkedHashMap<String, String> record = new LinkedHashMap<String, String>();
int x = 0;
for(String elem : this.clavesRegistro){
record.put(elem, values[x]);
x++;
}

this.registro.put(String.valueOf(largo), record);
}

}

/**
* Carga registro a registro los valores para el combo
* @param displayField - El campo a mostrar
* @param lkey - el valor a devolver
*/
public void cargarRegistros(String displayField, String lkey)
{
setMapaClave(displayField);
setMapaValor(lkey);

setMapa(this.registro, displayField, lkey);
}

/**
* Carga un store de acuerdo a un mapa, si el combo no tiene store lo setea y si ya tiene store lo modifica
*
* @param records - LinkedHashMap con la misma estructura que devuelve el servicio de base de datos,
* <String (clave o nro de registro), LinkedHashMap<String, String> (record mapeado nombre de campo - valor)
*
* @param displayField Lo que muestra el combo como opción
* @param key Nombre del campo del modelo de datos cuyo valor que devuelve el combo en la seleccion
*
*/
public void setMapa(LinkedHashMap<String, LinkedHashMap<String, String>> records, String key, String displayField)
{
this.key = key;
// si no esta vacio el store quiere decir q tengo q renovarlo
if((this.getStore() != null))
{
// para el store nuevo
List<ModeloDatoCombo> listaModif = new ArrayList<ModeloDatoCombo>();

// lo que entra por records lo itero y lo agrego en el store nuevo
Set<String> idRecord = records.keySet();
Iterator<String> ite = idRecord.iterator();

while(ite.hasNext())
{
ModeloDatoCombo aux = new ModeloDatoCombo(records.get(ite.next()));
listaModif.add(aux);
}

// saco todo del store actual y lo reemplazo por el store nuevo
this.getStore().removeAll();
this.getStore().add(listaModif);
//this.getStore().update(listaModif);

this.getListView().refresh();
//this.getView().refresh();
this.setDisplayField(displayField);
this.setEnabled(true);

} else {

// el store esta vacio
Set<String> idRecord = records.keySet();
Iterator<String> ite = idRecord.iterator();

ListStore<ModeloDatoCombo> lista = new ListStore<ModeloDatoCombo>();

while(ite.hasNext())
{
lista.add(new ModeloDatoCombo(records.get(ite.next())));
}

// cargo el store del combobox
this.setStore(lista);

}

this.setEmptyText("Elija una opción...");
this.setEditable(false);
this.setDisplayField(displayField);

loadListeners();
}


public void setMapaClave(String mapaClave) {
this.mapaClave = mapaClave;
}

public void setMapaValor(String mapaValor) {
this.mapaValor = mapaValor;
}

public boolean isDatosCargados()
{
return datosCargados;
}


/**
* Para devolver el texto de la opción elegida
* @param etiqValor la etiqueta del valor que se quiere recuperar
* @return
*/
public String getValor(String etiqValor)
{
return this.value.dame(etiqValor);
}


public String getSelectedLabel()
{
return selectedLabel;
}

public void setSelectedLabel(String selectedLabel)
{
this.selectedLabel = selectedLabel;
}

public String getValor()
{
return valor;
}

public void setValor(String valor)
{
this.valor = valor;
}

}
Class 3 extends BaseModelData, used for data modelling


public class ModeloDatoCombo extends BaseModelData{

/**
*
*/
private static final long serialVersionUID = 1690468797424147454L;


public ModeloDatoCombo(){}

/**
* Constructor con un solo key-value en dos String
*
* @param key
* @param value
*/
public ModeloDatoCombo(String key, String value)
{
super();
this.set(key, value);
}

/**
* Agrega un mapa al modelo de dato separándolo por pares key - value
*
* @param record Un mapa key - value
*/

public ModeloDatoCombo(LinkedHashMap<String, String> record)
{
Set<String> campos = record.keySet();
Iterator<String> ite = campos.iterator();
while(ite.hasNext())
{
String key = ite.next();
String value = record.get(key);
this.agregar(key, value);
}
}

/**
* Devuelve un valor correspondiente a la clave enviada
*
* @param key la clave del campo
* @return String el valor del campo
*/
public String dame(String key)
{
return this.get(key);
}


/**
* Agrega un nuevo par key - value a los ya existentes
*
* @param key El nombre del campo
* @param value El valor del campo
*/
public void agregar(String key, String value)
{
this.set(key, value);
}


@Override
public String toString()
{
return this.getProperties().toString();
}


}I think the problem is when you refresh the store by removing all the existing items - even if it's a empty store - and adding a list later.
The data is stored OK, but the text is not displayed.
Any help will be appreciated.
Thank you

sven
9 Mar 2010, 5:30 AM
Is it possible that you change the name of the displayfield? This is not possible once the list got rendered the first time.

ejmenendez
9 Mar 2010, 6:35 AM
Sven, that was just the cause, when assigning the empty store I din't specify a displayField. I did it when getting data from rpc, but had no idea that displayfield couldn't be specified after rendering. Now it works just fine, thanks a lot, have been a long time looking for the mistake. Thanks a lot, really
Esteban