TUTORIAL- AutoComplete Extender, Autocompletando desde la Base de datos

Si bien muchas veces hablamos de lo último que viene saliendo, también hay que darse un tiempo de hablar sobre lo que está y se utiliza poco, he visto a varios desarrolladores ASP.NET que no aprovechan este herramienta del Ajax Control Toolkit, de hecho fue por esto que me propuse la tarea de hacer un ScreenCast y un artículo que cada uno de los controles del Ajax Control Toolkit. Pero basta de hablar de mi, hablemos del Control AutoComplete.

Recuerda siempre que puedes ver los demos, y bajar la Suite en el sitio de ASP.NET

Cual es la Idea del Control

La idea es que puedas tener una funcionalidad muy similar a la que tienes en Google, que va completando con sugerencias, a medida que vas escribiendo en la caja de texto.

image 

Nuestro Ejemplo, un buscador de películas

EL primer paso va a ser crear nuestra base de datos de Películas,  voy a agregar unas 15 películas para tener datos, la estructura es la siguiente:

image

Nuestro segundo Paso va a ser la creación de la Interfaz de Usuario. (Los colores son simple casualidad)

image

Nuestro tercer paso , será crear el WebService que nos va a permitir obtener los datos para el autocompletar:

image

Luego, Cuarto Paso va a ser codificar nuestro WebService:

  <WebMethod()> _

Public Function ObtListaPeliculas(ByVal prefixText As String, ByVal count As Integer) As String()

Dim con As New SqlConnection (ConfigurationManager.ConnectionStrings("EjemploConString").ConnectionString)

Dim comando As New SqlCommand("select PeliculaNombre from Peliculas where PeliculaNombre  LIKE ‘%’ + @param + ‘%’ ", con)
comando.Parameters.AddWithValue("param", prefixText)
        Dim dr As SqlDataReader
        comando.Connection.Open()
        dr = comando.ExecuteReader
        Dim lista As New List(Of String)
        While dr.Read
            lista.Add(dr.Item("PeliculaNombre"))
        End While
        comando.Connection.Close()
        Return lista.ToArray
    End Function

Si bien el código no quedo muy ordenado en el post, veamos a grosso modo lo que realiza, los parámetros de entrada son obligatorios, y aunque no los estamos utilizando, como decíamos, deben ir. En el código hacemos una consulta con Like, para ver las coincidencias en cualquier parte del texto del campo PeliculaNombre, luego recorremos estas coincidencias y las vamos guardando en una lista de String, para luego retornarlas, según nuestro ejemplo (y como lo veras abajo) este webservice se va a ejecutar cuando escribamos 2 letras en el Textbox.

Nuestro Quinto Paso , será extender nuestro control TextBox , cabe recordar que yo ya tengo instalado en mi Visual Studio el Ajax Control Toolkit 3.5. Si no lo tienes, debes ir a la página

http://www.asp.net/ajax/ajaxcontroltoolkit/samples/

En donde puedes ver una demo del control y además descargar la Suite.

image

Luego, como decíamos , extendemos el control, y seleccionamos la AutoCompleExtender

image

Esta acción nos va a generar el siguiente código declarativo, lo cual no es suficiente, deberemos configurar más opciones para que nuestro ejemplo funcione. También recuerda agregar un control ScripManager en tu página, es indispensable para que nuestro control funcione.

Código Generado:

<cc1:AutoCompleteExtender ID="tx_buscar_AutoCompleteExtender" runat="server" DelimiterCharacters="" Enabled="True" ServicePath="" TargetControlID="tx_buscar">                    </cc1:AutoCompleteExtender>

Y lo que tenemos que configurar:

<cc1:AutoCompleteExtender ID="tx_buscar_AutoCompleteExtender" runat="server" enabled="True"
servicepath="BuscarPeliculas.asmx" minimumprefixlength="2" servicemethod="ObtListaPeliculas" enablecaching="true" targetcontrolid="tx_buscar" usecontextkey="True" completionsetcount="10"                                completioninterval="200" >
</cc1:AutoCompleteExtender>

Y Veamos los parámetros importantes:

  • servicepath : Corresponde al nombre del Webservice.

  • ServiceMethod : Corresponde al nombre del WebMethod del WebService
  • minimumprefixlength: corresponde a la cantidad mínima de caracteres antes de que se llame al WebService, esto es importante, ya que si dejas la cantidad mínima para un gran conjunto de datos, por la naturaleza del filtro, puede que tu consulta se demore un buen resto antes de entregar los datos.

  • targetcontrolid: Corresponde al control textbox en el que se va a ingresar el texto.

  • CompletionSetCount: Corresponde a la cantidad de resultados que quieres que se muestren en el autocomplete.
  • CompletionInterval : Corresponde a la cantidad de milisegundos antes de que se muestre la lista.

