Usar el calendario emergente de selección de fechas de jQuery UI y HTML5 con ASP.NET MVC: Parte 4

Por Rick Anderson

En este tutorial aprenderá los conceptos básicos para trabajar con plantillas de editor, plantillas de visualización y el calendario emergente de selección de fechas de jQuery UI en una aplicación web de ASP.NET MVC.

Agregar una plantilla para editar fechas

En esta sección creará una plantilla para editar fechas que se aplicará cuando ASP.NET MVC muestre la interfaz de usuario para editar las propiedades del modelo que estén marcadas con la enumeración Date del atributo DataType. La plantilla representará solo la fecha, no la hora. En la plantilla, usará el calendario emergente de selección de fechas de jQuery UI para proporcionar una manera de editar fechas.

Para comenzar, abra el archivo Movie.cs y agregue el atributo DataType con la enumeración Date a la propiedad ReleaseDate, como se muestra en el código siguiente:

[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

Este código hace que el campo ReleaseDate se muestre sin el tiempo en las plantillas de edición y de visualización. Si la aplicación contiene una plantilla date.cshtml en la carpeta Views\Shared\EditorTemplates o en la carpetaViews\Movies\EditorTemplates, se usará esa plantilla para representar cualquier propiedad DateTime durante la edición. De lo contrario, el sistema de plantillas de ASP.NET integrado mostrará la propiedad como una fecha.

Presione CTRL+F5 para ejecutar la aplicación. Seleccione un vínculo de edición para comprobar que el campo de entrada de fecha de lanzamiento muestra únicamente la fecha.

Image of movie release date

En el Explorador de soluciones, expanda la carpeta Views, expanda la carpeta Shared y, a continuación, haga clic con el botón derecho en la carpeta Views\Shared\DisplayTemplates.

Haga clic en Agregar y, a continuación, haga clic en Vista. Se abre el cuadro de diálogo Agregar vista.

En el cuadro Nombre de vista, escriba "Date".

Active la casilla Crear como vista parcial. Asegúrese de que las casillas Usar un diseño o una página maestra y Crear una vista fuertemente tipada no están activadas.

Haga clic en Agregar. Se crea la plantilla Views\Shared\EditorTemplates\Date.cshtml.

Agregue el código siguiente a la plantilla Views\Shared\EditorTemplates\Date.cshtml.

@model DateTime
Using Date Template
@Html.TextBox("", String.Format("{0:d}", Model.ToShortDateString()),
  new { @class = "datefield", type = "date"  })

La primera línea declara que el modelo es de tipo DateTime. Aunque no es necesario declarar el tipo de modelo en plantillas de edición y visualización, es un procedimiento recomendado para obtener la comprobación en tiempo de compilación del modelo que se pasa a la vista (otra ventaja es que se obtiene IntelliSense para el modelo en la vista en Visual Studio). Si el tipo de modelo no se declara, ASP.NET MVC lo considera de tipo dinámico y no hay ninguna comprobación de tipos en tiempo de compilación. Si declara que el modelo es de tipo DateTime, se convierte en fuertemente tipado.

La segunda línea es simplemente un marcado HTML literal que muestra el texto "Using Date Template" antes de un campo de fecha. Usará esta línea temporalmente para confirmar que esta plantilla de fecha se está usando.

La siguiente línea es un asistente Html.TextBox que representa un campo input que es un cuadro de texto. El tercer parámetro del asistente usa un tipo anónimo para establecer la clase del cuadro de texto en datefield el tipo, en date (como class es un objeto reservado en C#, debe usar el carácter @ para escapar el atributo class en el analizador de C#).

El tipo date es un tipo de entrada HTML5 que permite a los exploradores compatibles con HTML5 representar un control de calendario de HTML5. Más adelante, agregará código de JavaScript para enlazar el calendario de selección de fechas de jQuery al elemento Html.TextBox mediante la clase datefield.

Presione CTRL+F5 para ejecutar la aplicación. Se sabe que la propiedad ReleaseDate de la vista de edición usa la plantilla de edición porque la plantilla muestra "Using Date Template" justo antes del cuadro de entrada de texto ReleaseDate, como se muestra en esta imagen:

Image verifying template used

En el explorador, vea el código fuente de la página (por ejemplo, haga clic con el botón derecho en la página y seleccione Ver código fuente). En el ejemplo siguiente se muestra parte del marcado de la página, que ilustra los atributos class y type en el HTML representado.

<input class="datefield" data-val="true" data-val-required="Date is required" 
      id="ReleaseDate" name="ReleaseDate" type="date" value="1/11/1989" />

Vuelva a la plantilla Views\Shared\EditorTemplates\Date.cshtml y quite el marcado "Using Date Template". Ahora la plantilla completada tiene el siguiente aspecto:

@model DateTime
@Html.TextBox("", String.Format("{0:d}", Model.ToShortDateString()),
  new { @class = "datefield", type = "date" })

Agregar un calendario emergente de selección de fechas de jQuery UI mediante NuGet

En esta sección, agregará el calendario emergente de selección de fechas de jQuery UI a la plantilla de edición de fecha. La biblioteca jQuery UI proporciona compatibilidad con animaciones, efectos avanzados y widgets personalizables. Se basa en la biblioteca de JavaScript jQuery. Este calendario emergente de selección de fechas permite la entrada de fechas de forma fácil y natural mediante un calendario en lugar de escribir una cadena. También limita a los usuarios a usar fechas legales: la entrada de texto al uso de una fecha permitía escribir algo parecido a 2/33/1999 (33 de febrero de 1999), pero el calendario emergente de selección de fechas de jQuery UI no.

En primer lugar, debe instalar las bibliotecas jQuery UI. Para ello, usará NuGet, que es un administrador de paquetes que se incluye en las versiones SP1 de Visual Studio 2010 y Visual Web Developer.

En Visual Web Developer, en el menú Herramientas, seleccione Administrador de paquetes NuGet y, después, Administrar paquetes NuGet.

Image showing how to access Manage Nu Get Packages menu option

Nota: Si el menú Herramientas no muestra el comando Administrador de paquetes NuGet, debe instalar NuGet siguiendo las instrucciones de la página Instalar NuGet del sitio web de NuGet.

Si usa Visual Studio en lugar de Visual Web Developer, en el menú Herramientas, seleccione Administrador de paquetes NuGet y, a continuación, seleccione Agregar referencia de paquete de biblioteca.

Image showing Visual Studio version to access Nu Get Package manager

En el cuadro de diálogo MVCMovie: Administrar paquetes NuGet, haga clic en la pestaña En línea de la izquierda y, a continuación, escriba "jQuery.UI" en el cuadro de búsqueda. Seleccione Query UI Widgets:Datepicker y, a continuación, seleccione el botón Instalar.

Image showing j Query U I date picker

Image 2

NuGet agrega estas versiones de depuración y versiones reducidas de jQuery UI Core y del selector de fechas de jQuery UI al proyecto:

  • jquery.ui.core.js
  • jquery.ui.core.min.js
  • jquery.ui.datepicker.js
  • jquery.ui.datepicker.min.js

Nota: Las versiones de depuración (los archivos sin la extensión .min.js) son útiles para tareas de depuración, pero en un sitio de producción, solo incluiríamos las versiones reducidas.

Para usar realmente el selector de fecha de jQuery, debe crear un script de jQuery que enlace el widget de calendario a la plantilla de edición. En el Explorador de soluciones, haga clic con el botón derecho en la carpeta Scripts y seleccione Agregar, Nuevo elemento y, a continuación, Archivo JScript. Asigne el nombre DatePickerReady.js al archivo.

Agregue el código siguiente al archivo DatePickerReady.js:

$(function () {
    $(".datefield").datepicker(); 
});

Si no está familiarizado con jQuery, aquí tiene una breve explicación de lo que hace: la primera línea es la función "jQuery listo", a la que se llama cuando todos los elementos DOM de una página se han cargado. La segunda línea selecciona todos los elementos DOM que tienen el nombre de clase datefield y, a continuación, invoca la función datepicker para cada uno de ellos (recuerde que agregamos la clase datefield a la plantilla Views\Shared\EditorTemplates\Date.cshtml antes en el tutorial).

Ahora, abra el archivo Views\Shared\_Layout.cshtml. Debe agregar referencias a los siguientes archivos, todos ellos necesarios para poder usar el selector de fechas:

  • Content/themes/base/jquery.ui.core.css
  • Content/themes/base/jquery.ui.datepicker.css
  • Content/themes/base/jquery.ui.theme.css
  • jquery.ui.core.min.js
  • jquery.ui.datepicker.min.js
  • DatePickerReady.js

En el siguiente ejemplo se muestra el código real que debe agregar en la parte inferior del elemento head en el archivo Views\Shared\_Layout.cshtml.

<link href="@Url.Content("~/Content/themes/base/jquery.ui.core.css")" 
        rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/themes/base/jquery.ui.datepicker.css")" 
        rel="stylesheet"  type="text/css" />
    <link href="@Url.Content("~/Content/themes/base/jquery.ui.theme.css")" 
        rel="stylesheet" type="text/css" />

    <script src="@Url.Content("~/Scripts/jquery.ui.core.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.datepicker.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/DatePickerReady.js")" 
        type="text/javascript"></script>

La sección head completa se muestra aquí:

<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" 
        rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" 
        type="text/javascript"></script>

    <link href="@Url.Content("~/Content/themes/base/jquery.ui.core.css")" 
        rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/themes/base/jquery.ui.datepicker.css")" 
        rel="stylesheet"  type="text/css" />
    <link href="@Url.Content("~/Content/themes/base/jquery.ui.theme.css")" 
        rel="stylesheet" type="text/css" />

    <script src="@Url.Content("~/Scripts/jquery.ui.core.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.datepicker.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/DatePickerReady.js")" 
        type="text/javascript"></script>
</head>

El asistente de contenido URL convierte la ruta de acceso del recurso en una ruta de acceso absoluta. Debe usar @URL.Content para hacer referencia correctamente a estos recursos cuando la aplicación se ejecute en IIS.

Presione CTRL+F5 para ejecutar la aplicación. Seleccione un vínculo de edición y, a continuación, coloque el punto de inserción en el campo ReleaseDate. Se muestra el calendario emergente de jQuery UI.

Image of release date field with date picker

Al igual que la mayoría de los controles de jQuery, el selector de fechas permite personalizarlo ampliamente. Para obtener información, consulte Personalización visual: diseño de un tema de jQuery UI en el sitio de jQuery UI.

Compatibilidad con el control de entrada de fecha HTML5

A medida que más exploradores van admitiendo HTML5, conviene usar la entrada HTML5 nativa, como el elemento de entrada date, y no usar el calendario de jQuery UI. Puede agregar lógica a la aplicación para usar controles HTML5 automáticamente si el explorador los admite. Para ello, reemplace el contenido del archivo DatePickerReady.js por lo siguiente:

if (!Modernizr.inputtypes.date) {
    $(function () {
        $(".datefield").datepicker();
    });
}

La primera línea de este script usa Modernizr para comprobar que se admite la entrada de fechas HTML5. Si no se admite, se enlaza en su lugar el selector de fechas de jQuery UI. (Modernizr es una biblioteca de JavaScript de código abierto que detecta la disponibilidad de implementaciones nativas HTML5 y CSS3. Modernizr se incluye en cualquier proyecto nuevo de ASP.NET MVC que cree).

Después de realizar este cambio, puede comprobarlo usando un explorador que admita HTML5, como Opera 11. Ejecute la aplicación mediante un explorador compatible con HTML5 y edite una entrada de película. El control de fecha HTML5 se usa en lugar del calendario emergente de jQuery UI:

Image of H T M L 5 date control

Dado que las nuevas versiones de exploradores implementan HTML5 incrementalmente, un buen enfoque por ahora es agregar código al sitio web que admite una amplia variedad de compatibilidad con HTML5. Por ejemplo, a continuación se muestra un script DatePickerReady.js más sólido que permite que el sitio sea compatible con exploradores que solo admiten el control de fecha HTML5 parcialmente.

if (!Modernizr.inputtypes.date) {
    $(function () {
        $("input[type='date']")
                    .datepicker()
                    .get(0)
                    .setAttribute("type", "text");
    })
}

Este script selecciona elementos input HTML5 de tipo date que no admiten completamente el control de fecha HTML5. Para esos elementos, enlaza el calendario emergente de jQuery UI y, a continuación, cambia el atributo type de date a text. Al cambiar el atributo type de date a text, se elimina la compatibilidad parcial con fechas HTML5. En JSFIDDLE encontrará un script DatePickerReady.js aún más sólido.

Agregar fechas que aceptan valores NULL a las plantillas

Si usa una de las plantillas de fecha existentes y pasa una fecha nula, obtendrá un error en tiempo de ejecución. Para que las plantillas de fecha sean más sólidas, las cambiará para que acepten valores NULL. Para admitir fechas con valores NULL, cambie el código de Views\Shared\DisplayTemplates\DateTime.cshtml a lo siguiente:

@model Nullable<DateTime>
@(Model != null ? string.Format("{0:d}", Model) : string.Empty)

El código devuelve una cadena vacía cuando el modelo es NULL.

Cambie el código del archivo Views\Shared\EditorTemplates\Date.cshtml por lo siguiente:

@model Nullable<DateTime>

 @{
    DateTime dt = DateTime.Now;
    if (Model != null)
    {
       dt  = (System.DateTime) Model;
   
    }
    @Html.TextBox("", String.Format("{0:d}", dt.ToShortDateString()), new { @class = "datefield", type = "date"  })
}

Cuando se ejecuta este código, si el modelo no es NULL, se usa el valor DateTime del modelo. Si el modelo es NULL, se usa la fecha actual en su lugar.

Resumen

En este tutorial hemos cubierto los conceptos básicos de los asistentes con plantilla de ASP.NET y se describe cómo usar el calendario emergente de selección de fechas de jQuery UI en una aplicación ASP.NET MVC. Para obtener más información, pruebe con estos recursos:

  • Para obtener información sobre jQuery UI, consulte jQuery UI.
  • Para obtener información sobre cómo localizar el control de selección de fecha, consulte UI/Datepicker/Localization.
  • Para obtener más información sobre las plantillas de ASP.NET MVC, consulte la serie de blogs de Brad Wilson sobre plantillas de ASP.NET MVC 2. Aunque la serie está escrita para ASP.NET MVC 2, sigue siendo válida para la versión actual de ASP.NET MVC.