La Página de DriverOp

Plugin JQuery para autocompletar un input desde el servidor.

Porque me cansé de probar autocompletadores que tienen todo mal hecho o hecho a la necesidad del programador del plugin y no de quien lo va a usar. Esta es mi versión.

Contenido.

1. Objetivo del plugin.

Se trata de un plugin para JQuery similar a "autocomplete" pero que no requiere JQuery-UI y va directo al punto. El plugin le muestra al visitante un descolgable debajo del input donde está tipeando, una serie de coincidencias parciales extraidas desde el servidor web mediante peticiones AJAX.

A diferencia de otros autocompletadores, este es muy sencillo. No pretende hacer más de lo que se propone. Y además permite que desde el servidor se le envíen una arbitraria cantidad de datos que luego, tú, el programador, puede usar en el script JavaScript según lo que el visitante del sitio haya seleccionado.

La estética se controla desde un archivo CSS y el descolgable acompaña al input al cual está enlazado haciendo que el descolgable se adapte al cambio de tamaños de la ventana.

Eres libre de usar, modificar, hacer trabajos derivados, de acuerdo a la licencia LGPL, tal como se describe aquí: http://www.gnu.org/licenses/lgpl.html.

2. Requisitos previos.

Requiere JQuery, por supuesto. Lo he desarrollado usando JQuery ver 1.9.1 (del 2012) pero como me he limitado a usar lo justo y necesario de él, supongo que podría funcionar sin problemas con versiones anteriores.

He usado llamadas a métodos/funciones nativas de JavaScript cuando es posible en vez de usar su equivalente JQuery para acelerar la ejecución y no causar incompatibilidades indeseadas. De la misma manera creo que esas llamadas son estándar en los navegadores modernos.

Estos son los métodos JQuery que he usado: each(), extend(), append(), on(), empty(), children(), first(), last(), next(), prev(), addClass(), removeClass(), ajax(), hide() y attr().

Requiere que se cargue el archivo "frmAutocomplete.css" el cual tiene los estilos necesarios para que el descolgable se muestre correctamente.

Puedes modificar ese archivo para adaptar la estética del descolgable a la de tu web. Ten en cuenta también que ese archivo carga un archivo .gif (el rulo que le indica al visitante que algo está sucediendo en el fondo) pero no es escencial a la funcionalidad del plugin.

Requiere que del lado del servidor, haya un script (en PHP o cualquier otro lenguaje del lado del servidor) que sirva una estructura JSON. Concretamente un array donde cada elemento puede ser un string simple o un objeto. Más adelante en este documento se describe como puede ser la respuesta JSON.

3. Cómo se usa.

3.1 Opciones.

Como es un plugin muy sencillo, tiene solo tres opciones (por ahora, más adelante veremos...), estas son:

source:
Es la opción más importante. Es un string con la URL completa hacia el servidor apuntando al script del servidor que servirá la estructura JSON de la cual se alimenta el descolgable para mostrarle al visitante los resultados parciales de lo que está tipeando en el input.

select:
Es una función que se ejecutará cuando el visitante seleccione una de las propuestas mostradas en el descolgable (haciendo clic o dando Enter). Esta función recibe dos parámetros, el elemento <li> que compone el resultado seleccionado, y el dato devuelto por el resultado. Más detalles sobre esto, más adelante, en los ejemplos.

delay:
Es el retardo en milisegundos que el plugin espera desde que se pulsa una tecla en el input y el inicio de la petición AJAX al servidor. Esto sirve para retrasar esas peticiones mientras el visitante tipea en el input, de lo contrario se generaría una petición por cada pulsación de tecla, lo que atoraría el servidor web con peticiones. Por omisión el valor es 250.

3.2 La petición al servidor.

Cuando el plugin dispara la petición AJAX al servidor le envía por POST (HTTP REQUEST POST) un parámetro con nombre term que contiene lo que el visitante ha tipeado hasta ese momento en el input al cual el plugin está asociado.

Puedes agregar tus parámetros por GET en la opción source si quieres pasar alguna otra cosa. Hay un ejemplo de esto más adelante en este documento.

El servidor debe responder con una estructura JSON compuesta por un array. Cada posición del array puede ser un string o un objeto JSON.

Si es un array de strings tal como:

["Resultado 1","Resultado 2","Resultado 3"]

El plugin usará cada string para formar cada una de las posibles opciones que el visitante puede seleccionar.

Si el servidor responde con un array de objetos, tal como:

