Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Select dependiente con CGI::Ajax

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Intermedio
Mensaje Mie Oct 03, 2007 7:10 am
zozo666
Perlero Frecuente
Perlero Frecuente
Registrado: 26 May 2007
Mensajes: 137
Select dependiente con CGI::Ajax Responder citando

Buenos días perleros, necesitaría una cosilla. Cómo hago para rellenar un select con una consulta que realizo mediante Ajax a la base de datos.

La cosa es así, tengo un select con todos los países, y necesitaría que al elegir cualquier país, o sea en el evento onChange del select, me comunique con el Ajax y me realice una consulta sobre el país que seleccione. Luego que con esa consulta me rellene un select.
Seria algo asi como un select dependiente, que según lo que elija en un select, me aparece en el otro, pero en este caso trabajándolo desde la base de datos.

¿Alguna idea? Muchas gracias por la ayuda Wink
Mensaje Mie Oct 03, 2007 7:38 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4105
Ubicación: Valladolid, España
Responder citando

Por este foro hay algunos hilos al respecto. Usa el sistema de búsqueda. Busca por 'Ajax'.
Mensaje Mie Oct 03, 2007 8:23 am
zozo666
Perlero Frecuente
Perlero Frecuente
Registrado: 26 May 2007
Mensajes: 137
Responder citando

No verdaderamente no me sirvió nada de lo que había, lo estoy viendo demasiado complicado hacerlo en Perl, ya que me fijo como se hace en PHP y lo veo en 30 líneas hecho.

¿Por qué se complica tanto hacer esto en Perl, si solamente es rellenar un select desde una consulta?.

No hay una forma fácil de hacerlo, solamente utilizando Ajax. Ya me puse nervioso con esto, je disculpas.
Mensaje Mie Oct 03, 2007 8:40 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4105
Ubicación: Valladolid, España
Responder citando

Con el módulo CGI de Perl, se puede hacer en 5 líneas:
  1. Abrir conexión a la base de datos
  2. Preparar, hacer la consulta y recuperar el resultado
  3. Cerrar la conexión
  4. Hacer el select, en HTML
  5. Imprimir el HTML
Esto lo conviertes en un CGI y lo llamas desde un CGI::Ajax.
Mensaje Mie Oct 03, 2007 8:50 am
zozo666
Perlero Frecuente
Perlero Frecuente
Registrado: 26 May 2007
Mensajes: 137
Responder citando

Eso lo he hecho, pero tiene 2 problemas.

1º No funciona bien el tema de seleccionar y que se actualice el otro select

2º El select va impreso en el div, por lo tanto no puedo contar con los value que requiero para enviar el formulario con la información, ya que el Ajax lo imprime, pero no aparece en el código HTML.
Mensaje Mie Oct 03, 2007 9:06 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4105
Ubicación: Valladolid, España
Responder citando

Podrías devolver los valores a un JavaScript de la página que se encargase de modificar el contenido del select dependiente.
Mensaje Mie Oct 03, 2007 9:36 am
zozo666
Perlero Frecuente
Perlero Frecuente
Registrado: 26 May 2007
Mensajes: 137
Responder citando

Eso es lo que estoy probando ahora, pero como es eso de devolverlo a un javascript, osea como le paso los parametros al java script?? la funcion javascript ya me la dieron, lo que necesitaria saber es como le paso los parametros desde el ajax a ese javascript.

Probe usando HTML::template pero me tira la pagina entera dentro e la otra, osea necesitaria pasarle solamente los parameotros requeridos por la funcion javascript
Mensaje Mie Oct 03, 2007 9:51 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4105
Ubicación: Valladolid, España
Responder citando

Hay módulos para pasar información en formato JSON. También podría ser en formato XML. Pero si conoces cómo son los datos los podrías pasar, por ejemplo, en un string, separando los valores con un '|'.

La cuestión es que, como tu eres el que pasa los valores, deberías entonces saber la forma de leerlos.

El problema es entender que la información ha de pasar 'serializada'. No vale con hacer un print del contenido, sino que debe estar formateada para que pueda pasar por el protocolo HTTP sin problemas. Como ese protocolo es fundamentalmente texto, una forma de hacerlo es justamente pasando esa información a texto. Luego, con el JavaScript, lo recuperamos y modificamos el DOM del documento.
Mensaje Mie Oct 03, 2007 10:00 am
zozo666
Perlero Frecuente
Perlero Frecuente
Registrado: 26 May 2007
Mensajes: 137
Responder citando

Si yo lo que necesitaría es cómo pasarle los datos al Template, ya que dentro de éste se encuentra la función JavaScript que se encarga de todo.
Necesitaría únicamente la forma de pasar la información a el TMPL que no sea mediante un div. O sea en el Ajax sería una lógica así:

Perl:
#####
$resultado = $dbh->consulta;
#proceso el resultado
TMPL ->$resultado
#####


$resultado es un string que lo armo con la consulta desde el script, hasta ahí no hay problema, lo que necesitaría es cómo paso el string al template, así ya dentro del template le inserto la información en el llamado de la función JavaScript.

Javascript:
<script language="JavaScript">
                funcion_relleno ( 'selectcompania', relleno);
        }
</script>


Donde relleno es el string que procese desde Perl, entonces ¿cómo paso un string desde el script de Ajax al template?
Mensaje Mie Oct 03, 2007 10:21 am
kidd
Creador de Perl en Español
Creador de Perl en Español
Registrado: 15 Oct 2003
Mensajes: 1389
Ubicación: México
Responder citando

Veamos, lo que necesitas no es tan díficil, quizá un poco complejo porque necesitas de varias herramientas.

Para empezar te recomiendo que entres al siguiente tema del foro en donde se hablaba acerca de como llenar un select a base de la selección de otro select:
http://perlenespanol.baboonsoftware.com/foro/about833.html

Después, si quieres saber como implementar Ajax con Perl, entonces te recomiendo el tutorial de Ajax que tenemos en el sitio:
http://perlenespanol.baboonsoftware.com/tutoriales/cgi/perl_y_ajax.html

Para usar el HTML::Template también tenemos un tutorial:
http://perlenespanol.baboonsoftware.com/tutoriales/modulos/introduccion_a_htmltemplate.html


Saludos
Mensaje Mie Oct 03, 2007 1:33 pm
zozo666
Perlero Frecuente
Perlero Frecuente
Registrado: 26 May 2007
Mensajes: 137
Responder citando

Ahora estoy usando eso el dynamicoptionlist pero igualmente me gustaría saber cómo pasar los parámetros al TMPL desde el script Ajax, yo intenté haciendo que en el onChange se comunique con una función del script y me genere un select con los valores correspondientes. Pero el problema es que al estar dentro de div, no funcionan los values para utilizarlos en el form.

¿No hay ninguna otra forma de hacer esto, algo sencillo, en Ajax, alguna idea?
Mensaje Mie Oct 03, 2007 3:51 pm
kidd
Creador de Perl en Español
Creador de Perl en Español
Registrado: 15 Oct 2003
Mensajes: 1389
Ubicación: México
Responder citando

Lo primero que debes de hacer es crear o buscar un JavaScript que te permite hacer update de un select box, ya con eso, entonces lo puedes modificar para que en vez de poner lo valores con variables dentro de JavaScript, tome los valores de una respuesta con Ajax.
Mensaje Mie Oct 03, 2007 5:03 pm
zozo666
Perlero Frecuente
Perlero Frecuente
Registrado: 26 May 2007
Mensajes: 137
Responder citando

Estuve viendo el "dynamicoptionlist" y lo usé, pero tenía el presentimiento de que tampoco me iba a funcionar, el problema es que como no aparece el código de los option en la página cuando mando los datos a la función Ajax: {notificacion_enviar( ['evento_fecha','evento_titulo','evento_hora','cnlhorario','email','empresa'], ['mensaje_noti'] );} no me los toma, por lo tanto no me realiza la operación que yo quiero.

El tema es que el div "empresa" no aparece en la página, eso es todo código javascript que se encarga de listar todos los option, por lo tanto no puedo extraer el empresa = document.form1.empresa.value" porque el id empresa no existe ya que al ser código javascript el que lo genera, no aparece en la página, solamente veo que aparece cuando hago un submit con un GET pero no me sirve de esa manera.

¿Qué solución hay a esto? Hace horas que vengo con esto y la verdad no lo puedo solucionar.
Mensaje Mie Oct 03, 2007 6:31 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4105
Ubicación: Valladolid, España
Responder citando

La solución del problema de crear select actualizados en cascada con Ajax... en puro Perl:
Perl:
#!/usr/bin/perl -w
#
# Ejemplo de CGI::Ajax, extraído del ejemplo
# 'pjx_combo.pl' de la distribución CGI::Ajax
#
# Joaquín Ferrero. 20071004
#
# INSTALACIÓN: en algún lugar donde el servidor web pueda ejecutarlo
#
# este script muestra un conjunto dinámico de cajas select, donde la
# selección en una caja cambia los contenidos de la otra, o los valores
# html de un div. Los datos de cada select provienen de un hash, pero
# puede ser también de una conexión con una base de datos, etc.
#
# Nota, se requiere una versión de CGI::Ajax >= 0.49
#

use CGI ':standard';
use CGI::Ajax 0.49;

use strict;

# Nuestra base de datos
my %datos = (
    tipo_1 => {
                nombre    => 'Homer Simpson',
                direccion => 'Evergreen Terrace',
    },
    tipo_2 => {
                apodo     => 'Sean Connery',
                objetivo  => 'Downtown Street',
    },
    tipo_3 => {
                empresa   => 'Aprosi',
                calle     => 'Fanega, 1',
    },
    tipo_4 => {
                usuario     => 'zozo666',
                procedencia => 'Desconocida',
    },
);

