Depois de notar uma insistente dúvida, no fórum brasileiro, sobre como editar registros de um grid em uma janela a parte, resolvi criar o post de hoje. Iniciarei criando uma nova pasta no diretório examples do Ext, mas fiquem a vontade para criarem onde quiserem. Feito isso começo o desenvolvimento criando o fonte gridwindow.html com a estrutura básica dos includes:
<!--ExtJS--> <script src="../../adapter/ext/ext-base.js" type="text/javascript"></script> <script src="../../ext-all-debug.js" type="text/javascript"></script> <!--Scripts--> <script src="gridWindow.js" type="text/javascript"></script>
Notem que declarei o script gridWindow.js; criar este script será nosso próximo passo. Nele declarei uma classe singleton, ou seja, uma classe que não pode ser instanciada. Ela por si só é uma instância, global e única no sistema, como Ext ou Ext.Ajax. Essa modelo é famoso no Ext, chamado de Module Pattern, e na minha opinião atende bem pequenas aplicações. Para aplicações maiores sugiro a arquitetura de classes de interface publicada no post CRUD Avançado.
var GridWindow = function()
{
//...private...
return
{
//...public...
init: function()
{
//inicializacao
}
}
}();
Ext.EventManager.onDocumentReady(GridWindow.init, GridWindow);
Irei agora, na parte private, definir um DataStore com dados fictÃÂcios. Fica a seu encargo montar o grid, seja ele com dados do servidor ou não, usando JSON, XML, etc…
//dados ficticios
var dummyData = [
{nome: 'Bruno' ,idade: 19 ,desenvolveExt: 'S'}
,{nome: 'Ricardo' ,idade: 22 ,desenvolveExt: 'N'}
,{nome: 'Mayara' ,idade: 26 ,desenvolveExt: 'N'}
,{nome: 'MaurÃÂcio' ,idade: 21 ,desenvolveExt: 'S'}
]
//define dataStore
var store = new Ext.data.JsonStore({
data : dummyData
,fields : [
{name: 'nome' ,type: 'string' }
,{name: 'idade' ,type: 'int' }
,{name: 'desenvolveExt' ,type: 'string' }
]
});
//define renderers
var renderDesenvolveExt = function( value )
{
return value === 'S' ? 'Sim' : 'Nao';
}
No método init vou definir o grid:
//cria grid e guarda a referencia
this.grid = new Ext.grid.GridPanel({
title : 'Grid Window'
,renderTo : Ext.getBody()
,width : 450
,height : 300
,store : store
,deferRowRender : false
,viewConfig: {
forceFit: true
}
,columns: [{
header : 'Nome'
,dataIndex : 'nome'
}, {
header : 'Idade'
,dataIndex : 'idade'
}, {
header : 'Desenvolve Ext?'
,dataIndex : 'desenvolveExt'
,renderer : renderDesenvolveExt
}]
});
//seleciona primeira linha do grid
this.grid.getSelectionModel().selectFirstRow();
Após isto, definiremos um um Bottom ToolbarBar para o grid criando nele um botão que ativará a edição do registro selecionado. Também faremos um listener para disparar a edição mediante duplo clique da linha. Faço isto para demonstrar que não importa a maneira que vocé quer ativar a edição, o importante é obter o record (registro) da linha. Para fazer isso existem inúmeras maneiras, todas elas documentadas na API do ExtJS.
,bbar: [{
text : 'Editar Selecionado'
,scope : this
,handler: function()
{
//busca record da linha selecionada pelo SelectionModel. Ver docs de Ext.grid.RowSelectionModel
var record = this.grid.getSelectionModel().getSelected();
//invoca funçao
this.editRecord(record);
}
}
,'-'
,'<span style="color:gray;">*duplo clique sobre a linha para editar</span>'
]
,listeners: {
scope : this,
,rowdblclick: function(grid, rowIndex, e)
{
//pelo ÃÃndice buscamos no store o record
var record = grid.getStore().getAt(rowIndex);
//invoca funçao
this.editRecord(record);
}
}
Após isto criaremos um método público chamado editRecord, que irá receber um record, abrir uma window para edição, e modificar o registro:
,editRecord: function( record )
{
this.recordAtualizando = record;
if(!this.win)
{
this.win = new Ext.Window({
title : 'Ediçao de Registro'
,width : 400
,height : 200
,layout : 'fit'
,closeAction: 'hide'
,bodyStyle : 'background:white; padding:10px;'
,modal : true
,items : this.formWindow = new Ext.form.FormPanel({
border : false
,defaultType : 'textfield'
,items : [{
fieldLabel : 'Nome'
,name : 'nome'
},{
fieldLabel : 'Idade'
,xtype : 'numberfield'
,name : 'idade'
,allowDecimals : false
,allowNegative : false
},{
xtype : 'radiogroup'
,fieldLabel : 'Desenvolve Ext'
,hiddenName : 'desenvolveExt'
,items : [{
boxLabel : 'Sim'
,name : 'desenvolveExt'
,inputValue : 'S'
},{
boxLabel : 'Nao'
,name : 'desenvolveExt'
,inputValue : 'N'
}]
}]
})
,bbar : ['->',{
text : 'Atualizar Registro'
,scope : this
,handler: function()
{
var values = this.formWindow.getForm().getValues();
this.recordAtualizando.set('nome' , values.nome );
this.recordAtualizando.set('idade' , values.idade );
this.recordAtualizando.set('desenvolveExt' , values.desenvolveExt );
this.win.hide();
}
}]
});
}
this.win.show();
}
Populamos cada item de formulário com os dados do record (Atenção, existe uma falha com Ext.form.RadioGroup e CheckboxGroup, veja este fix):
//carrega formulário this.formWindow.getForm().loadRecord( record );
E por fim criamos um Bottom Toolbar na janela, e nele criamos o botão que irá buscar os dados no formulário, mudar o registro do grid, e concluir a edição:
,bbar : ['->',{
text : 'Atualizar Registro'
,scope : this
,handler: function()
{
var values = this.formWindow.getForm().getValues();
this.recordAtualizando.set('nome' , values.nome );
this.recordAtualizando.set('idade' , values.idade );
this.recordAtualizando.set('desenvolveExt' , values.desenvolveExt );
this.win.hide();
}
}]
E com isso terminamos nosso grid editável através de Ext.Window! Revisando:
- Criar grid
- Adicionar listener que dispara edição. No listener buscar o record de alguma forma.
- Criar a window com os itens de formulário, populando-os com os dados.
- Adicionar listener que dispara atualização de dados, buscando os valores e alterando o record.
Posts relacionados:





Parabéns pelo Blog!
Estava navegando pela net e o axei, gostei do jeito e exemplos c q tu expõem, muito bom mesmo, recomendarei-o!
Sinto q nos exemplos em geral pela net, falta um form básico c a interacao c uma linguagem q seja php e + banco de dados.
Mas continue assim pois está excelente e seu blog promete.
Não consegui visualizar o código completo.
Preciso urgente visualizar todo o código….Favor disponibilizar
Agredeço os comentários e peço desculpas pelo inconveniente do link. Espero que agora esteja corrigido.
Muito bom o post. Parabéns!
Ola, bom exemplo… só ficou faltando de fato o CRUD, apenas o Update foi demonstrado, com certeza quem visita este post aguarda os exemplos de Create, Retrieve e Delete… parabéns pelo blog :)