Secciones

Artículos para tus primeros pasos

Si estás empezando a introducirte en el mundo de Groovy y Grails, no te pierdas nuestros artículos básicos: 

Entrevistas con los expertos
 

Los protagonistas te cuentan de qué van los proyectos más importantes del mundo Groovy:


Un proyecto de:
ImaginaWorks
Campus Escuela de Groovy

Buenas prácticas con Grails: anidando combos con AJAX

martes 10/11/2009

Uno de los usos típicos de Ajax es el generar formularios que se definan dinámicamente en función de los valores que vaya introduciendo el usuario. Pensad por ejemplo en el típico caso de una serie de combos en los que el valor de cada uno depende de lo que el usuario haya introducido en el anterior (de hecho este artículo es una respuesta a un post de Abel Coronado sobre este tema).

Para resolver este caso, como siempre podemos seguir dos caminos: buscar una solución para el caso concreto en el que estemos trabajando, o desarrollar una solución genérica que podamos reutilizar. Evidentemente deberíamos optar por esta segunda siempre que fuera posible.

Lo que vamos a ver en este artículo es una posible implementación usando un par de plantillas GSP que permite encadenar un número indeterminado de combos. Tendremos un controlador que defina las acciones que se invocarán por ajax en el evento onchange de cada combo y generará el código para el siguiente.

Empezando por el principio, lo primero que queremos es mostrar el combo inicial, que para abreviar incluiremos directamente desde index.gsp:

  

    < g:render 
      template="ajax_combo"
      model="[items:['','uno','dos','tres'], comboId:'combo1', nextId:'combo2']" />



Como ves, el combo se dibuja en la plantilla _ajax_combo.gsp, que tiene esta pinta:

< div id="${comboId}">
< g:select
  id="${comboId}_select"
  name="${comboId}_select"
  from="${items}" onchange="${remoteFunction(action:'ajax_'+comboId,update:[success:nextId, failure:'error'], params:'\'value=\' + this.value' )}"
  />

Fíjate sobre todo en que recibe en el modelo dos Ids, el del combo actual y el del siguiente, y con esos datos genera el evento onchange que invocará una acción en el controlador (el nombre lo establecemos por el convenio) y el div para albergar el resultado. Con estas herramientas, lo único que tenemos que hacer es poner en el controlador las acciones que vayan generando los datos para cada combo en función del valor del anterior, veamos la primera:
    def ajax_combo1 = {
        def values = [
            '':['Elija un valor del primer combo...'],
            'uno':['','uno : A','uno : B','uno : C'],
            'dos':['','dos : A','dos : B','dos : C'],
            'tres':['','tres : A','tres : B','tres : C']
        ]

        render(
            template:'ajax_combo',
            model:[
                items:values[params.value],
                comboId:'combo2',
                nextId:'combo3'
            ]
        )
    }



y esta es la segunda, que genera el tercer combo en función del valor del segundo:
    def ajax_combo2 = {
        println params
        def values = [
            '':['Elija un valor del primer combo...'],
            'uno : A':['', 'uno : A : 1', 'uno : A : 2', 'uno : A : 3'],
            'uno : B':['', 'uno : B : 1', 'uno : B : 2', 'uno : B : 3'],
            'uno : C':['', 'uno : C : 1', 'uno : C : 2', 'uno : C : 3'],
            'dos : A':['', 'uno : A : 1', 'uno : A : 2', 'uno : A : 3'],
            'dos : B':['', 'uno : B : 1', 'uno : B : 2', 'uno : B : 3'],
            'dos : C':['', 'uno : C : 1', 'uno : C : 2', 'uno : C : 3'],
            'tres : A':['', 'uno : A : 1', 'uno : A : 2', 'uno : A : 3'],
            'tres : B':['', 'uno : B : 1', 'uno : B : 2', 'uno : B : 3'],
            'tres : C':['', 'uno : C : 1', 'uno : C : 2', 'uno : C : 3']
        ]

        /*
        El ultimo combo lo dibujamos con otra plantilla que no tiene
        evento javascript.
        */
        render(
            template:'combo',
            model:[
                items:values[params.value],
                comboId:'combo3',
                nextId:'combo4'
            ]
        )
    }

Evidentemente, en una situación real los valores se generarían a partir del modelo de datos o algún otro tipo de información. Fíjate que en el último caso utilizamos una plantilla distinta, _combo.gsp, que no incluye código Ajax, puesto que ya no hay combos que mostrar, pero podríamos utilizar esta misma solución para mostrar 4, 5 o 27 combos, simplemente añadiendo acciones al controlador. Podéis descargar el proyecto Grails con el código de este ejemplo desde este enlace.

 


Contenidos relacionados:



0 comentarios:

Tienes que estar registrado para iniciar sesión y poder publicar tus comentarios