Listas desplegables encadenadas con AJAX en jQuery

Este es un pequeño ejemplo de cómo realizar el efecto de listas encadenadas en Web.py usando AJAX.

El propósito es realizar una llamada asíncrona a la base de datos, según una lista desplegable de paises, para obtener las provincias de ese pais en una nueva lista desplegable.

Ficheros

/app.py  
/static:
    /static/jquery-1.7.2.js
/templates:
    /templates/formulario.html

Esquema Base de Datos

Tabla País:

CREATE TABLE pais( id serial, codigo char(3), descrip varchar(50) NOT NULL UNIQUE, ubicacion point, PRIMARY KEY (codigo));

Tabla Departamentos:

CREATE TABLE departamentos(id serial,codigo char(2), descrip varchar(50) NOT NULL UNIQUE, ubicacion point, 
cod_pais char(3), PRIMARY KEY (codigo), FOREIGN KEY (cod_pais) REFERENCES pais(codigo) MATCH FULL on delete cascade on update cascade);

Cabe aclarar que en Colombia las provincias se conocen como departamentos.

Podes ingresar algunos datos para los paises:

 id  | codigo |                     descrip                     | ubicacion 
-----+--------+-------------------------------------------------+-----------
  42 | 169    | COLOMBIA                                        | 
  51 | 199    | CUBA                                            | 
  53 | 211    | CHILE                                           | 
  54 | 215    | CHINA                                           | 
  59 | 235    | DOMINICA                                        | 
  60 | 239    | ECUADOR                                         |

Y también ingresar algunos datos para los departamentos(provincias):

 id | codigo |      descrip       |        ubicacion         | cod_pais 
----+--------+--------------------+--------------------------+----------
  1 | 91     | Amazonas           | (-1.0197222,-71.9383333) | 169
  2 | 05     | Antioquia          | (7,-75.5)                | 169
  7 | 17     | Caldas             | (5.25,-75.5)             | 169
 12 | 27     | Chocó              | (6,-77)                  | 169
 13 | 25     | Cundinamarca       | (5,-74.1666667)          | 169
 30 | 76     | Valle del Cauca    | (3.75,-76.5)             | 169

/templates/formulario.html

$def with (paises)
<!DOCTYPE html>
<html>
    <head>
        <style type="text/css">

            body {font-family: Arial; color:#555;}

            #myForm label{display: block;}

            input.text {
                background: #FAFAFA none repeat scroll 0%;
                border: 1px solid #EEE;
                font-size: 18px;
                line-height: 20px;
                margin: 0pt;
                padding: 3px;
                width: 440px;
            }
        </style>
        <script src="static/jquery-1.7.2.js"></script>
        <script>
            jQuery(document).ready(function(){
               jQuery('#paises').change(function(){

                   // Obtenemos el valor del combo de los paises
                   var country = jQuery(this).val(),
                   // Seleccionamos el combo de las provincias
                   comboprovin = jQuery('#myForm :disabled');

                   // Habilitamos el combo de las provincias
                   jQuery(comboprovin).removeAttr('disabled');

                   var newElement = [];

                   jQuery.ajax({
                            url      : 'provincias',
                            data     : { 'pais' : country },
                            type     : 'GET',
                            dataType : 'json',

                            success  : function(json){
                                jQuery.each(json, function(index, obj){
                                    newElement.push('<option value=' + obj.codigo + '>' + obj.descrip + '</option>');
                                });
                            jQuery(comboprovin).find(':first').before(newElement.join(''));
                            },

                            error    : function(jqXHR, status, error){
                                console.log("Se produjo un error: " + error);
                            },

                            complete : function(jqXHR, status){
                                console.log("Petición terminada con estado: " + status);
                                console.log(jqXHR);
                            }

                       }); 
               });

            });
        </script>
    </head>
    <body>
       <form id="myForm" action="infouser" method="post">
        <label>Nombre completo</label>
        <input type="text" id="nombre" name="usuario" size="50">
        <label>Documento</label>
        <input type="text" id="documento" name="documento" size="30">
        <label>E-Mail</label>
        <input type="text" id="email" name="email" size="30">
        <h2>Direcci&oacute;n</h2>
        <label>Pa&iacute;s</label>
        <select name="pais" id="paises">
            <option value="None">< -- Seleccione Un Pa&iacute;s -- ></option>
            $for opt in paises:
                <option value="$opt['codigo']">$opt['descrip']</option>
        </select>
        <label>Provincia</label>
        <select name="provincia" id="provincias" disabled="disabled">
            <option value="None">  Seleccione Una Provincia </option>
        </select>
        <br />
        <br />
        <label>$:('-'*90)</label>
        <input type="submit" value="Registrar">
       </form>
    </body>
</html>

/app.py

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import web
import json

plantilla = web.template.render('templates')

dB = web.database(dbn='postgres', user='postgres', pw='qwerty', db='myweb')

urls = (
            '/', 'root',
            '/provincias', 'provincias',
            '/infouser', 'infoUser',
        )

app = web.application(urls, globals())

class root:
    def GET(self):
        """ Muestra la página """
        paises = dB.select('pais')
        return plantilla.formulario(paises)

class provincias:
    """ 
        Obtiene los datos de las provincias y las envia en 
        formato JSON
    """
    def GET(self):
        inputdata = web.input()
        query = 'SELECT codigo, descrip FROM departamentos WHERE cod_pais = ' + '\'' + str(inputdata.pais.encode('UTF-8') + '\'')
        provincias = dB.query(query)
        web.header('content-Type', 'application/json')
        return json.dumps([row for row in provincias])

class infoUser:
    """ Muestra los datos enviados por el formulario """
    def POST(self):
        inputdata = web.input()
        return inputdata

if __name__ == "__main__": app.run()

Debes recordar descargar jQuery e incluirlo en la ubicación indicada, como lo muestra la estructura de los ficheros.

Al ejecutar el App y ya que solo tenemos provincias en nuestra base de datos para el país de Colombia, solo nos mostrará las provincias para éste.

Autor: Jolth

Anuncios

2 pensamientos en “Listas desplegables encadenadas con AJAX en jQuery

  1. Pingback: 50 Técnicas Ajax imprescindibles para diseñadores

  2. Pingback: 50 Técnicas Ajax imprescindibles para desarrolladores web

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s