I have a model to validate and the problem is the date of birth field. It must be composed of 3 dropdowns (day, month, year).
I tried the solution by Darin Dimitrov, but it had some minor problems.
One of the issues was conflicts with the default MVC 4 Javascript date validator - sometimes it kicked in even for valid dates and confused web site users. I invented a solution which can be found here: How to remove default client-side validators?
The second issue was that this solution generates the same id attributes for all the three dropdowns, and that is not good - ids should be unique per HTML page. Here is how I fixed it:
@Html.DropDownList("", years, "Year:", new { id = @ViewData.TemplateInfo.HtmlFieldPrefix + "_y" })
@Html.DropDownList("", months, "Month:", new { id = @ViewData.TemplateInfo.HtmlFieldPrefix + "_m" })
@Html.DropDownList("", days, "Day:", new { id = @ViewData.TemplateInfo.HtmlFieldPrefix + "_d" })
The last issue was that these dropdowns threw exception when I tried to preset some value on them from Controller. Here's how I fixed it:
var result = ViewData.ModelState[ViewData.TemplateInfo.HtmlFieldPrefix];
if (result != null && result.Value != null)
{
var values = result.Value.RawValue as string[];
years = new SelectList(years, "Value", "Text", values[0]);
months = new SelectList(months, "Value", "Text", values[1]);
days = new SelectList(days, "Value", "Text", values[2]);
result.Value = null;
}
else
{
var currentValue = ViewData.Model;
if (currentValue != null)
{
years = new SelectList(years, "Value", "Text", currentValue.Year);
months = new SelectList(months, "Value", "Text", currentValue.Month.ToString("00"));
days = new SelectList(days, "Value", "Text", currentValue.Day.ToString("00"));
}
}
And the last improvement - month names as text:
var months = Enumerable.Range(1, 12).Select(x => new SelectListItem { Value = x.ToString("00"), Text = System.Threading.Thread.CurrentThread.CurrentUICulture.DateTimeFormat.GetMonthName(x) });