SelectList not selecting a default value from List<string> - c#

I am starting to get very annoyed with this, but no matter what, I am not able to get SelectedValue to work for a SelectList.
This is my code:
List<string> PickupTimeList = EntityLogic.PopulateTimeSlots(vm.DateMileage.PickupDate,
vm.DateMileage.PickupDate.AddHours(-2), vm.DateMileage.PickupDate.AddHours(2).AddMinutes(15));
ViewBag.PickupTimeList = new SelectList(PickupTimeList, "11:00 PM");
I don't have a Text/Key value here because Text/Key will also be a string and same thing. Anyway, by this code, it's still not selecting "11:00 PM" as the default item.
What can I do to fix this problem?

Try like this:
var pickupTimeList = EntityLogic.PopulateTimeSlots(
vm.DateMileage.PickupDate,
vm.DateMileage.PickupDate.AddHours(-2),
vm.DateMileage.PickupDate.AddHours(2).AddMinutes(15)
)
.Select(x => new SelectListItem
{
Value = x,
Text = x,
});
ViewBag.PickupTimeList = new SelectList(PickupTimeList, "Value", "Text", "11:00 PM");

Related

Display the text value of an index from ViewData list of items in MVC, Razor

I'll try to keep this short. I am new to MVC.
I have a Controller which creates a list of timeslots (like a schedule), and puts this into a ViewData. I understand how to do this.
I know how to display this data in a drop down menu using #Html.DropDownList, for example my create page has the following:
#Html.DropDownList("TimeSlot", ViewData["TimeSlotsList"] as List<SelectListItem>)
#Html.ValidationMessageFor(model => model.TimeSlot)
My problem is on my index view, it displays the modelItem => item.TimeSlot and shows the value of the Time slot, (1, 2, 3, 4, etc)
#Html.DisplayFor(modelItem => item.TimeSlot)
I want to display the TEXT value of the index from the ViewData[TimeSlotsList] list. Obviously the index will be the value of the modelItem => item.TimeSlot.
I know this would have been much easier if the TimeSlots was its own table in the database but it was not setup this way and at this point in time I can't change without causing myself all kinds of migration headaches, etc.
If anyone knows how to do this or can point me in the right direction it is hugely appreciated! I tried some different ideas but nothing has worked yet.....
EDIT:
I Create the list of timeslots in my controller with this function:
private List<SelectListItem> CreateTimeSlotsList()
{
//Build Time Slot Drop Down
List<SelectListItem> li1 = new List<SelectListItem>();
li1.Add(new SelectListItem { Text = "10-10:50am, Tues Mar. 17", Value = "1" });
li1.Add(new SelectListItem { Text = "11-11:50am, Tues Mar. 17", Value = "2" });
li1.Add(new SelectListItem { Text = "1:10-2pm, Tues Mar. 17", Value = "3" });
li1.Add(new SelectListItem { Text = "2:10-3pm, Tues Mar. 17", Value = "4" });
li1.Add(new SelectListItem { Text = "3:30-4:20pm, Tues Mar. 17", Value = "5" });
li1.Add(new SelectListItem { Text = "8:30-9:20am, Wed Mar. 18", Value = "6" });
li1.Add(new SelectListItem { Text = "9:30-10:20am, Wed Mar. 18", Value = "7" });
li1.Add(new SelectListItem { Text = "11-11:50am, Wed Mar. 18", Value = "8" });
li1.Add(new SelectListItem { Text = "1:10-2pm, Wed Mar. 18", Value = "9" });
li1.Add(new SelectListItem { Text = "2:10-3pm, Wed Mar. 18", Value = "10" });
li1.Add(new SelectListItem { Text = "Hands On/Demo", Value = "99" });
ViewData["timeSlots"] = li1;
return (li1);
}
Then i use
ViewData["TimeSlotsList"] = CreateTimeSlots();
I want to display the TEXT value of the index of the above list.
This isn't pretty, but:
If you don't have access to the text descriptions of the time slots that you used to create the TimeSlotList;
If you do still have the TimeSlotList in ViewData on the Index page;
... then you could try something like this:
#Html.DisplayFor( modelItem =>
((List<SelectListItem>) ViewData["TimeSlotsList"])
.Single(sli => sli.Value==modelItem.TimeSlot)
.Text)
ETA: But you know what I'd do? I'd create a model for a TimeSlot object, populate a master list of them the way you're doing in your CreateTimeSlots function, and return that from your data layer the way you would the model objects you're getting. Basically, simulate a master TimeSlot table.
Then I'd use that to
Build your TimeSlotsList, and
Build a ViewModel based on your model object that includes a TimeSlot object from your master list.
Then, you could do something like:
#Html.DisplayFor(modelItem => item.TimeSlot.TimeSlotDescription)
... on your Index page.

