Reputation: 709
I want an dropdownList with short date format. But none of the following works. I have
[Property]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime? DepartrueDate { get; set; }
In the view, I tried
<div>@Html.DropDownListFor(m => m.TripDepartures.First().DepartrueDate, new SelectList(Model.TripDepartures.Select(s=>
new SelectListItem { Value = s.Id.ToString(), Text = s.DepartrueDate.Value.ToShortDateString() }).ToList()))</div>
</div>
It gave no output; I also tried
<div>@Html.DropDownListFor(m => m.TripDepartures.First().DepartrueDate, new SelectList(Model.TripDepartures, "Id","DepartrueDate"))</div>
</div>
It gives
How could I get a short date?
Upvotes: 2
Views: 5527
Reputation: 892
Shouldn't it be:
@Html.DropDownListFor(m => m.TripDepartures.First().Id.ToString(), new SelectList(Model.TripDepartures.Select(s=>
new SelectListItem() { Value = s.Id.ToString(), Text = s.DepartrueDate.Value.ToShortDateString() }).ToList()))
If it doesn't work: Are you sure Model.TripDepartures has elements?
I remember I have added the SelectList a few times in the model myself, so you can try adding a property in you Model, that is of type SelectList. You can add a SelectListItem for each DepartureDate setting the id and value yourself and loop and debug through it yourself. It is basically the same as your Linq code, but I do remember I have done this for a reason.
Model.DepartureDateSelectList = new SelectList();
foreach (TripDeparture tripDeparture in Model.TripDepartures) {
{
SelectListItem item = new SelectListItem();
item.Value = tripDeparture.Id.ToString();
item.Text = tripDeparture.DepartueDate.Value.ToShortDateString(); //Didn't do a null check, since you didn't do it in you code either. You should change DataType to non-nullable or perform a check and handle if it's null
Model.DepartureDateSelectList.Add(item);
}
If you do see the list but the default selected item isn't set, then apply the suggested change to the selected item expression. If it still isn't set correctly you can set the selected property in the loop yourself. There's a bug in the DropDownListFor that results in selected item not always being set.
Upvotes: 1
Reputation: 62290
Ideally, you do not want to pass domain entities (TripDepartures) to View from Controller. It is not a good design practice.
Instead, you want to pass SelectListItem.
@using (Html.BeginForm())
{
@Html.DropDownListFor(m => m.SelectedTripDepartureId, Model.AvailableTripDepartures)
<input type="submit" value="Submit" />
}
public class HomeModel
{
public int SelectedTripDepartureId { get; set; }
public IList<SelectListItem> AvailableTripDepartures { get; set; }
public HomeModel()
{
AvailableTripDepartures = new List<SelectListItem>();
}
}
public class HomeController : Controller
{
public ActionResult Index()
{
HomeModel model = new HomeModel();
model.AvailableTripDepartures = GetTripDepartures()
.Select(s => new SelectListItem
{
Value = s.Id.ToString(),
Text = s.DepartrueDate.Value.ToString("MM/dd/yyyy")
}).ToList();
return View(model);
}
[HttpPost]
public ActionResult Index(HomeModel model)
{
int tripDepartureId = model.SelectedTripDepartureId;
DateTime? departrueDate = GetTripDepartures()
.Where(x => x.Id == tripDepartureId)
.Select(x => x.DepartrueDate)
.FirstOrDefault();
return View(model);
}
// This data will be from persistent storage such as database.
private IList<TripDeparture> GetTripDepartures()
{
return new List<TripDeparture>
{
new TripDeparture {Id = 1, DepartrueDate = DateTime.Now.AddDays(1)},
new TripDeparture {Id = 2, DepartrueDate = DateTime.Now.AddDays(2)},
new TripDeparture {Id = 3, DepartrueDate = DateTime.Now.AddDays(3)},
};
}
}
public class TripDeparture
{
public int Id { get; set; }
public DateTime? DepartrueDate { get; set; }
}
Upvotes: 2
Reputation: 4146
You could cheat the system and bind to a string field instead of the date field:
[Property]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime? DepartrueDate { get; set; }
public string DepartrueDateText { get { return DepartrueDate.ToShortDataString(); } }
Don't forget your null check though. :)
I do this quite a bit for enumeration fields to get the [Display(Name="")] attribute to be recognized.
Upvotes: 0