Introducción a formularios en ExtJS: Ext.FormPanel
21/11/2008 por Javier Caride
Definiendo un formulario
Realmente la definición de un formulario que haga su carga de datos y guardado mediante Ajax, no dista mucho de la definición de un grid.
Lo primero que hacemos es definir el registro que contendrá nuestros datos. Como se puede ver en este ejemplo hemos utilizado la misma definición de registro.
var categoriesRecord = new Ext.data.Record.create([
{name: 'cad_id', type: 'int'},
{name: 'cad_name', type: 'string'},
{name: 'cad_description', type: 'string'}
]);
Para la carga de datos y respuestas del servidor, definimos también un reader (al igual que en los grids). Para este ejemplo vamos a seguir utilizando la codificación JSON, aunque podríamos haber elegido un reader XML
var categoriesFormReader = new Ext.data.JsonReader(
{
root : 'data',
successProperty : 'success',
totalProperty: 'total',
id: 'cad_id'
},categoriesRecord
);
Como vemos, su definición es prácticamente igual que en el caso del reader del grid, salvo que en esta ocasión hay que definir una propiedad ‘successProperty’ en la respuesta JSON que nos indique si ha tenido éxito o no la operación
Otra novedad respecto al grid, es que podemos indicar a un form desde el servidor si hubo algún error en algún campo. Esto lo podemos utilizar para hacer verificacion de campos en servidor (comprobar duplicados, caracteres no permitidos, etc.). Para ello se define una nueva clase que hereda de JsonReader: JsonErrorReader
Ext.form.JsonErrorReader = function() {
Ext.form.JsonErrorReader.superclass.constructor.call(this, {
root : 'data',
successProperty : 'success',
totalProperty: 'total'
},
[
{name: 'id'},
{name: 'msg'}
]);
};
Podemos ver que en este caso, en la definición del reader se cambia el registro por otro nuevo con sólo dos campos: ‘id’ y ‘msg’. En ‘id’ vendrá el identificador del campo en el que hay un error y en ‘msg’ vendrá el error para ese campo. Es importante que activemos los mensajes superpuestos mediante la línea Ext.QuickTips.init();
La definición del form es sencilla. Como en cualquier otro panel, en la propiedad ‘items’ vamos a introducir el array con todos los componentes del formulario, en este campos (texto, áreas de texto, combos, radios, etc.)
var formCategories = new Ext.FormPanel({
frame : true,
width : 624,
height: 346,
waitMsgTarget : true,
reader: categoriesFormReader,
errorReader: new Ext.form.JsonErrorReader(),
items : [{
fieldLabel : 'Categoría',
xtype: 'textfield',
name : 'cad_name',
allowBlank:false,
width : 430
}, {
fieldLabel : 'Descripción',
name : 'cad_description',
allowBlank:false,
xtype: 'textarea',
width : 430,
height: 225
}, {
fieldLabel : 'Fecha',
name : 'cad_date',
allowBlank:false,
xtype: 'datefield',
renderer: Ext.util.Format.dateRenderer('d/m/Y'),
width : 430
}, {
name : 'cad_id',
xtype: 'hidden'
}],
});
Acto seguido, vamos a añadir un botón. Esta vez en vez de indicarlo en el array de configuración, vamos a utilizar el método addButton y vamos a añadirle un poco de funcionalidad
var submitFormCategories = formCategories.addButton({
text : 'Guardar',
disabled : false,
handler : function() {
formCategories.getForm().submit({
url : 'formSaver.php',
waitMsg : 'Salvando datos...',
failure: function (form, action) {
Ext.MessageBox.show({
title: 'Error al salvar los datos',
msg: 'Error al salvar los datos.',
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.ERROR
});
},
success: function (form, request) {
Ext.MessageBox.show({
title: 'Datos salvados correctamente',
msg: 'Datos salvados correctamente',
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.INFO
});
responseData = Ext.util.JSON.decode(request.response.responseText);
formCategories.getForm().load({
url : 'formLoader.php',
method: 'GET',
params: {
cat_id: responseData.cat_id
},
waitMsg : 'Espere por favor'
});
}
});
}
});
En el handler vemos que realizamos una llamda a la función formCategories.getForm().submit(), a la cual le pasamos un array de configuración. Esta llamada lo que hace es llamar al envío del formulario. Éste se configura pasándole una función para el manejo de error, una función para el manejo de una operación correcta y la URL de actualización.
El código todo unido quedaría de la siguiente forma
Ext.onReady(function() {
Ext.QuickTips.init();
/*
* Creamos el registro de datos
*/
var categoriesRecord = new Ext.data.Record.create([
{name: 'cad_id', type: 'int'},
{name: 'cad_name', type: 'string'},
{name: 'cad_date', type: 'date', dateFormat: 'Y-m-d'},
{name: 'cad_description', type: 'string'}
]);
var categoriesFormReader = new Ext.data.JsonReader(
{
root : 'data',
successProperty : 'success',
totalProperty: 'total',
id: 'cad_id'
},categoriesRecord
);
Ext.form.JsonErrorReader = function() {
Ext.form.JsonErrorReader.superclass.constructor.call(this, {
root : 'data',
successProperty : 'success',
totalProperty: 'total'
},
[
{name: 'id'},
{name: 'msg'}
]);
};
Ext.extend(Ext.form.JsonErrorReader, Ext.data.JsonReader);
var formCategories = new Ext.FormPanel({
frame : true,
width : 624,
height: 346,
waitMsgTarget : true,
reader: categoriesFormReader,
errorReader: new Ext.form.JsonErrorReader(),
items : [{
fieldLabel : 'Categoría',
xtype: 'textfield',
name : 'cad_name',
allowBlank:false,
width : 430
}, {
fieldLabel : 'Descripción',
name : 'cad_description',
allowBlank:false,
xtype: 'textarea',
width : 430,
height: 225
}, {
fieldLabel : 'Fecha',
name : 'cad_date',
allowBlank:false,
xtype: 'datefield',
renderer: Ext.util.Format.dateRenderer('d/m/Y'),
width : 430
}, {
name : 'cad_id',
xtype: 'hidden'
}],
});
var submitFormCategories = formCategories.addButton({
text : 'Guardar',
disabled : false,
handler : function() {
formCategories.getForm().submit({
url : 'formSaver.php',
waitMsg : 'Salvando datos...',
failure: function (form, action) {
Ext.MessageBox.show({
title: 'Error al salvar los datos',
msg: 'Error al salvar los datos.',
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.ERROR
});
},
success: function (form, request) {
Ext.MessageBox.show({
title: 'Datos salvados correctamente',
msg: 'Datos salvados correctamente',
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.INFO
});
responseData = Ext.util.JSON.decode(request.response.responseText);
formCategories.getForm().load({
url : 'formLoader.php',
method: 'GET',
params: {
cat_id: responseData.cat_id
},
waitMsg : 'Espere por favor'
});
}
});
}
});
var windowForm = new Ext.Window({
closable: true,
resizable: true,
modal: false,
border: true,
plain: true,
closeAction: 'hide',
title: 'Layout Tab',
width: 640,
height: 380,
renderTo: 'divRender',
items: [formCategories]
});
formCategories.getForm().load({
url : 'formLoader.php',
method: 'GET',
params: {
cat_id: 1
},
waitMsg : 'Espere por favor'
});
windowForm.show();
});
Introduciendo un combo como campo
El tratamiento de un combo requiere un poco más de trabajo. En este caso vamos a introducir el combo en el formulario como un objeto independiente.
var categoriesComboWebs = new Ext.form.ComboBox({
fieldLabel: 'Web',
hiddenName: 'cad_web', // Este campo es importante, sin él no funciona el combo
store: new Ext.data.SimpleStore({
fields: ['cad_web', 'cad_web_text'],
data : websData,
id: 0
}),
valueField: 'cad_web',
displayField: 'cad_web_text',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText: 'Seleccione una web...',
selectOnFocus: true,
width: 430
});
En este caso hemos hecho que el combo sea local, y que los datos los saque de un Array. Para ello, hemos definido el store del mismo como un Ext.data.SimpleStore. En la propiedad data, hemos indicado cual es la variable javascript que contiene los valores a utilizar, y debe contener valores de la siguiente forma:
var websData = [
['1','http://www.3megapixels.com'],
['2','http://www.desarrollosweb.net'],
['3','http://www.axena.org'],
['4','http://www.javiercaride.es']
];
Una propiedad importante, para que cuando carguemos los datos se seleccione bien el elemento del combo correspondiente y que además se envíe al servidor la variable correcta, es ‘hiddenName’. Debe estar inicializada al valor del registro que contiene la información, en este caso cad_web
como puedo obtener el valos de uno de los combos necesito el valor del combo para enviarlo como dato en el store load.
saludos.
Buenas, me interesaria saber como se puede modificar el tamaño de letra de las opciones del combo.
Tengo un combo y no consigo cambiar el tamaño de las letras del desplegable, cuando selecciono la opcion si que se queda al tamaño que quiero.
Pero no consigo modificar el tamaño de las opciones, si alguien me hecha una manilla se lo agradecere muchisimo.
Gracias me fue de mucha ayuda esta información te lo agradesco
Hola, muy bueno el elemplo, se que hace tiempo que esta publicado, pero hay posibilidad de que subas el fuente del php? por que es la parte con la que estoy trancado y no se seguir.
Saludos, desde ya muchas gracias.