jueves, 2 de julio de 2009

jQueryUI widgets… no son webcontrols pero vamos…

¡¡Hola a todos!! ¿Como vamos?

Una de los argumentos que más usan aquellos a quienes no les gusta ASP.NET MVC és “que hemos vuelto a los 90”, refiriendose, entre otras cosas, a que en ASP.NET MVC no existe el concepto de “controles” y que continuamente estamos “mezclando” código de cliente y de servidor, lo que lleva a una tag-soup que recuerda peligrosamente a la ASP clásica…

No quiero discutir en este post si gusta más el modelo MVC que el clásico de webforms (para quien le interese esta discusión puede pasarse por este post en el blog de jersson), sinó decir que ambos argumentos en mi opinión no tienen validez.

Las críticas al tag-soup generalmente vienen porque se asocia la mezcla de etiquetas de cliente y servidor con el código spaghetti que teníamos en las páginas ASP clásicas. Pero no es ni mucho menos lo mismo: una vista MVC tiene sólamente etiquetas de servidor que gestionan lógica de presentación. Esto implica que deberían ser muchas menos etiquetas de servidor que en las clásicas páginas ASP. Si, aún así, nos aparecen muchas y nuestro código nos sigue recordando al clásico ASP, hay varias maneras de minimizarlo:

  1. Utilizar un motor de vistas alternativo (hay varios por ahí afuera) como p.ej. Brial, NHaml, NVelocity y XSLT, solo por citar los cuatro que vienen con MVCContrib.
  2. Extender los dos helpers (HtmlHelper y AjaxHelper) con funciones propias que generen código HTML. Pasaros por este post de Rob Conery (How to avoid tag soup) para ver un ejemplo práctico.
  3. Utilizar jQuery. Ya lo he comentado varias veces y no me cansaré de decirlo: el poder de jQuery es tremebundo. Muchas cosas que tendemos a hacer con código de servidor se pueden hacer con un par de líneas de jQuery… La contrapartida a pagar es obvia: javascript debe estar habilitado en el navegador, pero vamos… en el 99% de los casos esto no es problema alguno.

Un ejemplo clásico de este punto tres… quieres mostrar una tabla con varios registros, y que las filas pares tengan un estilo y las impares otro? Puedes generar código con tags <% if %> para que te genere un estilo u otro:

    <table>
<% int idx = 0; %>
<% foreach (var item in Model) { %>
<% if ((idx++ % 2) == 0) {%>
<tr class="odd">
<% } else { %>
<tr class="even">
<% } %>
<td>
<%= Html.Encode(item.ID) %>
</td>
<
td>
<%= Html.Encode(item.Name) %>
</td>
</
tr>
<% } %>
</table>

O bien generar la tabla “tal cual”:

    <table>
<% foreach (var item in Model) { %>
<tr>
<
td>
<%= Html.Encode(item.ID) %>
</td>
<
td>
<%= Html.Encode(item.Name) %>
</td>
</
tr>
<% } %>
</table>

y  dejar que jQuery haga el trabajo:

<script type="text/javascript">
$(document).ready(function() {
$("tr:odd").addClass("odd");
$("tr:even").addClass("even");
});
</script>

El argumento de que no hay controles tampoco me es válido. Mi respuesta a quien me lo formula suele ser: ¿Y para que los necesito? Dime un webcontrol y muy probablemente te podré decir un plugin de jQuery que hace lo mismo (sinó mejor)… con la ventaja de que el código final que se genera es mucho más limpio. De acuerdo, no hay diseño RAD con un editor visual de controles, pero honestamente creo que vale la pena pagar este precio. P.ej. para comparar la productividad de ASP.NET MVC versus la productividad de webforms muchas veces se menciona el control GridView. Evidentemente implementar un GridView “a mano” no es trivial, pero por ejemplo… ¿habéis echado un vistazo al plugin de jQuery para grids? ¿No? Hacedlo y vereis que es brutal.


Hoy os quiero enseñar una mini-demo de “estos controles jQuery” por decirlo de algún modo (widgets en terminología jQuery UI). He escogido el DatePicker que forma parte de la suite jQuery UI que es un conjunto de “controles” (así entre comillas) implementados como plug-in de jQuery, además de otros detalles (como nuevos efectos de animaciones y soporte para drag-and-drop).


El primer paso es descargarse jQuery UI desde http://jqueryui.com/download. Podeis bajaroslo todo o seleccionar solo aquellas partes que necesiteis (en mi caso tengo toda la versión 1.7.2, la última a la hora de escribir este post).


Crea un nuevo proyecto ASP.NET MVC (en mi caso he eliminado el AccountController y todas sus vistas (Views/Account/*.*) así como Views/Shared/LogOnUserControl.ascx). Como siempre las modificaciones las realizo en la página inicial (Views/Home/Index.aspx).


Lo primero es incluir jQuery y jQuery UI en la página master (para que sea usable desde cualquier página). Abrid Views/Shared/Site.master y añadid los archivos de jQuery, jQuery UI, que en mi caso son los siguientes:

<link href="../../Content/jquery-ui-1.7.2.custom.css" 
rel="stylesheet" type="text/css" />
<
script type="text/javascript"
src="../../Scripts/jquery-1.3.2.js"></script>
<
script type="text/javascript"
src="../../Scripts/jquery-ui-1.7.2.custom.min.js"></script>

Copiad tambien la carpeta images que viene con “jQuery UI” dentro del directorio “Content” de ASP.NET MVC (el directorio “images” contiene imágenes usadas por los widgets de jQuery UI).


Ahora modificamos la vista (Views/Home/Index.aspx) para incluir un textbox:

<input type="text" id="dtPicker" />

Y finalmente vinculamos este elemento con un DatePicker de jQuery UI:

<script type="text/javascript">
$(document).ready(function() {
$("#dtPicker").datepicker();
});
</script>

¡y listos! Nos aparece un textbox y cuando pulsamos sobre él se abre el DatePicker.


¡Cómo podeis apreciar no puede ser más facil! Al pulsar sobre un día este se seleccionar y es introducido en el textbox.


Podemos personalizar el DatePicker usando opciones cuando lo invocamos. P.ej. podemos establecer un intervalo de fechas válidas:

// Solo valido desde el 02/Feb/2009 hasta 15/Feb/2009
$("#dtPicker").datepicker({ maxDate: new Date(2009, 1, 15),
minDate: new Date(2009,1,2) });

Esto ha sido sólo un pequeño ejemplo… hay muchos más widgets en jQuery UI!! Echadle un vistazo enhttp://jqueryui.com/demos/. Y luego no olvideis que hay otros plug-ins para jQuery que siendo también “widgets” no forman parte de jQuery UI!


Saludos!!!!!


pd: Esto es un crosspost desde mi blog en geeks.ms!

No hay comentarios: