En la entrada semanal de nuestro blog relacionado con cakephp, vamos a hablar sobre autocompletar los campos mediante ajax, una opción que puede simplificar bastante la inserción de datos por parte de los usuarios y que a su vez resulta bastante elegante.
El funcionamiento es sencillo, al introducir una letra en un campo de entrada se buscarán en la base de datos las coincidencias con el texto que hemos insertado, mostrándolas como una lista y dándonos la opción de elegir entre todos los resultados.
Esta opción se usa habitualmente con los listados de paises, en nuestro ejemplo utilizaremos, como en el ejemplo de actualizar un select con ajax, las provincias españolas.
En este enlace se puede comprobar el funcionamiento.
Añadirlo en nuestro proyecto es realmente sencillo, supongamos que tenemos un modelo, cuyo controlador tiene una operación y una vista asociada, que será donde queremos utilizarlo.
Para ello en la vista, añadimos este trozo de código dentro de un formulario:
echo $form->label('provincias','Provincias');
echo $ajax->autoComplete('nombre','autocomplete');
Añadimos un label que tendrá el texto Provincias y un campo de entrada autocomplete, este recibe como parámetros, el nombre del campo y como segundo parámetro la url donde se encuentra la función a la que se va a llamar cuando se introduzca una letra, en nuestro caso, la vamos a añadir en el mismo controlador que estamos utilizando, si no fuese así la dirección sería ‘/nombre_del_controlador/función’.
En segundo lugar, creamos la función autocomplete, dentro del controlador utilizado añadimos el siguiente código:
function autocomplete()
{
$str = trim($this->data['Provincia']['nombre']);
$str = str_replace("á","a",$str);
$str = str_replace("é","e",$str);
$str = str_replace("í","i",$str);
$str = str_replace("ó","o",$str);
$str = str_replace("ú","u",$str);
$str = str_replace("Á","A",$str);
$str = str_replace("É","E",$str);
$str = str_replace("Í","I",$str);
$str = str_replace("Ó","O",$str);
$str = str_replace("Ú","U",$str);
$str = str_replace("Ñ","ñ",$str);
$condicion = "REPLACE (REPLACE( REPLACE( REPLACE( REPLACE( REPLACE ( Provincia.nombre,'á','a'), 'é','e'),'í','i'),'ó','o'),'ú','u'),'Ñ','ñ') LIKE "$str%"";
$this->set('provincias', Set::combine($this->Provincia->findAll($condicion,array('Provincia.nombre','Provincia.id'),'Provincia.nombre'), "{n}.Provincia.id","{n}.Provincia.nombre"));
$this->render('autocomplete','ajax');
}
La función es muy sencilla, realiza la búsqueda en la base de datos de todas las provincias cuyo nombre coincida con el texto introducido, pasado en $this->data con el nombre que se indica en el primer parámetro de la función autocomplete utilizada en la vista, para eso se añade en la condición la opción LIKE cadena% de sql.
Todas las opciones que añadimos anteriormente sirven para ignorar los acentos, tanto en la cadena que introducimos como en los nombres de las provincias almacenadas en la base de datos, con esto al realizar la búsqueda funcionará aunque cometamos fallos ortográficos.
Crearemos una vista para esta función, con una única línea de código, que crea una lista con todas las entradas del array.
echo $html->nestedList($provincias);
Y por último añadiremos al css que estemos utilizando, dos clases que modificarán el aspecto del listado que hemos creado:
div.auto_complete {
position :absolute;
width :250px;
background-color :white;
border :1px solid #888;
margin :0px;
padding :0px;
}
div.auto_complete ul{
list-style: none;
margin: 0px;
}
li.selected{
background-color: #ffb;
}
Con esto ya tendremos un campo de texto en el que al añadir texto se generará un listado con todas las entradas de la base de datos que coincidan con el texto introducido.
