DateTime property as two view inputs, one for the date and one for the time portion
Is it possible to have one DateTime property in the model, but use it as two inputs in a view / form? For example, Date part will use jqueryui datepicker while Time part picker will be masked input or some other nifty jquery plugin. From time to time I need to use two dropdows to select the time (hours and minutes).
My goal is to have one DateTime property in the model (no partial strings for date and time). Is it possible? Using MVC4.
source to share
Here is the technique I am using to split a date into 3 fields while there is only 1 DateTime property in the ViewModel. While not exactly what you want, you should use a similar method to achieve what you want.
Editor Template /views/shares/editortempaltes/datetime.cshtml
@model Nullable<System.DateTime>
@Html.TextBox("Day", Model.HasValue ? Model.Value.Day.ToString() : "", new { Type = "Number", @class="date-day" })
@Html.ValidationMessage("Day")
@Html.DropDownList("Month", months, new { @class="date-month" })
@Html.ValidationMessage("Month")
@Html.TextBox("Year", Model.HasValue ? Model.Value.Year.ToString() : "", new { Type = "Number", @class="date-year" })
@Html.ValidationMessage("Year")
Custom ModelBinder
public object GetValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
int day, month, year;
if (TryGetValue(controllerContext, bindingContext, propertyDescriptor.Name + ".Day", out day) && TryGetValue(controllerContext, bindingContext, propertyDescriptor.Name + ".Month", out month) && TryGetValue(controllerContext, bindingContext, propertyDescriptor.Name + ".Year", out year))
{
try
{
return new DateTime(year, month, day);
}
catch (ArgumentOutOfRangeException)
{
var fullPropertyName = bindingContext.ModelName + "." + propertyDescriptor.Name;
bindingContext.ModelState[fullPropertyName] = new ModelState();
bindingContext.ModelState[fullPropertyName].Errors.Add("Invalid date");
}
}
return null;
}
private bool TryGetValue(ControllerContext controllerContext, ModelBindingContext bindingContext, string propertyName, out int value)
{
var fullPropertyName = bindingContext.ModelName + "." + propertyName;
string stringValue = controllerContext.HttpContext.Request[fullPropertyName];
bindingContext.ModelState.Add(fullPropertyName, new ModelState() { Value = new ValueProviderResult(stringValue, stringValue, null) });
return int.TryParse(stringValue, out value);
}
Usage Add DateTime property to ViewModel then call
@Html.EditorFor(m => m.DateTimeProperty)
source to share
Yes, you can. Just pass the model to the view and use the DateTime as usual if you are trying to pass values to a field.
To get data back, you can return 2 DateTimes (one for seconds and one for time) and concatenate 2 dates in the controller.
If you need more specific help, please show us where your code issues are so we can help you with the implementation.
source to share