Como popular um ExtJS ComboBox usando um Spring Controller

14 Jun 2010
3 mins read

Para popular/carregar um ExtJS ComboBox usando  um Controller Spring, é necessário criar um request em Ajax usando Ext.data.HttpProxy e como response/resposta do server, você pode retornar um objeto JSON (ou um XML – neste exemplo, vou usar JSON, mas funcionar da memsa maneira que XML). Usando um JsonReader (ou XMLReader), pode-se ler os valores dos erver e popular o ComboBox. É a mesma lógica utilizada para popular um ExtJS DataGrid.

Frameworks/Bibliotecas que estou usando nesse tutorial:

Se você estiver usando Spring 2.5, pode conferir outros exemplo de como popular um JSONStore other examples e retornar JSON do Spring JSON from Spring using Spring-JSON lib.

Neste exemplo, vamos criar um combobox para listar todos os estados brasileiros. O screenshot pode ser conferido na figura abaixo:

O primeiro passo é crier um POJO (Objeto java com constructor e métodos getters e setters dos atributos):

[code lang="java" firstline="1" toolbar="true" collapse="false" wraplines="false"]
public class State {

private String code;
private String name;

public State(String code, String name) {
super();
this.code = code;
this.name = name;
}

//get and set methods
}
[/code]

Abaixo segue o Controller. O request está mapeado no método loadStates(), que busca/seleciona os estados de um repositório de dados (Estou usando apenas um método por motivos acadêmicos (e portabilidade, sem precisar instalar banco de dados, etc, porém, você pode buscar essas informações de um banco de dados):

[code lang="java" firstline="1" toolbar="true" collapse="false" wraplines="false"]
@Controller
public class StateController {

private StateService stateService;

@RequestMapping(value="getStates.json", method = RequestMethod.GET)
public @ResponseBody Map<String,? extends Object> loadStates() {

HashMap<String, List<State>> modelMap = new HashMap<String,List<State>>();
modelMap.put("states", stateService.getBrazilianStates());

return modelMap;
}

@Autowired
public void setStateService(StateService stateService) {
this.stateService = stateService;
}
}
[/code]

A anotação @ResponseBody converte automaticamento o objeto Map em um objeto JSON, por causa do framework Jackson. Você pode ver mais sobre as simplificações Ajax do Spring 3 neste link. E este é o objeto JSON que foi retornado do método loadStates para o browser:

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
{"states":[{"name":"Acre","code":"AC"},{"name":"Alagoas","code":"AL"},{"name":"Amapá","code":"AP"},{"name":"Amazonas","code":"AM"},{"name":"Bahia","code":"BA"},{"name":"Ceará","code":"CE"},{"name":"Distrito Federal","code":"DF"},{"name":"Espírito Santo","code":"ES"},{"name":"Goiás","code":"GO"},{"name":"Maranhão","code":"MA"},{"name":"Mato Grosso","code":"MT"},{"name":"Mato Grosso do Sul","code":"MS"},{"name":"Minas Gerais","code":"MG"},{"name":"Pará","code":"PA"},{"name":"Paraíba","code":"PB"},{"name":"Paraná","code":"PR"},{"name":"Pernambuco","code":"PE"},{"name":"Piauí","code":"PI"},{"name":"Rio de Janeiro","code":"RJ"},{"name":"Rio Grande do Norte","code":"RN"},{"name":"Rio Grande do Sul","code":"RS"},{"name":"Rondônia","code":"RO"},{"name":"Roraima","code":"RR"},{"name":"Santa Catarina","code":"SC"},{"name":"São Paulo","code":"SP"},{"name":"Sergipe","code":"SE"},{"name":"Tocantins","code":"TO"}]}
[/code]

E o conteúdo acima foi retornado por um método da classe StateService (neste caso, meu repositório de dados):

[code lang="java" firstline="1" toolbar="true" collapse="false" wraplines="false"]
@Service
public class StateService {

public List<State> getBrazilianStates(){

List<State> states = new ArrayList<State>();

states.add(new State("AC","Acre"));
states.add(new State("AL","Alagoas"));
states.add(new State("AP","Amapá"));
states.add(new State("AM","Amazonas"));
states.add(new State("BA","Bahia"));
states.add(new State("CE","Ceará"));
states.add(new State("DF","Distrito Federal"));
states.add(new State("ES","Espírito Santo"));
states.add(new State("GO","Goiás"));
states.add(new State("MA","Maranhão"));
states.add(new State("MT","Mato Grosso"));
states.add(new State("MS","Mato Grosso do Sul"));
states.add(new State("MG","Minas Gerais"));
states.add(new State("PA","Pará"));
states.add(new State("PB","Paraíba"));
states.add(new State("PR","Paraná"));
states.add(new State("PE","Pernambuco"));
states.add(new State("PI","Piauí"));
states.add(new State("RJ","Rio de Janeiro"));
states.add(new State("RN","Rio Grande do Norte"));
states.add(new State("RS","Rio Grande do Sul"));
states.add(new State("RO","Rondônia"));
states.add(new State("RR","Roraima"));
states.add(new State("SC","Santa Catarina"));
states.add(new State("SP","São Paulo"));
states.add(new State("SE","Sergipe"));
states.add(new State("TO","Tocantins"));

return states;
}
}
[/code]

E finalmente, o código ExtJS com a declaração do reader e do comboBox:

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
Ext.onReady(function(){

var store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: 'getStates.json'
}),
reader: new Ext.data.JsonReader({
root:'states'
},
[{name: 'code'},
{name: 'name'}
])
});

var combo = new Ext.form.ComboBox({
id: 'statesCombo',
store: store,
displayField: 'name',
valueField: 'code',
hiddenName : 'codeId',
typeAhead: true,
mode: 'local',
fieldLabel: 'States of Brazil',
anchor: '100%',
forceSelection: true,
triggerAction: 'all',
emptyText:'Select a state...',
selectOnFocus:true
});

var stateForm = new Ext.FormPanel({
frame:true,
url: 'saveState.json',
title: 'Combo Box Example',
bodyStyle:'padding:5px 5px 0',
width: 250,
labelAlign: 'top',
layout: 'form',
items: [combo]
});

store.load();

stateForm.render(document.body);

});
[/code]

Você pode fazer o download do projeto complete (incluindo todos os jars e arquivos ExtJS nencessários) do meu repositório do GitHub: http://github.com/loiane/extjs-combobox
Este projeto foi desenvolvido no Eclipse e usei o TomCat como webserver.

Bons códigos!