La historia de mis desventuras

Palabras más, palabras menos sobre desarrollo de software.

Breve Autocomplete Helper con ASP.NET MVC y jQuery

Posted by Jhonny López Ramírez en 16 marzo 2010

Han pasado ya varios días desde la última vez que escribí algo en el blog. Escaso tiempo. Vengo hoy con un pequeño Helper construido para hacer las veces de Autocomplete en ASP.NET MVC. Se trata de un ejemplo sencillo basado en un práctico jQuery Autocomplete (que pueden descargarse de aquí).

Una vez he descargado el paquete paso a descomprimirlo y a pegar los archivos claves en las rutas correspondientes, como muestro en la siguiente imagen:

2

Lo siguiente que haré será crear el HtmlHelper para automatizar el proceso de escritura de la función que hará la gracia. Para hacerlo tengo que disponer de una clase con los modificadores de acceso public y static y dentro un método de extensión a la clase HtmlHelper. Pongo aquí el código:

using System.Text;

using System.Web.Mvc;

 

namespace AutoCompleter.Helpers

{

    public static class MyHelpers

    {

        public static string AutoCompleter(this HtmlHelper helper, string name, string controller, string action, string fieldName, bool mustMatch)

        {

            StringBuilder html = new StringBuilder("<script type=\"text/javascript\">");

 

            html.Append("$(document).ready( function() {");

            html.AppendLine("$('#" + name + "').autocomplete('/" + controller + "/" + action + "/', {");

            html.AppendLine("dataType: 'json',");

            html.AppendLine("parse: function(data) {");

            html.AppendLine("var rows = new Array();");

            html.AppendLine("for(var i=0; i<data.length; i++){");

            html.AppendLine("rows[i] = { data:data[i], value:data[i]." + fieldName + ", result:data[i]." + fieldName + " };");

            html.AppendLine("} return rows;},");

            html.AppendLine("formatItem: function(row, i, n) {");

            html.AppendLine("return row." + fieldName + ";},");

            html.AppendLine(" width: 300, mustMatch: " + mustMatch.ToString().ToLower() + " , });});</script>");

 

            return html.ToString();

 

        }

    }

}

 

Como ven, se trata de un método que escribe el código de la función, que anexa a un cuadro de texto, generará el comportamiento de autocomplete. Revisemos los parámetros:

  • helper: ¿Es necesario decirlo? Es el que nos dice que se trata de un método de extensión sobre la clase HtmlHelper.
  • name: Representa el nombre del cuadro de texto que va a tener la funcionalidad de autocompletado.
  • controller: Hace referencia al controlador que contendrá un método dispuesto a retornar los objetos que se listarán en el autocompletado.
  • action: Nombre del método del controlador que retornará los objetos a listarse en el autocompletado. Para efectos de que nuestro AutoComplete funcione es necesario que lo retornado por este método sea un objeto Json.
  • fieldName: Se refiere a la propiedad de los objetos que se retornen que será el texto a mostrarse en la lista de autocompletado.
  • mustMatch: Nos permitirá indicar si el valor del cuadro de texto debe coincidir con alguno de los retornados en la lista de autocompletado.

Vamos a poner aquí un ejemplo de lo que sería el método que retornaría la lista de autocompletado. En nuestro Home controller agregaremos este método:

public ActionResult GetStrings(string q)

{

    string[] strings = new string[] { "abc", "abecedario", "akeronte", "abuela", "about" };

 

    var data = from string s in strings select new { myText = s };

 

    return Json(data);

}

El tipo de retorno de este método es un ActionResult que luego será específicamente un Json. Tiene un parámetro llamado q (ese debe ser su nombre) de tipo string que representará el texto escrito en el cuadro de texto. En este caso no lo uso puesto que la lista a retornar es bastante pequeña, pero se hace muy útil en escenarios en los que quiero filtrar realmente el conjunto de resultados a retornar (cuando por ejemplo lo saco de una base de datos). Tengo en este caso un arreglo de strings que luego convierto en un objeto anónimo con una propiedad llamada myText. Retorno este objeto convertido en uno Json.

Ahora bien, en el MasterPage de mi sitio agrego las referencias necesarias a los scripts de jQuery, así:

<head runat="server">

    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>

    <script type="text/javascript" src="../../Scripts/MicrosoftAjax.js"></script>  

    <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />

    <link href="../../Content/jquery.autocomplete.css" rel="stylesheet" type="text/css" />

    <script type="text/javascript" src="../../Scripts/jquery-1.2.6.min.js"></script>

    <script type="text/javascript" src="../../Scripts/jquery.autocomplete.js"></script>

</head>

Voy a probarlo sobre el Index del Home controller. Para poder usar el Helper que he creado debo hacer un Import sobre el espacio de nombres que lo contiene. He aquí todo el código del Index:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<%@ Import Namespace="AutoCompleter.Helpers" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">

    Home Page

</asp:Content>

 

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

    

   

    <h2><%= Html.Encode(ViewData["Message"]) %></h2>

    <p>

        <%= Html.TextBox("MyTextBox") %>

        <%= Html.AutoCompleter("MyTextBox", "Home", "GetStrings", "myText", false) %>

    </p>

</asp:Content>

Como ven, primero creo un cuadro de texto (a través de la etiqueta input o con el Helper TextBox) al que he llamado MyTextBox. Luego creo el AutoCompleter y le asigno valores a sus parámetros. El primero es el nombre del cuadro de texto que se comportará como autocompletador. Luego doy el nombre del controlador que contiene al método, el tercer parámetro es el nombre del método, el cuarto parámetro representa a la propiedad que se mostrará en la lista de autocompletado y finalmente digo si deberá coincidir el texto ingresado con algún elemento de los retornados.

Ejecutándolo se verá así:

image

Dejo el enlace para descargar la solución:

AutoCompleter.sln

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

 
A %d blogueros les gusta esto: