Foro

Creación de Formularios Dinámicos

1
Hola muy buen día.
Mi duda es la siguiente, yo desde base de datos quiero armar un formulario de manera dinámica, es decir la base de datos me dice dependiendo lo que traiga que componente va a crear. 
Por ejemplo de base de datos traigo una serie como esta 3 2 3 3 1 2 3 3
3=dropdown
2=radios
1=textbox

Y otra duda, Cómo puedo leer los datos de un JsonStore dato por dato?
Si pudieran dejarme un pequeño ejemplo. muchas gracias

1
Hola Soporte buen día (Te recomiendo cambiar tu nombre y avatar desde tu perfil XD).

No es algo muy complejo lo que planeas hacer, me ha tocado realizar cosas semejantes en varios proyectos, lo más importante aquí es tener definida correctamente la base de datos, personalmente preferiría en lugar de enviar un ID en el JSON representando cada componente enviar el xtype, de esta manera te será mucho más sencillo entender tu código en el futuro, a ti y a otros desarrolladores que se integren a tu proyecto más adelante.

Lo que se trata aquí es ir formado lo componentes al vuelo, es decir necesitas enviar en tu servicio JSON por lo menos el xtype, name y fieldLabel, luego puedes usar el método "add" del formulario para agregar tus nuevos componentes. O bien crear un formulario nuevo con tus nuevos campos y borrar el formulario anterior.

Vamos a suponer que este es el JSON que regresa tu servicio:

{
    "success": true,
    "fields" : [
        {"xtype":"textfield","name":"nombre","fieldLabel":"Nombre"},
        {"xtype":"textfield","name":"apellido","fieldLabel":"Apellido"},
        {"xtype":"numberfield","name":"edad","fieldLabel":"Edad"}
    ]
}

Ahora el JS a ejecutar despues de consultar el servicio sería algo así:
//Primero necesitamos parsear el JSON que envía el servicio
var data = Ext.decode(response.responseText); 
if(data.success){
    var defaults = {margins:'0 3 0 0'}; //aqui podrías definir las propiedades por default para aplicar a todos los campos (opcional)
    for(var i=0,len=data.fields.length;i<len;i++){
        Ext.apply(data.fields[i],defaults);
    }
    //tomamos el formulario (asumiendo que estamos en un controller de ExtJS usando una referencia) y le agregamos los campos
    var form = this.getForm();
    form.add(data.fields); //agregar los campos al formulario
}

Te recomiendo darle una leída a este tutorial sobre MVC: http://quizzpot.com/blog/modelos-vistas-y-controladores-en-ext-js-4

Saludos

PS: SI esta respuesta te sirvio dale puntos o marcalo como respuesta (del lado izquierdo de este post)
somacky: Ok eso es con respecto a mi primer Pregunta ahora le doy una leida 31/10/2013
somacky: Ya a esta hora tengo un avance con respecto a como me enviaste la solución, pruebo y comento 31/10/2013
1
Con respecto a mi segunda pregunta yo desde base de datos traigo algo como esto
0
Aún tengo problemas para crear el formulario.
he avanzado y ahora el jsonstore regresa ya los formularios solo para hacerlos como me lo sugeriste 
//Code here{
 'xtype' : 'combobox',
 'labelAlign': 'top',
 'name' : 'IdTipoOperacion',
 'fieldLabel' : 'IdTipoOperacion',
 'queryMode' : 'local',
 store: new Ext.data.Store({
 fields:[
 'IdTipoOperacion',
 'TipoOperacion'],
 data:[,
{
 'IdTipoOperacion' : 'Importacion'
 'TipoOperacion' : '1'
 },
{
 'IdTipoOperacion' : 'Exportacion'
 'TipoOperacion' : '2'
 },
{
 'IdTipoOperacion' : 'Transito'
 'TipoOperacion' : '3'
 }
]}),
 'displayField': 'TipoOperacion',
 'valueField' : 'IdTipoOperacion',
 'emptyText' : 'Selecciona',
 'triggerAction' : 'all',
 },{
 'xtype' : 'textfield',
 'name' : 'Referencia',
 'fieldLabel' : 'Referencia',
 'labelAlign': 'top',
 },{
 'xtype' : 'textfield',
 'name' : 'Sub',
 'fieldLabel' : 'Sub',
 'labelAlign': 'top',
 },],  "mensaje": '' }