# Lista de funciones a exportar al JavaScript
my %funciones = (
    Select1   => \&select1,
    Select2   => \&select2,
    Resultado => \&resultado,
);

# Nuestros objetos CGI y CGI::Ajax
my $cgi  = CGI->new();
my $ajax = CGI::Ajax->new( %funciones );

# Inicializa algunos parámetros del comportamiento CGI::Ajax
$ajax->JSDEBUG(1); # activa el depurado javascript, que colocará un
                   #  nuevo elemento div al final de nuestra página mostrando
                   #  el URL de la petición asíncrona

# Salida de nuestra página web
print $ajax->build_html( $cgi, \&muestra_html );


### Subrutinas

# Salida del HTML.
# He añadido una función javascript para borrar los contenidos.
# Esto evitará efectos extraños al sobreescribir un div sin antes
# vaciarlo.
sub muestra_html {
    my $html = <<EOT;
<HTML>
<HEAD><title>Ejemplo CGI::Ajax de select en cascada</title>
<SCRIPT>
// define una funcion para limpiar adecuadamente los div
function reinicia_div( ) {
    if ( arguments.length ) {
        // reinicia un div especifico
        for(var i = 0; i < arguments.length; i++ ) {
            document.getElementById(arguments[i]).innerHTML = "";
        }
    }
    else {
        // reinicia todos los div
        document.getElementById("div_lista1").innerHTML = "";
        document.getElementById("div_lista2").innerHTML = "";
        document.getElementById("div_resultado").innerHTML = "";
    }
}
</SCRIPT>

</HEAD>
<BODY onload="reinicia_div(); Select1([],['div_lista1']); return true;" >
<form><table border="3">
<tr>
    <td><div id="div_lista1"></div></td>
    <td><div id="div_lista2"></div></td>
    <td><div id="div_resultado" style="border: 1px solid black; width: 240px; height: 80px; overflow: auto"></div></td>
</tr>
<tr>
    <td colspan="2"><input type="text" name="textfield"></td>
    <td><input type="submit" name="Submit" value="Submit"></td>
</table></form>
</BODY>
</HTML>
EOT

    return $html;
}

# Estas son las funciones exportadas - notar que Select1 y Select2
# solo están devolviendo el html que es insertado es sus correspondientes
# elementos div
sub select1 {

    # Creamos un select, cuyo Onclick activa la petición Ajax
    # En la petición Ajax Select2 pasamos el valor elegido en select_1 e
    # indicamos que el resultado debe quedarse en el div_lista2
    # Aquí usamos las facilidades del módulo CGI para crear código HTML
    # sin verlo:
    my $html
        = Select(
            {
                -id      =>  'select_1',
                -name    =>  'lista_1_nombre',
                -size    =>   4,
                -OnClick => q{reinicia_div('div_resultado');}
                          . q{Select2( ['select_1'], ['div_lista2'] );}
                          . q{return true;},
            },

            # Obtener los valores desde nuestros %datos.
            # Podría ser también una consulta a una base de datos
            # Por cada uno de ellos, lo map()eamos a una <option>
            map { option($_) } sort keys %datos,
    );

    return $html;
}

sub select2 {

    # Recibimos como argumento el valor activado en el select_1
    my $valor_select_1 = shift;

    # Igual que antes, creamos el html a mostrar en el div
    # Es un select que, al activarse un valor, hace otra llamada Ajax,
    # esta vez a la función Resultado pasándole los valores de los dos select,
    # y dejando la respuesta en div_resultado
    # En esta ocasión armamos el select creando el código HTML directamente,
    # para compararlo con la forma anterior
    my $html = qq!<select multiple id="select_2" name="lista_2_nombre" size=3!
             . qq! onclick="Resultado( ['select_1','select_2'], ['div_resultado'] );!
             . qq! return true;"
!
             . qq!>!;

    # Mostramos los valores desde %datos
    foreach my $valor ( keys %{ $datos{ $valor_select_1 } } ) {
        $html .= '<option value=' . $valor . '>' . $valor . "</option>";
    }

    $html .= "</select>";

    return $html;
}

sub resultado {

    # Recibimos varios argumentos.
    # El primero es el valor de select_1
    my $valor_select_1 = shift;

    # Lo que vamos a devolver es el texto dentro del div
    my $html = "";

    # El segundo argumento puede ser un conjunto de valores,
    # porque el select_2 tiene el atributo 'multiple'.
    while ( @_ ) {
        my $valor_select_2 = shift;
        $html .= $datos{ $valor_select_1 }{ $valor_select_2 } . "<br>";
  }

  return $html;
}

__END__


Ultima edición por explorer el Vie Abr 25, 2008 1:00 pm, editado 1 vez
Mensaje Jue Oct 04, 2007 6:37 am
zozo666
Perlero Frecuente
Perlero Frecuente
Registrado: 26 May 2007
Mensajes: 137
Responder citando

Muchas gracias ya lo estoy probando...
Publicar nuevo tema   Responder al tema    Foros de discusión -> Intermedio Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group