Dropdownlistfor selected text and value ASP.NET MVC - asp.net-mvc

I have three dropdownlistfor in edit mode, i am able to populate the correct text in DDLFor but the id of it is coming up as 0 on submit, but if i select a different team it is coming up with correct id. Following is my code
ViewModel
public List<SelectListItem> TeamOneList { get; set; }
public string SelectedTeamOne { get; set; }
.... //remaining properties for DDL's..........
Controller
List<SelectListItem> TeamOneList = new List<SelectListItem>();
foreach (var item in db.Teams)
{
TeamOneList.Add(new SelectListItem { Text = item.TeamName, Value = item.TeamId.ToString() });
}
string SelectedTeamOne = db.Teams.Where(o => o.TeamId == fixture.TeamOneId).Select(s => s.TeamName).Single();
View
#Html.DropDownListFor(model => model.TeamOneId, Model.TeamOneList, Model.SelectedTeamOne, new { #class = "form-control" })

Your generating the option value attribute based on the TeamId property of Team, but your setting the SelectedTeamOne value based on the TeamName name property, so the value of SelectedTeamOne does not match any of the options, therefore the first option (the null label option) is selected (because something has to be).
But you generating the null label option with the same text as SelectedTeamOne so it appears your are selecting it when in fact your only selecting the option with a null value (there is actually a second option with the same name in your dropdownlist).
Your need to change the code in the view to
#Html.DropDownListFor(model => model.SelectedTeamOne, Model.TeamOneList, "-Please select-", new { #class = "form-control" })
and then change the controller code to
SelectedTeamOne = db.Teams.Where(o => o.TeamId == fixture.TeamOneId).Select(s => s.TeamId).Single();
Note that it appears TeamId is typeof int, therefore your SelectedTeamOne property should also be int, not string
public int SelectedTeamOne { get; set; }
In addition, you can simply use
var model = new yourModelName
{
TeamOneList = db.Teams.Select(x => new SelectListItem>
{
Value = x.TeamId.ToString(),
Text = x.TeamName
}),
SelectedTeamOne = fixture.TeamOneId // no need to make a database call
};
return View(model);
or, even simpler
var model = new yourModelName
{
TeamOneList = new Selectist(db.Teams, "TeamId", "TeamName"),
SelectedTeamOne = fixture.TeamOneId // no need to make a database call
};
return View(model);

Related

Placeholder on a #Html.Dropdownlist that is not selectable

How do i put a placeholder on my #Html.Dropdownlist that is not selectable.
I implemented chosen-jquery on my dropdown.
My code is as per below:
#Html.DropDownList("Id", new SelectList(new Ahib.Membership.UserFacade().GetAllUsers(), "Id", "Username"), "-select a system owner-", new { #class="chosen1-select" })
Currently my dropdownlist has a placeholder but the "-select a system owner-" becomes a selectable value which i dont want. How do solve this issue?
You can convert your list to the selectitem list and apply your disabled attribute from the controller itself.
like this
assuming your model is like this
class user
{
public int Id { get; set; }
public string Username { get; set; }
}
Convert your list to List<SelectListItem> like this, note here I am disabling the select a system owner entry.
public ActionResult Index()
{
List<user> users = new List<user>();
users.Add(new user { Id = 1, Username = "test1" });
users.Add(new user { Id = 2, Username = "test2" });
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem { Text = "-select a system owner-", Value = "0", Disabled = true });
foreach (var item in users)
{
list.Add(new SelectListItem
{
Text = item.Username,
Value = item.Id.ToString()
});
}
ViewBag.listItems = list;
return View();
}
and in view use it like this
#Html.DropDownList("test", ViewBag.listItems as IEnumerable<SelectListItem>);
Result:

How to set the default value for Html.DropDownListFor in MVC