Para ver más detalles puedes ir a:
http://www.asp.net/AJAX/AjaxControlToolkit/Samples/AutoComplete/AutoComplete.aspx

Sexto Paso: Ahora a probarlo!

Al escribir Los  por la naturaleza de la Query (La sentencia Like que va a buscar la coincidencia de la cadena de texto en cualquier parte del campo a consultar) vamos a obtener:

image

Ahora veámoslo en Acción, con un Video 🙂

DESCARGA TODO EL EJEMPLO ACA

Espero que te sirva, cualquier duda o comentario, no dudes en consultar 🙂
Saludos y Feliz Año nuevo 2010!

Gonzalo

58 comentarios en “TUTORIAL- AutoComplete Extender, Autocompletando desde la Base de datos”

  1. En google la funcionalidad es casi inmediata…en una aplicación así se notaría retardo cada vez que escribes en la caja de texto, no ??? se puede mejorar esa sensación ??

    gracias !!1 feliz añooooo

  2. Hola Preguntón, puedes setear la propiedad CompletionInterval en Cero para que no exista retardo programado (solo el propio de la bd)
    Saludos!

  3. Hola, me gustaría saber como puedo capturar el id del item que he seleccionado,es lo que necesito por favor, estoy buscando en muchos foros pero no encuentro nada.. por favor ayudenme!

  4. Obed, lamentablemente este control por definición solo obtiene un string, extendiendo el control podrías hacerlo. O la solución facil, pero no tan optima(pero se ocupa, creeme) es obtener el ID a partir del texto, se entiende?

  5. Hola, yo implemente este control en una pagina y no puedo controlar los items que muestra, siempre me muestra los mismos, estoy haciendo lago mal?

  6. Una pregunta,

    si haciendo la consulta a la base de datos no hay coincidencias, y poniendo este texto para que lo devuelva el array, puede deshabilitarse el control para que no lo ponga en el textbox??

    Saludos

  7. hola que pena, lo que pasa es que lo probe y me funciona correctamente con mi bd y todo, pero cuando lo voy a implementar en mi proyecto no me funciona no me hace nada, nisiquiera me funcionan los puntos de interrupcion cuando le hago seguimiento,,,,, y necesito que me fucnione bn urgente, podrias ayudarme por favor…

  8. @risras, Se puede pero programandolo, es decir, si no hay coincidencia (puedes ver el articulo de lostfocus) borras lo que se escribio y dejas el textbox desabilitado.

  9. @andreaq
    Osea localmente te funciona, en y luego, cuando haces deploy, en el servidor no funciona, que version de asp.,net estas ocupando, que version de microsoft ajax y que version del ajax control toolkit estas usando?

  10. Amigo Gonzalo, tengo un problemilla con el AutoComplete Extender. Resulta que quiero mostrar una lista de Ciudades en un textbox a medida que ingreso un texto.
    En el WebService, tengo mi funcion Obtener() que funciona a la perfeccion siempre y cuando no le mande parametros. Cuando le agrego un parametro, como por ejm tienes tu el prefixText el autocompletado deja de funcionar. Es decir siempre muestra todas las ciudades sin importar el texto que ingrese…

  11. Enviame el código de ejemplo a: chalalo “..arroba..” hotmail punto com, ejejje, para que los robots no me carguen el correo.

    Bueno, me lo envias y lo reviso, eso si, lo reviso desde el jueves en adelante, que estoy fuera de mi country sin mucho acceso a Inet.

  12. Amigo, ante nada gracias por tu pronta respuesta.
    Te comento que pude lidiar con el problemilla, era una tontes, resulta que en el WebService le mandaba un parametro con cualquier nombre, y al parecer solo acepta el nombre “prefixText”. Lei por ahi que el AutoComplete no anda en la ultima version de Firefox (3.6), estas al tanto del tema? sera cierto? Bueno, saludos, ahora me pongo a investigar la ModalPopup, tu sabes algo de ello??

  13. Hola Ignacio, sii, se me olvido mencionar que los parametros se deben llamar de esa manera, solo dije que eran obligatorios.
    Sobre el modal, estoy haciendo un Articulo, pero no creo que lo publique antes del lunes, si necesitas ayuda adicional y antes, me avisas !

    Sobre el tema de FireFox, lo voy a probar
    Saludos,
    g-

  14. Hola Muy buen tutorial, felicidades, sin embargo tengo la necesidad de que al desplegar el autocomplete me aparezca otra columna, similar a lo que hace google con la cantidad de resultados, sabes si es esto posible con autocompleteextender? o de algun sitio donde lo hayas visto?

  15. Hola…

    Gonzalo ya te envio mi codigo a tu correo, el error me lo manda en esta linea:

    Dim lista As New List(Of String)

    List(Of String) = Me marca que no esta definida.

  16. antes que nada entiendo y tengo todo solo que en mi sitio web (Intranet) no funciona el autocomplementar estoy haciendo algo mal no se si no ejecuta el webservice o que onda, como pruebo si el webservice se esta ejecutando?

    mi mail es cora.ben@gmail.com

    Saludos ……….

  17. Hola, colocale un punto de interrupcion al código del servicio, si pasa por ahi, seguro lo notarás.
    Para que se ejecute correctamente los parametros del Webmethod deben llamarse como indica el artículo.
    Puedes pegar el código por aca?

  18. tengo un problema,
    cuando obtengo una lista de codigos, por ejemplo 120567-4
    120887-3

    por el autocomplete me trae la resta, como hago para que no se respte, osea trae:

    120563
    120884

  19. hola, use tu ejemplo como referencia, muy bueno.
    mi problema es que al teclear algo en el textbox aparece la lista con varios elemento pero todos dicen undefined. Espero m puedas ayudar, gracias

  20. Lucci87,
    Revisa el nombre del campo:
    lista.Add(dr.Item(“PeliculaNombre”))

    Al parecer el retrieve desde la base esta con problemas, si quieres pega el código

  21. Hola

    Yo conozco una manera de guardar para cada item del autocomplete y text y un value y luiego al seleccionarlo obtener ambios valores, tal y como pedía más arriba obed:

    Para guardar el text y el value de cada item hay que añadir los valores en el array de esta manera:

    Lista.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(, ))

    Luego para obtener el valor seleccionado habría que añadir al evento onclientitemselected del autocomplete una llamda a una funcion javascript que obtuviera los valores, tal y como indico a continuación:

    function CodigoSeleccionado(source, eventArgs) {

    document.getElementById(‘< %= txtCodigo.ClientID %>‘).innerText = eventArgs.get_value();
    }

    Esto escribiría el value del item seleccionado en una textbox llamada txtCodigo

    Salu2

  22. este es mi codigo:

    dbConOracle = New OdbcConnection(myConnectionString)
    cmOracle = New OdbcCommand(“select cm_sort from cm_mstr WHERE cm_sort Like ‘” & prefixText & “‘”, dbConOracle)
    ‘cmOracle.Parameters.AddWithValue(“param”, prefixText)
    cmOracle.Connection.Open()
    drOracle = cmOracle.ExecuteReader

    While drOracle.Read
    listaNombres.Add(drOracle.Item(“cm_sort”))
    End While

    cmOracle.Connection.Close()

    Return listaNombres.ToString

  23. Hola, bueno lei que lo que necesita recibir el autocompleteextender es un arreglo de string y bueno hice algunos cambios a mi codigo, pero ahora ya no hace nada, escribo en el text box y no pasa absolutamente nada, este es mi codigo:

    Imports System.Web
    Imports System.Web.Services
    Imports System.Web.Services.Protocols
    Imports System.Data
    Imports System.Data.Odbc
    Imports System.Web.Script.Services
    Imports System.Collections.Generic

    _
    _
    _
    _
    Public Class AutoCom
    Inherits System.Web.Services.WebService

    _
    Public Function GetVINList(ByVal prefixText As String, ByVal count As Integer) As String()
    Dim listaNombres As New List(Of String)
    Dim dbConOracle As OdbcConnection
    Dim drOracle As OdbcDataReader
    Dim cmOracle As OdbcCommand

    dbConOracle = New OdbcConnection(myConnectionString)
    cmOracle = New OdbcCommand(“select cm_sort from cm_mstr WHERE cm_sort Like ‘%’ + @param + ‘%'”, dbConOracle)
    cmOracle.Parameters.AddWithValue(“param”, prefixText)
    cmOracle.Connection.Open()
    drOracle = cmOracle.ExecuteReader

    While drOracle.Read
    listaNombres.Add(drOracle.Item(“cm_sort”))
    End While

    cmOracle.Connection.Close()

    Return listaNombres.ToArray
    End Function

    End Class

    y asi tengo mi aspx:






    Cliente:


  24. Buenas !, mi problema es el siguiente:

    – Tengo 3 tablas: Clientes , Productos y Categorias

    Necesitaría un textbox “BUSCADOR” que busque en las 3, y me traiga con un autocomplete, las coincidencias en cada tabla.. por separado ( 3 columnas ) y según la que cliquée el usuario es la que se busca. O sea, que cada ítem podría tener un href a la página de resultados indicando qué texto completo está buscando y de qué columna ( Clientes , productos o categorías ).

    No encuentro mucha info en internet sobre meter tablas en un panel de autocomplete, con 3 sources de información.

    Podrías ayudarme ? Gracias!.-

  25. hola exelente tutorial…pero quisiera saber como puedo agregar un evento..para que cuando el usuario le de click ala sugerencia del autocomplementar me traiga datos de una base de datos y poder mostrarlos dependiendo de la seleccion..
    gracias..

  26. Hola, Yo hize una aplicacion hace un año, implemente el AutoComplete copiandolo de ajax control tooltikt samples y me funciono. Y ahora hize lo mismo en otra pagina y no me funciona.
    probe el tuyo y tampoco, que podra ser demen un luz, un camino, sera el Theme, el style.. que podra ser.???

    Ayuda

  27. Hola

    Estoy realizando Autocomplete Textbox con Ajax y WebServices, y funciona bien, pero lo que necesito hacer es algo mas dinámico utilizando un procedimiento almacenado que me reciba 3 parámetros, incluyendo prefixText.

    Lo que he leido, es que el prefixText se envia a través de la propiedad TargetControlID; pero este no me funciona.

    No se como enviarle los 3 parámetros, o bueno el prefixText si, pero y los otros dos, como?

    Gracias por su colaboración 😉

  28. tengo una duda, si al utilizar el autocomplete unes nombre y apellido que son dos campos en la base de datos como podrias hacer para traer otros datos segun el hallado en el autocomplet

  29. Hola Gonzalo queria preguntarte..tengo el problema que no puedo seleccionar el control del cuadro de herramientas..ya instale ajaxcontroltoolkit 3.5 y nada no me deja ingresar el control al webform por ello no puedo realizar el proceso…ayuda por favor uso visual estudio 2008

  30. Muy bueno el articulo, es de gran ayuda.
    Por el tipo de búsqueda que hice retornaron muchos resultados (+ de 700) y el control no los mostró, para resolver esto ¿Hay forma de paginar los resultados?

    gracias

  31. Con tu ejemplo , lo prueba y normal , pero cuando intento realizarlo con una base de datos mia me sale , no me realiza la busqueda …

  32. hola, mira estoy teniendo un problema con esta y otras herramientas de ajax. podras mandarme un mail, asi lo hablamos por privado? saludos
    (braianj@gmail.com)

  33. probe este ejemplo, y la verdad se me hace muy completo, el problema es que no me funciona =/ no tengo idea de por que!! estoy haciendo la busqueda con usuarios y por alguna razon no aparecen

    saludos

  34. agrego mi codigo del web service

    Public Function listusuario(ByVal prefixText As String, ByVal cont As Integer) As String()
    Dim con As New SqlConnection(ConfigurationManager.AppSettings(“cnn”))
    Dim comando As New SqlCommand
    Dim dr As SqlDataReader
    Dim lista As New List(Of String)
    Try
    con.Open()
    comando.Connection = con
    comando.CommandType = CommandType.StoredProcedure
    comando.CommandText = “sp_SearchUsers_Network”
    comando.Parameters.Add(New SqlParameter(“@User”, prefixText))
    dr = comando.ExecuteReader
    While dr.Read
    lista.Add(dr.Item(“Usuario”))
    End While
    Catch ex As Exception
    Finally
    con.Close()
    End Try
    Return lista.ToArray
    End Function

    // y para mandarlo a llamar desde el autocompleteExtender

    =/ asi lo tengo pero no funciona!!

    saludos y gracias de antemano

  35. Excelente el tutorial!! Queria consultarte ya que al ejecutarlo en mi pagina web como ayuda para numeraciones (almacenadas como string) cuando la numeracion empieza con “0” no me muestra este valor (en la BD esta asi) o sea:
    Si tipeo 08xxx el control me lo encuentra pero me muestra solamente 8xxx (sin el cero inicial)

  36. hola hermano

    El autocompletar tambien funciona cuando se tiene un UpdatePanel de ajax?????

    Uso:
    .net 2010
    .AjaxControlToolkit.Binary.NET4
    .SQL 2008

    muchas gracias

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *