Cómo utilizar el widget de autocompletado de la interfaz de usuario de jQuery
Spanish (Español) translation by Vukica (you can also view the original English article)
En este tutorial veremos uno de los componentes más nuevos de jQuery UI 1.8: el widget de Autocompletar. Los campos de texto de autocompletar pueden ser una opción popular entre los visitantes de tu sitio porque facilitan mucho la introducción de información. Se pueden usar en campos de búsqueda de productos, por ejemplo, o cuando un visitante debe ingresar a un país, una ciudad o cualquier otra cosa que pueda ser una opción de un conjunto de datos común. Además de ser popular entre los visitantes, jQuery UI Autocomplete es popular entre los desarrolladores porque es fácil de usar, potente y flexible.
No soy un gran fan de Facebook, prefiero Twitter (@danwellman por cierto), pero una característica de Facebook que me gusta es la función de mensajería que te permite enviar un mensaje a un amigo o amigos. Me gusta cómo se usa el autocompletar para facilitar la selección de los nombres de tus amigos, y cómo se formatean los nombres una vez que se han seleccionado y agregado al campo 'para', p. cada uno tiene un vínculo cercano que permite que el nombre se elimine fácilmente sin tener que seleccionar ningún texto.
En este tutorial usaremos el widget de autocompletar de la interfaz de usuario de jQuery para replicar este aspecto del sistema de mensajería de Facebook. Sin embargo, no veremos el envío de mensajes. Esto es lo que vamos a crear:

Paso 1 Comenzando
Necesitaremos crear una descarga personalizada de jQuery UI que contenga solo los componentes que necesitamos; dirígete al generador de descargas en http://jqueryui.com/download. Necesitaremos utilizar los siguientes componentes principales:
- Centro
- Widget
- Posición
También necesitaremos el widget de Autocompletar, así que asegúrate de que solo los elementos anteriores, así como Autocompletar, estén marcados en la sección Componentes a la izquierda. Utiliza el tema predeterminado (UI Lightness) y asegúrate de que la versión 1.8 esté seleccionada a la derecha.
Una vez descargado, crea una nueva carpeta en tu computadora y llámala autocompletar. Luego abre el archivo y copia las carpetas css y js en la nueva carpeta que acabas de crear. Esto te proporcionará todos los archivos de biblioteca necesarios para este ejemplo, incluido el propio jQuery, por lo que no es necesario descargarlo por separado.
Paso 2 El HTML subyacente
Primero que nada, veamos el HTML del <form>:
1 |
<div id="formWrap"> |
2 |
<form id="messageForm" action="#"> |
3 |
<fieldset>
|
4 |
<legend>New message form</legend> |
5 |
<span>New Message</span> |
6 |
<label id="toLabel">To:</label> |
7 |
<div id="friends" class="ui-helper-clearfix"> |
8 |
<input id="to" type="text"> |
9 |
</div>
|
10 |
<label>Subject:</label> |
11 |
<input id="subject" name="subject" type="text"> |
12 |
<label>Message:</label> |
13 |
<textarea id="message" name="message" rows="5" cols="50"></textarea> |
14 |
<button type="button" id="cancel">Cancel</button> |
15 |
<button type="submit" id="send">Send</button> |
16 |
</fieldset>
|
17 |
</form>
|
18 |
</div>
|
Es una forma bastante estándar; hay un contenedor externo <div> que podemos usar para diseñar y el <input> al que se adjuntará Autocompletar también está dentro de un elemento <div>; aplicaremos un estilo al <div> para que quede ligeramente oculto, y aplicaremos un estilo al <div> para que se parezca a los demás campos del formulario. Le damos al contenedor para <input> el nombre de la clase ui-helper-clearfix para hacer uso de esta clase de utilidad del marco CSS de jQuery UI.
También necesitaremos vincularnos a los archivos que desempaquetamos del archivo jQuery UI, así como una hoja de estilo personalizada; los siguientes archivos deben ir al <head> de la página:
1 |
<link rel="stylesheet" type="text/css" href="css/ui-lightness/jquery-ui-1.8.custom.css"> |
2 |
<link rel="stylesheet" type="text/css" href="css/autocomplete.css"> |
Los siguientes archivos deben ir al final del <body>:
1 |
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script> |
2 |
<script type="text/javascript" src="js/jquery-ui-1.8.custom.min.js"></script> |
Paso 3 Diseñando el formulario

Usamos un tema neutral y muy simple en este ejemplo, la mayoría de los cuales son puramente un ejemplo. Se requieren muy pocos de los estilos y la mayoría se puede cambiar si es necesario. El siguiente CSS se utiliza en la hoja de estilo autocomplete.css (todo el estilo de la interfaz de usuario de jQuery está en la hoja de estilo jquery-ui-1.8.custom.css):
1 |
#formWrap { |
2 |
padding:10px; position:absolute; float:left; background-color:#000; |
3 |
background:rgba(0,0,0,.5); -moz-border-radius:10px; |
4 |
-webkit-border-radius:10px; border-radius:10px; |
5 |
}
|
6 |
#messageForm { |
7 |
width:326px; border:1px solid #666; background-color:#eee; |
8 |
}
|
9 |
#messageForm fieldset { |
10 |
padding:0; margin:0; position:relative; border:none; |
11 |
background-color:#eee; |
12 |
}
|
13 |
#messageForm legend { visibility:hidden; height:0; } |
14 |
#messageForm span { |
15 |
display:block; width:326px; padding:10px 0; margin:0 0 20px; |
16 |
text-indent:20px; background-color:#bbb; |
17 |
border-bottom:1px solid #333; font:18px Georgia, Serif; color:#fff; |
18 |
}
|
19 |
#friends { |
20 |
width:274px; padding:3px 3px 0; margin:0 auto; |
21 |
border:1px solid #aaa; background-color:#fff; cursor:text; |
22 |
}
|
23 |
#messageForm #to { |
24 |
width:30px; margin:0 0 2px 0; padding:0 0 3px; |
25 |
position:relative; top:0; float:left; border:none; |
26 |
}
|
27 |
#messageForm input, #messageForm textarea { |
28 |
display:block; width:274px; padding:3px; margin:0 auto 20px; |
29 |
border:1px solid #aaa; |
30 |
}
|
31 |
#messageForm label { |
32 |
display:block; margin:20px 0 3px; text-indent:22px; |
33 |
font:bold 11px Verdana, Sans-serif; color:#666; |
34 |
}
|
35 |
#messageForm #toLabel { margin-top:0; } |
36 |
#messageForm button { float:right; margin:0 0 20px 0; } |
37 |
#messageForm #cancel { margin-right:20px; } |
38 |
#friends span { |
39 |
display:block; margin:0 3px 3px 0; padding:3px 20px 4px 8px; |
40 |
position:relative; float:left; background-color:#eee; |
41 |
border:1px solid #333; -moz-border-radius:7px; |
42 |
-webkit-border-radius:7px; border-radius:7px; color:#333; |
43 |
font:normal 11px Verdana, Sans-serif; |
44 |
}
|
45 |
#friends span a { |
46 |
position:absolute; right:8px; top:2px; color:#666; |
47 |
font:bold 12px Verdana, Sans-serif; text-decoration:none; |
48 |
}
|
49 |
#friends span a:hover { color:#ff0000; } |
50 |
.ui-menu .ui-menu-item { white-space:nowrap; padding:0 10px 0 0; } |
Para darle al formulario un bonito borde transparente con esquinas redondeadas, usamos la regla CSS3 RGBa y las reglas -moz-border-radius, -webkit-border-radius y border-radius; Los navegadores más populares ahora admiten estas reglas, incluidos Firefox, Safari, Chrome y Opera. IE no es compatible con ninguno de ellos y, aunque puede usar un filtro para implementar una opacidad rudimentaria, las esquinas redondeadas deberían ser compatibles con el uso de imágenes. La efectividad de la transparencia RGBa no se muestra al máximo en este ejemplo; pero este tipo de formulario probablemente se usaría como una superposición modal flotante en una implementación completa, que se ubicaría sobre el contenido real de la página.
El contenedor <div> alrededor del campo <input> al que se adjuntará el campo de texto Autocompletar tiene la misma posición y estilo que los elementos <input>, pero el <input> dentro de este contenedor tiene su borde eliminado para que sea oculto. También reducimos su ancho y lo flotamos hacia la izquierda. Esto es para que cuando agreguemos los destinatarios formateados al <div>, el <input> no se desbordará y aumentará la altura del <div> innecesariamente.
También aplicamos estilo a los destinatarios, que se agregarán al <div> como elementos <span> que contienen un enlace. En su mayoría, estos están diseñados para que coincida con el tema básico y también tienen esquinas redondeadas. Es importante que estos elementos estén hechos a nivel de bloque y también floten para que se apilen correctamente. También necesitamos anular algunos de los estilos de Automcomplete proporcionados por el tema jQuery UI que estamos usando; el último selector simplemente evita que las sugerencias individuales en el menú se rompan entre palabras, lo que sucede porque hemos hecho que el <input> al que está asociado sea tan pequeño.
En esta etapa, el formulario debería aparecer así:

Paso 4 Adjuntar el autocompletado
A continuación, debemos adjuntar el widget de Autocompletar al <input> dentro del <div>; para hacer esto podemos usar el siguiente script:
1 |
<script type="text/javascript"> |
2 |
$(function(){
|
3 |
|
4 |
//attach autocomplete |
5 |
$("#to").autocomplete({
|
6 |
|
7 |
//define callback to format results |
8 |
source: function(req, add){
|
9 |
|
10 |
//pass request to server |
11 |
$.getJSON("friends.php?callback=?", req, function(data) {
|
12 |
|
13 |
//create array for response objects |
14 |
var suggestions = []; |
15 |
|
16 |
//process response |
17 |
$.each(data, function(i, val){
|
18 |
suggestions.push(val.name); |
19 |
}); |
20 |
|
21 |
//pass array to callback |
22 |
add(suggestions); |
23 |
}); |
24 |
}, |
25 |
|
26 |
//define select handler |
27 |
select: function(e, ui) {
|
28 |
|
29 |
//create formatted friend |
30 |
var friend = ui.item.value, |
31 |
span = $("<span>").text(friend),
|
32 |
a = $("<a>").addClass("remove").attr({
|
33 |
href: "javascript:", |
34 |
title: "Remove " + friend |
35 |
}).text("x").appendTo(span);
|
36 |
|
37 |
//add friend to friend div |
38 |
span.insertBefore("#to");
|
39 |
}, |
40 |
|
41 |
//define select handler |
42 |
change: function() {
|
43 |
|
44 |
//prevent 'to' field being updated and correct position |
45 |
$("#to").val("").css("top", 2);
|
46 |
} |
47 |
}); |
48 |
}); |
49 |
</script> |
El widget se adjunta a <input> mediante el método autocomplete (). Proporcionamos un objeto literal como argumento para el método, que configura la opción de fuente y las devoluciones de llamada de eventos de selección y cambio.
La opción fuente se utiliza para indicarle al widget de dónde obtener las sugerencias para el menú Autocompletar. Usamos una función como valor de esta opción, que acepta dos argumentos; el primero es el término ingresado en <input>, el segundo es una función de devolución de llamada que se usa para pasar las sugerencias al widget.
Dentro de esta función usamos el método getJSON() de jQuery para pasar el término a un archivo PHP del lado del servidor. El archivo PHP usará el término para extraer nombres de contactos coincidentes de una base de datos MySql. Usamos una devolución de llamada JSONP para procesar los datos devueltos por el servidor; la función de devolución de llamada que se pasa como segundo argumento a la opción de origen espera recibir los datos en una matriz, por lo que primero creamos una matriz vacía y luego usamos el método each() de jQuery para procesar cada elemento en la matriz JSON devuelta por el servidor . Simplemente iteramos sobre cada elemento de esta matriz y agregamos cada sugerencia a nuestra nueva matriz. Una vez que se construye nuestra nueva matriz, la pasamos a la función de devolución de llamada para que el widget se muestre en el menú.
Luego definimos un controlador para el evento de selección personalizado de Autocompletar; esta función será ejecutada por el widget cada vez que se seleccione una sugerencia en el menú Autocompletar. A esta función se le pasan automáticamente dos argumentos: el objeto de evento y ui objeto de interfaz de usuario que contiene la sugerencia que se seleccionó. Usamos esta función para formatear el nombre del destinatario y agregarlo al <div>. Simplemente creamos un elemento <span> para contener el texto y un elemento de anclaje que se puede usar para eliminar el destinatario. Una vez que se ha creado el destinatario formateado, simplemente lo insertamos directamente antes del <input> camuflado.
Por último, agregamos un controlador para el evento de cambio; esta función se invocará siempre que cambie el valor del <input> con el que está asociado el Autocompletar. Simplemente lo usamos para eliminar el valor de <input> porque ya hemos agregado la versión formateada a nuestro contenedor <div>. El quilate se ve un poco alto una vez que se ha agregado un nombre de contacto formateado al <div>, por lo que también usamos este controlador de eventos para corregir esto.
Esta es toda la configuración que necesitamos para esta implementación en particular, pero todavía hay un par de funciones adicionales que necesitamos agregar para arreglar un poco las cosas. Después del método autocomplete() agrega el siguiente código:
1 |
//add click handler to friends div |
2 |
$("#friends").click(function(){
|
3 |
|
4 |
//focus 'to' field |
5 |
$("#to").focus();
|
6 |
}); |
7 |
|
8 |
//add live handler for clicks on remove links |
9 |
$(".remove", document.getElementById("friends")).live("click", function(){
|
10 |
|
11 |
//remove current friend |
12 |
$(this).parent().remove(); |
13 |
|
14 |
//correct 'to' field position |
15 |
if($("#friends span").length === 0) {
|
16 |
$("#to").css("top", 0);
|
17 |
} |
18 |
}); |
El <input> al que se adjunta nuestro Autocompletar está parcialmente oculto y su contenedor <div> tiene un estilo para que aparezca como los otros campos en el formulario; para completar el engaño, agregamos un controlador de clics al contenedor <div> para que al hacer clic en cualquier lugar dentro de él se enfoque el <input> real. Desde el punto de vista visual y funcional, el <div> debería ser indistinguible de un campo normal.
También necesitamos manejar los clics en el ancla que se agrega a cada destinatario formateado; usamos el método live() de jQuery porque estos elementos pueden o no existir en la página en un momento dado y es más fácil que vincular la función del controlador cada vez que creamos uno de estos anclajes. Siempre que se hace clic en uno de estos anclajes, todo lo que hacemos es navegar hasta el padre del ancla en el que se hizo clic y luego eliminarlo de la página. ¿Recuerdas cuando corregimos la posición del quilate anteriormente en el guión? Solo necesitamos verificar si se han eliminado todos los destinatarios y, de ser así, restablecer su posición a la predeterminada.
Paso 5 Código y recursos adicionales
Usé una base de datos MySql que contiene una tabla que enumera cada uno de los nombres de los destinatarios y el siguiente archivo PHP para aceptar los datos enviados por el método getJSON() y extraer destinatarios coincidentes de la base de datos:
1 |
<?php |
2 |
|
3 |
//connection information |
4 |
$host = "localhost"; |
5 |
$user = "root"; |
6 |
$password = "your_mysql_password_here"; |
7 |
$database = "test"; |
8 |
$param = $_GET["term"]; |
9 |
|
10 |
//make connection |
11 |
$server = mysql_connect($host, $user, $password); |
12 |
$connection = mysql_select_db($database, $server); |
13 |
|
14 |
//query the database |
15 |
$query = mysql_query("SELECT * FROM friends WHERE name REGEXP '^$param'");
|
16 |
|
17 |
//build array of results |
18 |
for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
|
19 |
$row = mysql_fetch_assoc($query); |
20 |
|
21 |
$friends[$x] = array("name" => $row["name"]);
|
22 |
} |
23 |
|
24 |
//echo JSON to page |
25 |
$response = $_GET["callback"] . "(" . json_encode($friends) . ")";
|
26 |
echo $response; |
27 |
|
28 |
mysql_close($server); |
29 |
|
30 |
?> |
Para ejecutar los archivos de ejemplo descargables, necesitarás un servidor web de desarrollo con PHP instalado y configurado, así como MySql y la base de datos y la tabla adecuadas. Cuando se escribe una letra en el campo 'para', esta letra se pasa al servidor y se utiliza para extraer cada nombre que comienza con la letra que se escribió. Los nombres coincidentes se devuelven a la página como JSON y se muestran en el menú de sugerencias:

Este tutorial mostró cómo replicar el formulario de envío de mensajes de Facebook, específicamente, la forma en que se agregan amigos al formulario de mensajería como destinatarios mediante Autocompletar, y cómo se formatean los nombres de los amigos una vez que se han agregado para que puedan eliminarse fácilmente. Nuestro formulario de ejemplo en realidad no hace nada, pero lo que tendríamos que hacer para enviar el formulario sería pasar el contenido del formulario a un archivo del lado del servidor para enviarlo usando AJAX, que podría conectarse fácilmente al envío. evento del botón enviar utilizado en el formulario.
Los destinatarios tendrían que tener algún tipo de significado para el sistema de back-end, por supuesto, y probablemente se asignarían a direcciones de correo electrónico en la base de datos. Necesitaríamos recuperar el contenido textual de cada uno de los elementos <span> antes de volver al servidor, aunque esto sería un asunto bastante trivial.
El widget jQuery UI Autocomplete facilita la conexión a cualquier fuente de datos y contiene un rico conjunto de controladores de eventos a los que podemos proporcionar funciones para reaccionar al texto que se ingresa en el campo asociado, o una sugerencia que se selecciona en el menú. El widget está diseñado utilizando el extenso marco CSS de jQuery UI y se puede cambiar fácilmente para que coincida con el tema de su sitio existente. Considerándolo todo, es un excelente widget que es fácil de usar y proporciona una gran funcionalidad.



