2011-07-14 10 views

Respuesta

3

En su carpeta Views/Shared/EditorTemplates cree una vista parcial llamada DateTime.ascx.

El código para esta EditorTemplate debe ser algo como

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DateTime?>" %> 

<% 
    string controlId = ViewData.TemplateInfo.HtmlFieldPrefix.Replace('.', '_'); 
%> 

<script type="text/javascript"> 
$(function() { 
    $('#<%: controlId %>_Day, #<%: controlId %>_Month, #<%: controlId %>_Year').live('change', function() { updateHiddenDate('<%: controlId %>'); }); 
    $('#<%: controlId %>_Day').val('<%: Model.HasValue ? Model.Value.Day.ToString() : "" %>'); 
    $('#<%: controlId %>_Month').val('<%: Model.HasValue ? Model.Value.Month.ToString() : "" %>'); 
    $('#<%: controlId %>_Year').val('<%: Model.HasValue ? Model.Value.Year.ToString() : "" %>'); 
    updateHiddenDate('<%: controlId %>'); 
}); 

function updateHiddenDate(hiddenDateId) { 
    $('#' + hiddenDateId).val($('#' + hiddenDateId + '_Year').val() + "-" + $('#' + hiddenDateId + '_Month').val() + "-" + $('#' + hiddenDateId + '_Day').val()); 
} 
</script> 

<select id="<%: controlId %>_Day"> 
<% for (int dayOrdinal = 1; dayOrdinal <= 31; dayOrdinal++) 
    { 
     Response.Write(string.Format("<option value=\"{0}\">{0}</option>", dayOrdinal)); 
    } 
%> 
</select> 
<select id="<%: controlId %>_Month"> 
<% for (int monthOrdinal = 1; monthOrdinal <= 12; monthOrdinal++) 
    { 
     Response.Write(string.Format("<option value=\"{0}\">{1}</option>", monthOrdinal, System.Globalization.DateTimeFormatInfo.CurrentInfo.MonthNames[monthOrdinal - 1])); 
    } 
%> 
</select> 
<select id="<%: controlId %>_Year"> 
<% for (int yearOrdinal = DateTime.Now.Year - 5; yearOrdinal <= DateTime.Now.Year + 5; yearOrdinal++) 
    { 
     Response.Write(string.Format("<option value=\"{0}\">{0}</option>", yearOrdinal)); 
    } 
%> 
</select> 

<%: Html.Hidden("", Model.HasValue ? String.Format("{0:yyyy-MM-dd}", Model) : "") %> 

que crea un editor de plantillas con un campo oculto que contiene una representación de la norma ISO 8601 a la fecha la cual el MVC ModelBinder puede analizar.

jQuery actualiza el campo oculto cada vez que cambian las listas desplegables. Tenga en cuenta el uso del ViewData.TemplateInfo.HtmlFieldPrefix que uso para obtener el id generado del campo oculto.

Note que esta solución se aplica fácilmente sin que se dañe con Custom ModelBinders porque construimos un único valor de formulario que contiene la fecha y hora completa.Sin embargo, esto no quiere decir que

  1. Usted confía en que el cliente tenga activado Javascript, y
  2. Es necesario incluir una referencia de script a la biblioteca jQuery en su masterpage (por ejemplo <script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>)

Si eso no es aceptable, tendrá que mirar Custom ModelBinders como @Jon ha señalado.

0

Probablemente no sea el más eficiente, pero en su modelo de vista podría tener tres ints para el día, mes y año, respectivamente. Luego, cuando devuelva el modelo de vista enviado, simplemente puede usar los tres campos para crear un objeto DateTime.

En cuanto a la creación de una plantilla, creo que una vista parcial sería la mejor manera de hacerlo. No estoy seguro, todavía estoy aprendiendo MVC yo mismo.

1

Editor Templates son su mejor opción. Si desea que la plantilla del editor esté disponible desde cualquier lugar, colóquela en la carpeta Views/Shared/EditorTemplates. Si desea que todos los tipos DateTime usen esta plantilla, cree una parcial llamada DateTime. Si solo desea que algunos de ellos utilicen esta plantilla, llámelo de otra forma y use el atributo UIHintAttribute y cree una plantilla de editor con el mismo nombre que el valor que usa para ese atributo.

Para que el archivador modelo siga funcionando, es posible que deba agregar algunos javascript a su editor, y onchange para cualquiera de los desplegables desplegables debe actualizar un campo oculto (con el nombre correcto para que el encuadernador modelo funcione) con el valores de mes/día/año seleccionados.

3

Scott Hanselman tiene un blog post al crear un encuadernador de modelo personalizado para manejar DateTime s. No se ajusta exactamente a su escenario, pero debería darle algunas ideas, y una vez que esté en su lugar, la plantilla del editor debería ser mucho más fácil ...

En términos de dónde colocar el archivo una vez que se ha creado, esa es la parte fácil:

~/Views/Shared/EditorTemplates/DateTime.[ascx|cshtml|vbhtml] 
0

si está utilizando html.editorfor puede especificar sus propios editores mediante la adición de un ascx en views/shared/editores que define el control, y la adición de los tres campos se llevaría a cabo en el código detrás de ese archivo.

Cuestiones relacionadas