el JsonStore quedo
 Ext.define('ItemBusqueda', {
        extend: 'Ext.data.Model',
        fields: ['nombre', 'idCampo']
    });
    var dsBusqueda = Ext.create('Ext.data.JsonStore', {
        autoDestroy: true,
        storeId: "dsBusquedaObj",
        model: 'ItemBusqueda',
        //autoLoad: { start: 0, limit: this.pageSize },
        proxy: {
            type: 'ajax',
            url: "operRmts.aspx?d=" + Math.random(),
            reader: {
                root: 'Campos',
                idProperty: 'idCampo',
                totalProperty: 'total',
                messageProperty: 'mensaje',
                successProperty: 'exitoso'
            },
            listeners: {
                exception: function (aThis, response, operation, eOpts) {
                    data = Ext.JSON.decode(response.responseText);
                    alert(data.mensaje);
                },                              
            }
        },
        listeners: {
            loadexception: excepcionCargaDatos,
            beforeload: function (sender, aOptions) {
                sender.getProxy().setExtraParam('oper', '6');
                sender.getProxy().setExtraParam('IdDireccion', actIdTipo);
            },
//Aquí agregue el metodo que me sugeriste y parece que esta bien
            load: function (response) {
                var data = Ext.decode(response.responseText);
                if (data.success) {
                    var defaults = { margins: '0 3 0 0' }; //aqui podrías definir las propiedades por default para aplicar a todos los campos (opcional)
                    for (var i = 0, len = data.campos.length; i < len; i++) {
                        Ext.apply(data.campos[i], defaults);
                    }
                    //tomamos el formulario (asumiendo que estamos en un controller de ExtJS usando una referencia) y le agregamos los campos
                    var form = this.getForm();
                    form.add(data.campos); //agregar los campos al formulario
                }
            }
        }
    });
 var panel3 = Ext.create('Ext.Panel', {
        //step 2
        columns: 2,        
        bodyStyle: "padding : 10px",
        border: true,
        defaults: { width: 200 },
        store: dsBusqueda,
        items: [cboTipoExpediente, comboLocal],       
        
    });
El problema es a la hora de intentar cargar los nuevos elementos del formulario en el panel, no se si estoy haciendo el llamado correctamente o el listener load del jsonstore sea el correcto.
1
Después de buscar y probar llegué a esta solución se las aporto para quienes también requieren hacer dinámicamente sus formularios. 
Lo primero es el Json regresa algo como esto


{ "exitoso": true, "total": 13, 
 "Campos" : [
 {
 'xtype' : 'combobox',
 'name' : 'IdAduana',
 'fieldLabel' : 'Aduana',
 'displayField': 'NombreAduana',
 'valueField' : 'IdAduana',
 'emptyText' : 'Selecciona'
 },{
 'xtype' : 'combobox',
 'name' : 'IdPatente',
 'fieldLabel' : 'Patente',
 'displayField': 'NumeroPatente',
 'valueField' : 'IdPatente',
 'emptyText' : 'Selecciona'
 },{
 'xtype' : 'numberfield',
 'name' : 'Folio',
 'fieldLabel' : 'Folio',
 'labelAlign': 'top',
 'allowNegative' : 'false',
 'minValue' : 1,
 },{
 'xtype' : 'textfield',
 'name' : 'Referencia',
 'fieldLabel' : 'Referencia',
 'labelAlign': 'top',
 },{
 'xtype' : 'datefield',
 'name' : 'FechaEntrada',
 'fieldLabel' : 'FechaEntrada',
 'labelAlign': 'top',
 'dateFormat' : 'Y-m-d',
 'submitFormat' : 'Y-m-d',
 'emptyText' : 'DD/MM/AAAA'
 }{
 'xtype' : 'textfield',
 'name' : 'TipoOperacion',
 'fieldLabel' : 'TipoOperacion',
 'labelAlign': 'top',
 }
],  "mensaje": '', "flds": [
 {
 'name': 'IdAduana'
},
{
 'name': 'NombreAduana'
},
 {
 'name': 'RazonSocial'},
 {
 'name': 'IdCliente'
},{
 'name': 'IdTipoOperacion'
},
{
 'name': 'TipoOperacion'
} 
], "data": [
 {
 'NombreAduana' : 'Pantaco',
 'IdAduana' : '1',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Aeropuerto',
 'IdAduana' : '2',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Altamira',
 'IdAduana' : '3',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Manzanillo',
 'IdAduana' : '4',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Veracruz',
 'IdAduana' : '5',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Nuevo Laredo',
 'IdAduana' : '6',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Lazaro Cardenas',
 'IdAduana' : '7',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Mexicali',
 'IdAduana' : '8',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Cd. Juarez',
 'IdAduana' : '9',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Cd. Hidalgo',
 'IdAduana' : '10',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Toluca',
 'IdAduana' : '11',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Guadalajara',
 'IdAduana' : '12',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Logistica',
 'IdAduana' : '13',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Legal',
 'IdAduana' : '14',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Consultoria',
 'IdAduana' : '15',
 'Identificador' : 0
 },{
 'NombreAduana' : 'Aeropuerto Internacional Mariano Escobedo',
 'IdAduana' : '16',
 'Identificador' : 0
 },{
'RazonSocial': 'PHILIPS MEXICANA SA DE CV',
'IdCliente': '22',
'Identificador' : 1},{
'RazonSocial': 'FOTORAMA DE MEXICO SA DE CV',
'IdCliente': '36',
'Identificador' : 1},{
'RazonSocial': 'IMPORTADORA GLOBASTIC, S.A. DE C.V.',
'IdCliente': '2025',
'Identificador' : 1},{
 'TipoOperacion' : 'Importacion',
 'IdTipoOperacion' : '1',
 'Identificador' : 2
 },{
 'TipoOperacion' : 'Exportacion',
 'IdTipoOperacion' : '2',
 'Identificador' : 2
 },{
 'TipoOperacion' : 'Transito',
 'IdTipoOperacion' : '3',
 'Identificador' : 2
 }
] }
En el JsonStore que recibe los datos la función que te marca que fue regresado correctamente
getResponseData: function (response) {
                    try {
                        var data = Ext.decode(response.responseText);
                        var resp = response.responseText;
                        var results = resp.split(':');
                        if (data.exitoso) {
                            var defaults = { margins: '0 3 0 0', labelAlign : 'top', queryMode: 'local', triggerAction: 'all', /*store: storeext*/}; //aqui podrías definir las propiedades por default para aplicar a todos los campos (opcional)
                            for (var i = 0, len = data.Campos.length; i < len; i++) {
                                Ext.apply(data.Campos[i], defaults);
                            }
                            //panel3.add(data.Campos);
                        }
                    }
                    catch (ex) {
                        Ext.Error.raise({
                            response: response,
                            json: response.responseText,
                            parseError: ex,
                            msg: 'El JSON que regresa el Servidor no tiene el formato correcto: ' + ex.toString()
                        });
                    }
                    agregar(data);
                    //var resp = response.responseText;
                    //var results = resp.split(':');
                    //var data = Ext.JSON.decode(resp);
                    
                    return data;
                },

Y la función que agrega los combos al formulario
function agregar(response) {
    var r = response;
    var xsx = r.data[0].Identificador;
    //var data = Ext.decode(response.responseText);
    var container = panel3.getForm(); // mi panle formulario se llama panel3
    var longdata = r.data.length;
    var camp = r.Campos.length;
    var cont = 0;
    var fld = 0;
    var x = r.flds.length / 2;    
    //aquí comienzas a declarar los stores dinamicos
    for (var i = 0; i < camp; i++) {
        if (r.Campos[i].xtype == "combobox" || r.Campos[i].xtype == "radiobutton") {
            storeext[i] = Ext.create('Ext.data.Store', {
                //store: {
                fields: [],
                data: { "data": [] },
                proxy: {
                    type: "memory",
                    reader: {
                        type: "json",
                        root: "data"
                    }
                }
                //},
            });
            var fiel = storeext[i].model.prototype.fields; //aquí tomas los modelos y en seguida agregas los fields que necesiten los combos o radios
            //var v = r.flds.length;        
            for (var j = 0; j < 2; j++) {
                fiel.add(r.flds[fld]);
                fld = fld + 1;
                //fiel.add(r.flds[1]);
            }
            while (longdata > cont + 1 && r.data[cont].Identificador == r.data[cont + 1].Identificador) {
                storeext[i].add(r.data[cont]);
                cont++;
            }
            storeext[i].add(r.data[cont]);
            var def = { store: storeext[i] }; //aqui podrías definir las propiedades por default para aplicar a todos los campos (opcional)        
            Ext.apply(r.Campos[i], def);
            cont++;
            panel3.add(r.Campos[i]);
        }
        else {
            panel3.add(r.Campos[i]);
        }
    }
    panel3.add(btnBuscar); //boton extra para hacer el submit
}

Espero les sirva.
Saludos

¿Conoces a alguien que pueda responder esta pregunta? Comparte el link en Twitter o Facebook

Es necesario registrarse para poder participar en el foro! Si ya tienes una cuenta puedes entrar y comentar en este foro.