Why does binding a DropDownList function differently than manually adding ListItems?

Snippet One
I add list items to my drop down one at a time.
var ddlHour = new DropDownList {ID = "ddlHour" + i};
ddlHour.Items.Add(new ListItem("12 AM", "0:00"));
ddlHour.Items.Add(new ListItem("1 AM", "1:00"));
ddlHour.Items.Add(new ListItem("2 AM", "2:00"));
Console.WriteLine(ddlHour.Items[0].Value);
// Prints 0:00
Snippet Two
I bind my drop down to an array of list items.
var hourItems = new[]
{
new ListItem("12 AM", "0:00"), // "Text", "Value"
new ListItem("1 AM", "1:00"),
new ListItem("2 AM", "2:00")
};
var ddlHour = new DropDownList {ID = "ddlHour" + i, DataSource = hourItems};
ddlHour.DataBind();
Console.WriteLine(ddlHour.Items[0].Value);
// Prints 12 AM
After the first snippet executes, I inspect the values of each item and find "0:00", "1:00", and "2:00". Exactly what I expect.
After the second snippet executes, I inspect the values of each item and find "12 AM", "1 AM", and "2 AM". Not what I expect. What happened to my values?
They are same. Only different is that if you use DataSource, you need to specify DataTextField and DataValueField.
...
ddlHour.DataBind();
ddlHour.DataTextField = "Text";
ddlHour.DataValueField = "Value";
Console.WriteLine(ddlHour.Items[0].Value);

Get drop down list default selected item is not passing to the controller in Asp.net MVC

I have a problem when the user (Edit the event) it display drop down list for time, and text box for date.
But when the user submit the form the, edit action is not receiving the old value for time.
This code works fine if the user changes the time value, it will get the value. otherwise. it wont.
Please help me.
**the code**
Html.DropDownListFor(x=>x.StartTime, Model.Times,
Model.Appointment.StartDate.ToString("hh:mm tt"), new {#class = "dropdownlist" })
public ActionResult Edit(int id = 0){
Appointment app = eventService.GetEventByID(id);
EventViewModel model = new EventViewModel()
{ Appointment =app,
StartTime = app.StartDate.ToString("hh:mm tt"),
EndTime = app.EndDate.ToString("hh:mm tt"),
Times = TimesSelectListItem, };
// Get the time portion of our date/time from our drop down lists
DateTime startTime = Convert.ToDateTime(model.StartTime);
DateTime endTime = Convert.ToDateTime(model.EndTime);
// Create a new date based on the date from our date picker, and time from our drop down lists:
model.Appointment.StartDate = new DateTime(model.Appointment.StartDate.Year, model.Appointment.StartDate.Month, model.Appointment.StartDate.Day, startTime.Hour, startTime.Minute, startTime.Second);
model.Appointment.EndDate = new DateTime(model.Appointment.EndDate.Year, model.Appointment.EndDate.Month, model.Appointment.EndDate.Day, endTime.Hour, endTime.Minute, endTime.Second);
if (model == null) {
return HttpNotFound(); }
PopulatePriorityDropDownList(model.Appointment.FK_PriorityID);
PopulatePrivacyDropDownList(model.Appointment.FK_PrivacyID);
PopulateTypeDropDownList(model.Appointment.FK_AppointmentTypeID);
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(EventViewModel model, int id, string PriorityID, string PrivacyID, string TypeID)
{
//------------
this is in the controler...
IEnumerable<SelectListItem> TimesSelectListItem = new[] {
new SelectListItem{ Text="6:00 AM", Value = "6:00 AM" },
new SelectListItem{ Text="6:30 AM", Value = "6:30 AM" },....etc}
StartTime/ StartTime : string, only to display in the view.
StartDate/ EndDate: dateTime type from db.
If the value of StartTime does not match one of the properties in the SelectList then the value of the select will be null on postback because you have used an option label in DropDownListFor() (this renders an option with no value).
Check that the value of StartTime exactly matches the value of one of the options.
If you always set the initial value then remove the 3 parameter of the DropDownListFor() method
#Html.DropDownListFor(x=>x.StartTime, Model.Times, new {#class = "dropdownlist" })
otherwise, make it a user friendly message so its clear that the user should select something
Html.DropDownListFor(x=>x.StartTime, Model.Times, "Please select a time"), new {#class = "dropdownlist" })

Selected value not set on DropDownListFor() in MVC4

It seems like this question has been asked too many times. But this is driving me nuts.
This is my (simplified) model.
public class UserEditModel
{
[Required]
public string Title { get; set; }
private IEnumerable<SelectListItem> _titleList;
public IEnumerable<SelectListItem> TitleList
{
get { return _titleList.Select(x => new SelectListItem {
Selected = (x.Value == Title),
Text = x.Text,
Value = x.Value
});
}
set { _titleList = value; }
}
}
The Text and Value properties of each SelectListItem in the TitleList member are identical. For example:
new SelectListItem { Text = "Mr", Value = "Mr" }
When the following code is posted, the correct Title value is bound to the model, but whenever the model is pushed to the view in response to a POST or a GET, the selected value is not set on the dropdownlist, even though all the intellisense shows that the correct values are present.
#Html.DropDownListFor(x => x.Title, Model.TitleList)
I have ensured that the code is correct based on several articles and several SO answers, so I am stumped.
Any suggestions?
Update:
For completeness, this is the action and supporting method:
[HttpGet]
public ActionResult Edit(int id)
{
var user = _userService.Get(id);
var model = new UserEditModel()
{
...
Title = user.Title,
TitleList = ListTitles()
};
return View(model);
}
private IEnumerable<SelectListItem> ListTitles()
{
var items = new[] {
new SelectListItem() {Text = "Mr", Value = "Mr" },
new SelectListItem() {Text = "Mrs", Value = "Mrs"},
new SelectListItem() {Text = "Ms", Value = "Ms"},
new SelectListItem() {Text = "Miss", Value = "Miss"},
new SelectListItem() {Text = "Professor", Value = "Professor"},
new SelectListItem() {Text = "Dr", Value = "Dr" }
};
return items;
}
As you see there is nothing fancy, just a straightforward implementation.
You need to add ModelState.Clear() because by default when returning a view from a post action, it thinks it has failed validation, so uses the values in ModelState and not the values in the Model. Many people think this is actually a bug in MVC, but it's by design:
ASP.NET MVC assumes that if you’re rendering a View in response to a HttpPost, and you’re using the Html Helpers, then you are most likely to be redisplaying a form that has failed validation. Therefore, the Html Helpers actually check in ModelState for the value to display in a field before they look in the Model. This enables them to redisplay erroneous data that was entered by the user, and a matching error message if needed.
Link
Well, it seems there is actually nothing wrong with the code, just the name of the Title property in the model.
It looks like Title is a reserved word and replacing it with TitleX or more appropriately Salutation makes everything work fine.
Are you sure you retrieve the selectlist item appropriately in the controller?
For me it is working fine.
I would use a get method instead of a property ( GetTitleList(string value) ), to avoid mistakes in getting the selectionlist farther along in your code.

Setting Selected Value of DropDownList in MVC 3

I have gone through numerous methods of trying to set the value of a dropdownlist and must be doing something silly because none of the methods are working.
#Html.DropDownList("startTime", #Model.startTimeList, new { #class = "startTime", style = "width: 100px;" })
Its a generated list of half hour increments.
In my controller I set this string value..
model.startTime = myTime + " " + amOrPm; //ex 10:30 PM
My List looks like this.
List<SelectListItem> startTimeList = new List<SelectListItem>();
SelectListItem time12 = new SelectListItem { Text = "12:00 PM", Selected = false, Value = "12:00PM" };
startTimeList.Add(time12);
SelectListItem time12Half = new SelectListItem { Text = "12:30 PM", Selected = false, Value = "12:30PM" };
startTimeList.Add(time12Half);
My list always defaults to 12:00 PM because its the first one entered into the list. I want that if model.startTime has a value it sets to that value.
You can use DropDownListFor and let the Razor engine do the work of selecting the item that matches the property.
#Html.DropDownListFor(model => model.startTime, startTimeList)
The alternative would be to explicitly set Selected on the item that matches:
startTimeList.First(item => item.Text.Equals(model.startTime)).Selected = true;
If you have a startTime property on your model, and the value of that property matches one of the values in the list (ie, it matches "12:00PM", or "12:30PM" but not "12:00 PM" or "12:30 PM"), then I think this should work:
#Html.DropDownListFor(model => model.startTime,
#Model.startTimeList,
new { #class = "startTime", style = "width: 100px;" })

Categories

Resources