Posts Tagged ‘asp.net MVC’

jQuery plugin: Autocomplete con ASP.NET MVC

Octubre 3rd, 2009

Una de las cosas que mas gustan de ASP.NET MVC es la posibilidad de utilizar librerias como jQuery de manera muy facil, vamos a utilizar el plugin Autocomplete para jQuery diponible en http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/.

Antes que nada para poder utilizar el plugin debemos referenciar los archivos correspondientes en nuestro SiteMaster, en la declaración del head de la pagina colocamos:

    <%--jQuery Core --%>
    <script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
    <%--end jQuery Core--%>
    <%--jQuery Autocomplete--%>
    <link href="../../Scripts/jquery.autocomplete.css" rel="stylesheet" type="text/css" />
    <script src="../../Scripts/jquery.autocomplete.js" type="text/javascript"></script>
    <%--end jQuery Autocomplete--%>

Ya que tenemos las referencias, vamos a crear el controlador que nos servirá como proveedor de datos:

public ActionResult Completer(string q)
        {
            if (q != "")
            {
                NWDataContext db = new NWDataContext();
                var suggest = from i in db.Customers
                                  .Where(e => e.ContactName.ToLower().StartsWith(q.ToLower()))
                                   select (i.ContactName + "|" + i.CustomerID);
                return Content(String.Join("\n", suggest.ToArray()));
            }
            return new EmptyResult();
        }

