ExtJS e Spring Framework: Exemplo de um CRUD Grid
Este tutorial demonstra como implementar um CRUD Grid (Create, Read, Update, Delete) usando ExtJS e Spring Framework

O que geralmente queremos fazer com os dados
- Create (Criar) – (Insert)
- Read (Ler/Visualizar) – (Select)
- Update (Atualizar) – (Update)
- Delete (Deletar) – (Delete)
Até a versão 3.0 do ExtJS, podíamos apenas LER dados utilizando o componente dataGrid. Se você quisesse fazer um update, insert ou delete, você tinha que codificar funções específicas para essas ações no lado ExtJS. Com a versão 3.0 (e versões mais recentes) do ExtJS, a biblioteca javascript introduziu o ext.data.writer, e você não tem todo aquele trabalho de criar as funções específicas, pode utilizar o Writer para ter um CRUD Grid.
Mas o que é preciso para ter todas as funcionalidades funcionando apenas com o uso desse writer?
No exemplo desse tutorial, estou usando JSON como formato de dados para troca de informações entre brwoser e servidor.
Primeiro, é preciso criar um Ext.data.JsonWriter:
2 | var writer = new Ext.data.JsonWriter({ |
Onde writeAllFields significa que queremos enviar todos os campos do registro para o banco de dados. identifies that we want to write all the fields from the record to the database. Se você tem uma estrutura de dados um pouco complicada ou o usuário irá fazer muitas iterações de update, é melhor deixar setado como false.
Por exemplo, Essa é a declaração da minha estrutura de dados no ExtJS:
01 | var Contact = Ext.data.Record.create([ |
Se eu apenas atualizar o nome do contato, a aplicação irá apenas enviar o nome do contato e a id do mesmo para o servidor dizendo que foi atualizado (se o campo writeallfields estiver como false). Se tiver setado como true, irá enviar todos os campos, e o trabalho para descobrir o que sofreu alteração ficará para o server.
Agora, é necessário configurar o proxy, como esse:
1 | var proxy = new Ext.data.HttpProxy({ |
3 | read : 'contact/view.action' , |
4 | create : 'contact/create.action' , |
5 | update: 'contact/update.action' , |
6 | destroy: 'contact/delete.action' |
E só para constar, é assim que meu reader se parece:
1 | var reader = new Ext.data.JsonReader({ |
2 | totalProperty: 'total' , |
3 | successProperty: 'success' , |
6 | messageProperty: 'message' |
O próximo passo é juntat tudo (writer, proxy e reader) no objeto store:
2 | var store = new Ext.data.Store({ |
O autosave significa que deseja salvar as alterações automaticamente no servidor (não precisa de um botão salvar na tela, assim que o usuário atualizar, deleter ou criar um novo dado, será enviado automaticamente para o servidor). Para este exemplo, implementei um botão salvar, assim, qualquer registro ou dado que for adicionado ou alterado terá uma marcação vermelha (no canto superior esquerdo da célula), assim quando o evento (ou botão) salvar for disparado, serão enviados para o servidor os dados que sofreram alteração (marcados com o flag vermelho). Você pode fazer múltiplos updates e enviar todos para o servidor em apenas uma vez (Observe como isso foi tratado no código da classe de serviço no código fonte desse projeto).
E para deixar a vida ainda mais fácil (afinal, pra isso que usamos bibliotecas como ExtJS
), vamos usar o plugin RowEditor, que permite a edição dos dados de forma muito simples. Tudo o que precisa fazer para usar esse plugin é primeiro adicionar os arquivos necessários na sua página HTML (ou JSP, ou outra extensão!):
2 | < link rel = "stylesheet" type = "text/css" href = "/extjs-crud-grid/ext-3.1.1/examples/ux/css/rowEditorCustom.css" /> |
3 | < link rel = "stylesheet" type = "text/css" href = "/extjs-crud-grid/ext-3.1.1/examples/shared/examples.css" /> |
4 | < link rel = "stylesheet" type = "text/css" href = "/extjs-crud-grid/ext-3.1.1/examples/ux/css/RowEditor.css" /> |
7 | < script src = "/extjs-crud-grid/ext-3.1.1/examples/ux/RowEditor.js" >script > |
E adicionar o plugin na declaração do grid:
01 | var editor = new Ext.ux.grid.RowEditor({ |
06 | var grid = new Ext.grid.GridPanel({ |
36 | dataIndex: 'birthday' , |
37 | renderer: Ext.util.Format.dateRenderer( 'm/d/Y' ), |
38 | editor: new Ext.form.DateField ({ |
41 | maxValue: ( new Date()) |
50 | iconCls: 'icon-user-add' , |
55 | phone: '(000) 000-0000' , |
56 | email: 'new@loianetest.com' , |
57 | birthday: '01/01/2000' |
61 | grid.getView().refresh(); |
62 | grid.getSelectionModel().selectRow(0); |
63 | editor.startEditing(0); |
66 | iconCls: 'icon-user-delete' , |
67 | text: 'Remove Contact' , |
70 | var s = grid.getSelectionModel().getSelections(); |
71 | for ( var i = 0, r; r = s[i]; i++){ |
76 | iconCls: 'icon-user-save' , |
77 | text: 'Save All Modifications' , |
E Finalmente, precisamos de código no lado servidor. O Controller que implementei ficou assim:
001 | package com.loiane.web; |
003 | import java.util.HashMap; |
004 | import java.util.List; |
007 | import javax.servlet.http.HttpServletRequest; |
008 | import javax.servlet.http.HttpServletResponse; |
010 | import org.springframework.web.servlet.ModelAndView; |
011 | import org.springframework.web.servlet.mvc.multiaction.MultiActionController; |
013 | import com.loiane.model.Contact; |
014 | import com.loiane.service.ContactService; |
016 | public class ContactController extends MultiActionController { |
018 | private ContactService contactService; |
020 | public ModelAndView view(HttpServletRequest request, |
021 | HttpServletResponse response) throws Exception { |
025 | List contacts = contactService.getContactList(); |
027 | return getModelMap(contacts); |
029 | } catch (Exception e) { |
031 | return getModelMapError( "Error trying to retrieve contacts." ); |
035 | public ModelAndView create(HttpServletRequest request, |
036 | HttpServletResponse response) throws Exception { |
040 | Object data = request.getParameter( "data" ); |
042 | List contacts = contactService.create(data); |
044 | return getModelMap(contacts); |
046 | } catch (Exception e) { |
048 | return getModelMapError( "Error trying to create contact." ); |
052 | public ModelAndView update(HttpServletRequest request, |
053 | HttpServletResponse response) throws Exception { |
056 | Object data = request.getParameter( "data" ); |
058 | List contacts = contactService.update(data); |
060 | return getModelMap(contacts); |
062 | } catch (Exception e) { |
064 | return getModelMapError( "Error trying to update contact." ); |
068 | public ModelAndView delete(HttpServletRequest request, |
069 | HttpServletResponse response) throws Exception { |
073 | String data = request.getParameter( "data" ); |
075 | contactService.delete(data); |
077 | Map modelMap = new HashMap( 3 ); |
078 | modelMap.put( "success" , true ); |
080 | return new ModelAndView( "jsonView" , modelMap); |
082 | } catch (Exception e) { |
084 | return getModelMapError( "Error trying to delete contact." ); |
089 | * Generates modelMap to return in the modelAndView |
093 | private ModelAndView getModelMap(List contacts){ |
095 | Map modelMap = new HashMap( 3 ); |
096 | modelMap.put( "total" , contacts.size()); |
097 | modelMap.put( "data" , contacts); |
098 | modelMap.put( "success" , true ); |
100 | return new ModelAndView( "jsonView" , modelMap); |
104 | * Generates modelMap to return in the modelAndView in case |
109 | private ModelAndView getModelMapError(String msg){ |
111 | Map modelMap = new HashMap( 2 ); |
112 | modelMap.put( "message" , msg); |
113 | modelMap.put( "success" , false ); |
115 | return new ModelAndView( "jsonView" ,modelMap); |
122 | public void setContactService(ContactService contactService) { |
123 | this .contactService = contactService; |
Se quiser visualizar o código inteiro dessa app de exemplo (ou fazer o donwload do código completo), visite o meu repositório do GitHub: http://github.com/loiane/extjs-crud-grid
Só mais uma observação: você pode usar o dataWriter para salvar as informações que foram arrastadas para o grid com o plugin DataDrop (Lembra do plugin?). Também incluí o plugin no projeto, caso deseje testar.
Fonte:
http://www.loiane.com/2010/03/extjs-e-spring-framework-exemplo-de-um-crud-grid/