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.

+1


source to share


3 answers


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)

      

+1


source


As an alternative to the suggested solution, you can use a hidden field mapped to the DateTime property and change it accordingly on the client side using Javascript when some control on the form changes part of the date.



+1


source


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.

0


source







All Articles