[{"label":"Resultado 1"},{"label":"Resultado 2"},{"label":"Resultado 3"}]

Uno de los campos de cada objeto en el array debe llamarse "label". El plugin usará el contenido de ese campo para formar las opciones presentadas al visitante.

La totalidad del objeto será almacenada y luego pasada como parámetro a la función apuntada por select cuando se establecen las opciones del plugin.

Si además, en el objeto se incluye un campo llamado "value", tal como:

[{"label":"Esto es el resultado 1","value":"Resultado 1"},{"label":"Este es Resultado 2","value":"Resultado 2"},{"label":"Resultado 3"}]

Entonces el plugin usará ese campo para reemplazar lo que el visitante haya escrito en el input. Pero seguirá presentando label en las opciones del descolgable.

Como se ve en el ejemplo, no es obligatorio que todos los objetos tengan estos dos campos, o que cada posición del array sea homogeneo (es decir, que todos tengan idéntica estructura).

4. Ejemplos.

En este ejemplo, el visitante tiene que seleccionar un país de una lista. Para ello, primero hay que confeccionar el script del lado del servidor, en este caso en PHP, que tome la palabra parcial del visitante (tomando el parámetro POST 'term' que el plugin envía), dispare una consulta sobre una tabla de una base de datos (la tabla está incluida en la descarga, más abajo), arme el array de resultados y se lo envíe de regreso al cliente, es decir, al plugin.

Código del script PHP

Este es el código del script PHP del lado del servidor.

<?php
require_once("class.dbutil.inc.php");

$db = new cDB();
$db->Connect("localhost", "test", "tuusuario", "tucontrasena"); // Cambiá por tus datos de acceso.

$db->SetUTF8();

$resultado = array();
$term = strtolower(substr(trim(@$_POST['term']),0,25)); // Limpiar un poco lo que el usuario envía.

$term = $db->RealEscape($term);


$sql = "SELECT * FROM `paises` WHERE LOWER(`nombre`) LIKE LOWER('".$term."%') LIMIT 10;";

$db->Query($sql);
if (!$db->error) {
	if ($fila = $db->First()) {
		do {
			$aux = array(
				'label'=>$fila['nombre'],
				'value'=>$fila['nombre'],
				'tld'=>$fila['tld'],
				'id'=>$fila['id']
			);
			$resultado[] = $aux;
		} while($fila = $db->Next());
		echo json_encode($resultado);
	} else {
		echo '[]'; // Consulta vacía
	}
} else {
	echo '[]'; // Consulta vacía
}
$db->Disconnect();
?>

Notar que uso la clase DBUtil explicada aquí por conveniencia. Sírvete leer aquél articulo para entender mejor el código.

Luego de establecer la conexión a la base de datos, se toma el parámetro term, se lo limpia un poco, se neutraliza cualquier caracter que pueda interferir con la consulta SQL. Luego se arma la consulta y se ejecuta.

Durante el ciclo while de PHP se almacena en el array $resultado cada uno de los registros devueltos por la consulta SQL estableciendo los campos label y value, y dos campos más que luego serán útiles en el script JavaScript.

Finalmente se usa la función PHP json_encode() para devolver el resultado en formato JSON.

En caso de error, o cuando la consulta no devuelve resultados, se devuelve un array vacío.

Código HTML.

Este es el código del formulario, solo la parte HTML:

<form name="frmEjemplo1" id="frmEjemplo1" onSubmit="return false;">
	<p>
		<label class="" for="pais">Pais:</label>
		<input type="text" name="pais" id="pais" value="" />
	</p>
	<p>Selección: <span id="seleccion">(ninguna)</span></p>
</form>
Código JavaScript.

Y ahora sí, la declaración necesaria en JavaScript para hacer funcionar el plugin:

<script type="text/javascript">
$(document).on("ready", function () {
	$("#pais").frmAutocomplete({
		source: 'paises.php',
		select: GetSelected,
		delay: 250
	});
});

function GetSelected(elLI, data) {
	document.getElementById('seleccion').innerHTML = 'Pais: '+data.value+'. TLD: '+data.tld;
}
</script>

Ver demo del ejemplo.

5. Descarga.

Se incluye el código JavaScript del plugin, el archivo CSS correspondiente, el gif animado, el código del script PHP antes mostrado y la tabla SQL paises usada como ejemplo.

jquery.frmAutocomplete.zipJQuery frmAutocomplete ver 1.0 para JQuery (8,86 KB)

Por Diego Romero,