i have following code :
controller method:
public ActionResult Register(int? registrationTypeId)
{
IEnumerable<AccountType> accountTypes = new List<AccountType>
{
new AccountType
{
AccountTypeId = 1,
AccountTypeName = "Red"
},
new AccountType
{
AccountTypeId = 2,
AccountTypeName = "Blue"
}
};
// I want to select account type on registrationTypeId
ViewBag.AccountTypes = accountTypes;
return View();
}
View
<div class="col-md-10">
#Html.DropDownListFor(n => n.AccountType,
new SelectList(ViewBag.AccountTypes, "AccountTypeId", "AccountTypeName"), new { #class = "form-control" })
</div>
Model
public class RegisterViewModel
{
[Required]
[Display(Name = "Account Type")]
public int AccountType { get; set;
}
As you can see registrationTypeId in controller , i want to set the type on its bases if it is not null ,otherwise set to red. I have tried a alot but nothing worked for me. Any help will be appreciated !
I would highly recommend that you don't pass your list through the view bag. have seen too many questions where that has caused major issues. add this to your model
public List<SelectListItem> AccountTypes { get; set; }
in your controller in the get method set your default and set your list
Model.AccountType = 1; // change the one to your default value
Model.AccountTypes = accountTypes; //instead of ViewBag.AccountTypes = accountTypes;
then on your view
#Html.DropDownListFor(x => x.AccountType, Model.AccountTypes)
setting AccountType before passing the model to the view will set the default and the selected value on the view will be passed back in that same value.
The Wrong Way To Do This
var accountTypes = new SelectList(accountTypes, "AccountTypeId", "AccountTypeName");
foreach(var item in accountList)
if (item.AccountTypeId == registrationTypeId)
item.Selected = true;
ViewBag.AccountTypes = accountTypes;
In view,
#Html.DropDownListFor(n => n.AccountType, (SelectList)ViewBag.AccountTypes)

SelectList how to set selected item only when valid value for System.Web.Mvc.SelectList

When you create a SelectList you can optionally pass in the SelectedValue property for which the documentation says
// selectedValue:
// The selected value. Used to match the Selected property of the corresponding
// System.Web.Mvc.SelectListItem.
However, if you pass it a value object which is not contained in the list of items, it still sets the selected value. Try this:
using System.Web.Mvc;
class SomeItem
{
public int id { get; set; }
public string text { get; set; }
}
class CreateSelectList
{
public static SelectList CreateSelectList()
{
List<SomeItem> items = new List<SomeItem>();
for (int i = 0; i < 3; i++)
{
items.Add(new SomeItem() { id = i, text = i.ToString() });
}
// 5 is not in the list of items yet the property SelectedValue does = 5
return new SelectList(items, "id", "text", 5);
}
}
My questions are:
Since I want to lazily set my selected value only if it exists, I just want to pass in a value and have it ignored when it does not exist in the list, but how? (is this a bug or a design feature), or
If you create a SelectList without the SelectedValue, after you have constructed it, how can you set the SelectedValue (again when it exists in the list) ?
If your code is near to your real scenario, you could use something like this
// check if there is any element with id = 5
if (items.Any(i => i.id == 5))
{
// there is an element with id = 5 so I set the selected value
return new SelectList(items, "id", "text", 5);
}
else
{
// there is no element with id = 5 so I don't set the selected value
return new SelectList(items, "id", "text");
}

why is my dropdown selection not being submitted?

I have a dropdown list when the form is submitted it is submitted null...
html:
#Html.DropDownListFor(c => Model.HowOftenCar, Model.HowOftenCar, new { id = "CompDrop" })
Model:
public IEnumerable<SelectListItem> HowOftenCar { get; set; }
Controller:
IList<string> HowOftenCar = new List<string>();
HowOftenCar.Insert(0, "More than once a week");
HowOftenCar.Insert(1, "Once a month");
HowOftenCar.Insert(2, "Once a year");
model.HowOftenCar = HowOftenCar.Select(c => new SelectListItem()
{
Text = c,
Value = c
});
Post:
[HttpPost]
public ActionResult Index(Competition model)
{
if (ModelState.IsValid)
{}
}
I have also tried...
#Html.DropDownListFor(c => Model.HowOftenCar, new SelectList(Model.HowOftenCar, "Value","Text"), new { id = "CompDrop" })
You're not using DropDownListFor correctly.
The first parameter is the property on the model you want to populate. If you want to populate the HowOftenCar property on the model, it should be of the type of the value - in this case, it looks like a string.
public string HowOftenCar { get; set; }
The second parameter is the list of choices. You've got that right, but it needs to be something else than the property you're trying to set.
IList<string> HowOftenCarChoices = new List<string>
{
"More than once a week",
"Once a month",
"Once a year"
};
model.HowOftenCarChoices = HowOftenCar.Select(c => new SelectListItem()
{
Text = c,
Value = c
});
So then you'll end up with
#Html.DropDownListFor(m => m.HowOftenCar, Model.HowOftenCarChoices)
Note that you don't need the id property, because DropDownListFor will automatically give it the id of HowOftenCar, based on the lambda.

Problem with DropDownListFor SelectedItem

This has totally puzzled me.
Here's my View:
#Html.DropDownListFor(model => model.ScoreDescription,
Model.RatingOptions,
"--",
new { #id = clientId })
And the model:
public decimal? Score { get; set; }
public SelectList RatingOptions
{
get
{
var options = new List<SelectListItem>();
for (var i = 1; i <= 5; i++)
{
options.Add(new SelectListItem
{
Selected = Score.HasValue && Score.Value == Convert.ToDecimal(i),
Text = ((decimal)i).ToRatingDescription(ScoreFactorType),
Value = i.ToString()
});
}
var selectList = new SelectList(options, "Value", "Text");
// At this point, "options" has an item with "Selected" to true.
// Also, the underlying "MultiSelectList" also has it.
// Yet selectList.SelectedValue is null. WTF?
return selectList;
}
}
As the comments suggest, i can't get the selected value to happen.
Is it something to do with the fact i'm using a nullable decimal ? After that loop, options is correct in that it has exactly 1 item with select to true, so it seems i'm doing the right thing.
Now, if i use a different SelectList overload:
var selectedValue = Score.HasValue ? Score.Value.ToString("0") : string.Empty;
var selectList = new SelectList(options, "Value", "Text", selectedValue);
It works. Why? At first i thought it might be a LINQ-trick (e.g deferred execution), but i tried forcing a .ToList() and there is no difference.
It's like setting the Selected property as you create the SelectListItem has no effect, and you have you set it at the end using the SelectList ctor parameter.
Can anyone shed some light on this?
If you look at the implementation of the SelectList class it never actually uses the fact that you are passing a SelectListItem. It works with an IEnumerable. So the Selected property of a SelectListItem is not used. Personally I prefer setting the selected value of a dropdown by setting the value of the corresponding property that you are binding the ddl to.
Example:
public int? Score { get; set; }
public SelectList RatingOptions
{
get
{
var options = Enumerable.Range(1, 5).Select(i => new SelectListItem
{
Text = ((decimal)i).ToRatingDescription(ScoreFactorType),
Value = ((decimal)i).ToString()
});
return new SelectList(options, "Value", "Text");
}
}
and then in the controller action simply set the Score property to the necessary value and in the view use this Score property to bind to:
#Html.DropDownListFor(
model => model.Score,
Model.RatingOptions,
"--",
new { #id = clientId }
)

Resources