Esta ActionResult recibe como parámetro un string q, que sera enviado por el Autocomplete Plugin al momento que el usuario empiece a llenar el TexBox. Verificamos si la q no esta vacia (”" – solo por si acaso), instan ciamos nuestro proveedor de datos o repositorio, en mi caso es un DataContext de LINQtoSQL, y realizo la busque en la tabla Customers donde el contact name empiece con q.

NOTA: pase todo a Lower para evitarme un posible dolor de cabeza con el case sensitive.

Al final retorno un arreglo con este formato para cada elemento:
Ana Trujillo|ANATR
Antonio Moreno|ANTON
Ann Devon|EASTC
Aria Cruz|FAMIA
André Fonseca|GOURL
Annette Roulet|LAMAI
Alexander Feuer|MORGK
Alejandra Camino|ROMEY
Art Braunschweiger|SPLIR
Anabela Domingues|TRADH

Ustedes no necesariamente deben utilizar este tipo de estructura, también pueden utilizar JSON si lo desean.

Con este método nos basta para realizar muchas cosas, vamos a implementar 5 variantes de este autocomplete:

  • Autocomplete Simple.
  • Autocomplete Multiples Selecciones.
  • Autocomplete Incluyendo el ID del elemento elegido en un campo Oculto.
  • Autocomplete Forzando la seleccion de uno de los sugeridos.
  • Autocomplete Con Imagenes (Fancy).

AutoComplete Simple

AutoComplete Simple - jQuery Plugin

AutoComplete Simple - jQuery Plugin


Lo que corresponde de HTML, generar el texbox con la ayuda de los helpers de MVC.

<span>Autocomplete Simple</span>
    <hr />
    <% =Html.TextBox("Clientes") %>

Y setear el Autocomplete dentro de un SCRIPT TAG.

<script type="text/javascript">
        $(function() {
 
 
            $('#Clientes').autocomplete(' <% =Url.Action("Completer","Home") %>', {
                width: 300,
                formatItem: formatItemNoID,
                formatResult: formatResult
            });
    });
    </script>

$(’#Clientes’).autocomplete setea el comportamiento del input con ID Clientes, para que sea autocompletado.
El primar parametro del autocomplete es la url, que como ven utilice el helper de MVC para que me genere un link hacia el ActionResult “Completer” del Controlador “Home”, la q es adjuntada como queryString al URL que le proporcionen, al final seran links de este tipo:
http://localhost/Home/Completer?q=a&limit=10&timestamp=1254590546937, el limit es la cantidad de resultados que serán sugeridos al usuario por defecto 10 elementos.
El segundo parámetro es una colección de opciones con figurables que trae el plugin, no entrare en detalle ya que todas las opciones son bastante digeribles a la primera, pero si les dejo una url donde pueden ver todas las opciones disponibles: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions.

Lo que si voy a explicar son las funciones para parsear el resultado del autocomplete:

            function formatItem(row) {
                return row[0] + " (<strong>id: " + row[1] + "</strong>)";
            }
            function formatItemWIMG(row) {
                return "<img src='../../Content/img/es.jpg'/> " + row[0];
            }
            function formatItemNoID(row) {
                return row[0];
            }
            function formatResult(row) {
                return row[0].replace(/(<.+?>)/gi, '');
            }

Lo que realizan estas funciones es dar forma a la lista de sugerencias del autocomplete, ya sea que queremos ver imágenes, formatear el texto, en general la forma en que se ve la lista.

Autocomplete Multiples Selecciones
Acá la diferencia es que se pueden seleccionar mas de un elemento, separados por comas.

Multiples Selecciones - jQuery Plugin

Multiples Selecciones - jQuery Plugin


<span>Autocomplete Multiples Selecciones</span><br />
    <hr />
    <% =Html.TextArea("ClientesMultiples") %>
    <br />
    <br />

$('#ClientesMultiples').autocomplete(' <% =Url.Action("Completer","Home") %>', {
                width: 300,
                multiple: true,
                formatItem: formatItemNoID,
                formatResult: formatResult
            });

La diferencia esta al configurar el autocomplete, ahora la opción multiple es TRUE.

Autocomplete Incluyendo el ID del elemento elegido en un campo Oculto
Algunas veces lo que necesitamos es el ID del cliente, así que ahora cuando configuramos el autocomplete utilizamos el evento .result (se ejecuta cuando el usuario selecciona algún elemento de la lista sugerida).

Autocomplete con ID - jQuery Plugin

Autocomplete con ID - jQuery Plugin

Ahora cuando el usuario selecciona Ana, ademas de completar la palabra en el primer texbox, el ID de Ana sera colocado en la casilla de la derecha.

Setear el ID del elemento selecionado

Setear el ID del elemento selecionado


<span>Incluyendo el ID en un campo Oculto</span>
    <hr />
    <% =Html.TextBox("ClienteName") %> <% =Html.TextBox("hiddenID", null, new { style = "width:50px", disabled = "disabled" })%>
    <br />
    <br />


$('#ClienteName').autocomplete(' <% =Url.Action("Completer","Home") %>', {
                width: 300,
                formatItem: formatItem,
                formatResult: formatResult
            });
            $('#ClienteName').result(function(event, data, formated) {
                $('#hiddenID').val(data[1]);
            });

En esta sección le agregue el evento result, y acá le indico que cuando el usuario seleccione algún elemento, envié el id seleccionado al campo oculto.

Porque data[1]?
data representa el elemento seleccionado, al parsearlo data[0] venrdia siendo el nombre del cliente y data[1] el ID del mismo. Recuerden que en el controlador devuelvo un array de esta forma:
Nombre del Cliente | ID
Que en este contexto es:
Data [0] | Data[1]

Autocomplete Forzando la seleccion de uno de los sugeridos
SI lo que queremos es que el usuario no nos este inventando nombres de clientes, podemos setear el autocomplete para que solo acepte elementos existentes dentro de los sugeridos, si el usuario escribe cualquier otra cosa que no hace match con algún nombre de cliente existente, se resetea el texbox.
En lo personal no me agreda mucho esta opcion, me parece algo agresivo con el usuario limpiar todo lo que ha escrito sin enviarle algún mensaje de lo que esta pasando.

Para lograr este efecto simplemente colocamos la opcion mustMatch: true.

$('#ClientesForced').autocomplete(' <% =Url.Action("Completer","Home") %>', {
                width: 300,
                mustMatch: true,
                formatItem: formatItem,
                formatResult: formatResult
            });

Autocomplete Con Imagenes (Fancy)
Ya como últimos punto, si queremos lograr algo mas llamativo imaginen que tuviésemos a disposición una imagen del rostro de los clientes, entonces podemos desplegar en las sugerencias junto con el nombre una imagen del cliente.

AutoComplete con imgs - jQuery Plugin

AutoComplete con imgs - jQuery Plugin


<span>Autocomplete Con Imagenes</span><br />
    <hr />
    <% =Html.TextBox("ClienteFace") %>


$('#ClienteFace').autocomplete(' <% =Url.Action("Completer","Home") %>', {
                width: 300,
                formatItem: formatItemWIMG,
                formatResult: formatResult
            });


Acá lo único distinto es la función que utilizamos para darle formato a los elementos formatItemWIMG.

Pueden descargar el proyecto de ejemplo aqui

Entradas Relacionadas:

ASP.NET MVC, retornar un resultado en notacion JSON

Agosto 20th, 2009

Una de las cosas que nos permite ASP.NET MVC, es retornar un tipo de resultado dependiendo de como lo necesitemos. Uno de estos ejemplos es cuando necesitamos que el servidor nos retorne JSON (Javascript Object Notation), para los que no lo conocen JSON tiene este formato:

...
{
	"id": "007",
	"type": "dona",
	"name": "dulce",
	"image":
		{
			"url": "images/007.jpg",
			"width": 200,
			"height": 200
		},
	"thumbnail":
		{
			"url": "images/007.jpg",
			"width": 32,
			"height": 32
		}
}
...

Este tipo de formato es consumible por javascript al ser evaluado por un metodo como eval().

Si necesitamos que un Controlador nos retorne JSON, ASP.NET MVC nos provee de unos parsers o serializadores, el que nos interesa en este caso es Json.

Veamos el siguiente ejemplo:

...
 public ActionResult GetValidation(int Mid)
        {
 
            bool result = _service.Validate(Mid);
            return Json(result);
        }
...

Lo que hace este controlador es ejecutar el metodo Validate y retorna un boolean, en la siguiente linea lo que hacemos es retornar el resultado, pero en lugar de retornar una vista, retornamos un Json, que al final lo que nos devuelve es algo así:

...
{"result":false}
...

Como ven es muy fácil serializar JSON con ASP.NET MVC.

Entradas Relacionadas:

ASP.NET MVC 1.0 Lo Básico (Parte 1 Controladores)

Agosto 19th, 2009

Desde que apareció Ruby on Rails MVC tomo mas fuerza, tanto que la gente de Microsoft no ha tenido más opción que sacar una versión de ASP.NET MVC, que la verdad en mi opinión y la de muchos otros, creo que es lo mejor que ha podido hacer Microsoft, yo nunca trabaje con WebForms pero me parecía algo muy extraño y conozco colegas que dicen que WebForms es algo que nunca intentarían aprender.

Bueno pero que es MVC, viene del Ingles (Model View Controller), que en español seria Modelo Vista Controlador.
El Modelo representa los datos o entidades de Negocio, el controlador se encarga del flujo de la aplicación y la vista se encarga de desplegar los datos o recursos al usuario final.

Utilizar este patrón de desarrollo nos brinda entre otras cosas:

  • Separación de Responsabilidades.
  • Control sobre el MarkUp (HTML).
  • Nos brinda mas libertad al poder utilizar librerías como jQuery.
  • Ok, vamos a ver un ejemplo de como funciona ASP.NET MVC.

    Nos vamos al Visual Studio 2008, vamos al menu File->New->Project.

    File->New->Project

    File->New->Project

    En la siguiente Ventana Nos aseguramos de que este selecionado el .Net FrameWork 3.5 y buscamos un proyecto de tipo ASP.NET MVC Web Application.

    ASP.NET MVC Web App

    ASP.NET MVC Web App

    Si no sale el template para proyectos ASP.NET MVC, lo mas probable es que haga falta installar ASP.NET MVC, ya que el VS.NET 2008 no lo trae por defecto. Puedes descargar ASP.NET MVC desde el sitio oficial http://www.asp.net/mvc/download/.

    Seguidamente el Wizard nos preguntará si deseamos crear un proyecto de pruebas, por ahora le decimos que no.

    Unit Testing Project

    Unit Testing Project

    Visual Studio nos genera una estructura de directorios, para empezar a trabajar, las más sobresalientes son: Views, Controllers y Models.

    Estructura de Directorios

    Estructura de Directorios

    Como veras los directorios no vienen vacíos ya hay un par de controladores y tres directorios de Vistas. Si ponemos a correr el proyecto veremos que ya esta la estructura básica de una web, que nos incluye Membership para el manejo de cuentas de usuarios, una pagina de Home y una de About.

    Pagina Web Base

    Pagina Web Base

    Ahora explicare que tiene que ver esos controladores y vistas con la Web Base que acabamos de ver.
    Primero los Controladores, nos vamos al HomeController.cs (Asumiendo que usamos C#) y veremos lo siguiente:

    ...
    public class HomeController : Controller
        {
            public ActionResult Index()
            {
                ViewData["Message"] = "Welcome to ASP.NET MVC!";
     
                return View();
            }
     
            public ActionResult About()
            {
                return View();
            }
        }
    ...

    Un Controlador no es mas que una clase que contiene métodos, cada método de tipo ActionResult, puede ser accesado a través de una URL, que es mapeada de la siguiente manera: /Nombre_del_Controlador/Nombre_de_la_Accion/, entonces para este caso particular seria /Home/Index/ si quisiéramos ejecutar el ActionResult Index() del Controlador HomeController. NOTA: Esto es válido siempre y cuado estemos utilizando los rutas por defecto que trae ASP.NET MVC, ya que podemos cambiar el mapeo a placer.

    Quizas hayan notado que aunque la clase se llama HomeController, en la URL solo hacemos referencia a Home, esto es por convencion de ASP.NET MVC,y es bastante logico, una de las reglas para que un controlador sea Controlador, es que su nombre debe terminar en Controller así:

    public class HomeController : Controller

    De otra manera ASP MVC no reconocera la clase como Controlador.

    Bueno ahora siguiendo con los ActionResult, veran que tiene dos cosillas que no vemos en ASP.NET WebForms, un ViewData y un Return View.
    Un ViewData es un Diccionario que tiene la finalidad de pasar datos a la Vista y es una de las maneras de pasar los datos.

    ViewData["Message"] = "Welcome to ASP.NET MVC!";

    Aquí lo que estamos haciendo es crear un espacio en ViewData para que guarde el String :”Welcome to ASP.NET MVC!“. De esta manera pasamos ese String a la Vista Correspondiente, pero ¿Cual de todas las Vistas?, si observamos de nuevo el directorio Views vemos que existe otra convención. Si existe un Controlador llamado HomeController debe existir un directorio en Views llamado Home.

    Convención de Directorios

    Convención de Directorios

    En Views/Home Contamos con dos Vistas: Index.aspx y About.aspx.

    Si vemos el controlador observamos que nos queda la sentencia :

    return View();

    Ustedes se preguntarán, ¿Como sabe cual de las dos vistas que están en Views/Home debe utilizar?. Sencillo, es otra convención, si al método View(), no le especificamos una vista, por defecto asumirá que en Views/Home existe una Vista que tiene el mismo nombre que el Método, el metodo actual se llama Index y vemos que existe un Views/Home/Index.aspx. De esta manera el Controlador sabe cual vista debe retornar.
    Sabiendo esto, podemos decir que esta sentencia:
    return View();
    es igual a:
    return View("Index");

    Este post se esta poniendo algo largo, así que vamos a dejarlo hasta aquí, como la parte 1 de lo Básico de ASP.NET MVC.

    Entradas Relacionadas:

    Como insertar google maps en mi web

    Agosto 17th, 2009

    Google maps es una de esas cosas que puede hacer que nuestra Web se vea muy bien, desde el punto de vista estético y funcional. Pero aveces algunos se asustan por lo complicado que puede llegar a ser, y en realidad el nivel de complejidad va dado por lo que queremos mostrar en nuestro mapa, normalmente direcciones y ubicaciones de cosas o personas. Pero por ahora solo para empezar iremos de a poco y les mostraré como pueden integrar google maps a su pagina Web, es algo bastante sencillo.

    Antes que nada necesitaremos adquirir nuestro google api key, que simplemente es un código que nos da google para poder utilizar su API, para adquirir un codigo nos dirigimos a esta dirección Web http://code.google.com/intl/es/apis/maps/signup.html.

    google api key

    google api key

    Insertamos la dirección del sitio web en el cual queremos utilizar el mapa, leemos y aceptamos los terminos y condiciones (que entre muchas otras cosas dice que podemos utilizar el API siempre y cuando el acceso a la web sea libre o gratuito, en otras palabras no lo podemos utilizar para fines comerciales donde vamos a generar dinero o lucrar).

    Le demos clic al boton Generar Clave de api y listo, google nos generara el codigo que podemos utilizar para nuestro dominio.

    Hay algo aquí que confunde a muchos, como nosotros le dimos explicitamente a google una dirección web por ejemplo la mía “http://www.diarioplus.com”, entonces eso quiere decir que puedo utilizar la misma API key para cualquier subdomino del dominio registrado como por ejemplo “http://mapas.diarioplus.com” o “http://ubicaciones.diarioplus.com” en fin cualquier subdominio, sin embargo hay otro dominio que esta abierto al uso que es “http://localhost/” que generalmente se utiliza para ambientes de desarrollo y pruebas, asi que no hay que preocuparce po subir todos los archivos a nuestro servidor para poder probrar el mapa, ya que lo podemos hacer localmente.

    Bueno ahora que ya contamos con nuestro key vamos a ver algo de código, yo voy a utilizar Visual Studio 2008 y un proyecto de ASP.NET MVC para esta demostración, ustedes pueden usar cualquier editor de texto (hasta notepad si lo desean =), aunque mejor les recomiendo algo como DreamWaver o Expression Web).

    Una ves tenemos nuestras herramientas a tono, vamos a lo premiro:

    1. Hacemos referencia a la API de google Maps, para esto agregamos la siguiente linea de código entre los tags HEAD de nuestra pagina, de esta manera:

    ...
         <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=ABCDEFG" type="text/javascript"><!--mce:0--></script>
     
    ...

    En donde reemplazaremos ABCDEFG por nuestra API Key.

    2. Ahora necesitamos una DIV en donde colocar el mapa, colocamos el siguiente codigo HTML entre los tags BODY de nuestra web.

    ...
     <div id="gmap">
        </div>
    ...

    También agregamos la siguiente a nuestra hoja de estilos, para darle espacio al mapa:

    ...
    #gmap
    {
    	width:500px;
    	height:300px;
    }
    ...

    3. Ahora viene lo interesante, ya hicimos referencia al API en el HEAD y ya tenemos un espacio para el mapa en el BODY, pero aun no hemos inicializado en mapa, así que ahora vamos al HEAD nuevamente he introducimos el siguiente código javascript.

    ...
         <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=ABQIAAAAl3anRmZdIVQV8MhyaB62NBS87hanF3knsvNrhfwTtlK6gOzTHhTZXZeB0Nq3fJAPVEXlYzKBbtz-VQ" type="text/javascript"></script>
     
        <script type="text/javascript">
            var centerLatitude = 37.818361;
            var centerLongitude = -122.478032;
            var StartZoom = 2;
     
            function init() {
                if (GBrowserIsCompatible()) {
                   var map = new GMap2(document.getElementById("gmap"));
                   map.addControl(new GSmallMapControl());
                   var location = new GLatLng(centerLatitude, centerLongitude);
                   map.setCenter(location, StartZoom);
     
                 }
             }
             window.onload = init;
        </script>
     
    ...

    Lo que hace este código es:
    1. Verificar que el Navegador sea compatible con google Maps.
    2. Inicializar el mapa.
    3. Agregar un Control al Mapa, el que aparece en la parte superior izquierda.
    4. Setear una locación como posición inicial.

    Y estamos listos probamos la Web y vemos que el mapa ya esta cargando como debería.
    mapa-cargado

    Entradas Relacionadas: