ASP.NET MVC Select Option Value of SelectList - asp.net-mvc

I am rendering a dropdown list.
ViewBag.Categories = new SelectList(db.HelpCategories, "ID", "Name");
In my view I call it like this:
Categories: #Html.DropDownList("Categories", (SelectList)ViewBag.Categories, "All")
For which I get select values like this.
<select id="Categories" name="Categories">
<option value="">All</option>
<option value="1">Dėl Krepšelių</option>
</select>
I really need to set the value of "All" to 0. Can't figure out a way to do it. Found a tutorial that it's done with SelectListItem, but that doesn't fit my code.
Any help is really appreciated, thank you.

You can always build the SelectListItem list in your action method where you can add an item with the specific value and text explicitly, if you absolutely want that.
var categoryList = new List<SelectListItem>
{
new SelectListItem { Value="0", Text = "All"}
};
categoryList.AddRange(db.HelpCategories
.Select(a => new SelectListItem {
Value = a.Id.ToString(),
Text = a.Name}));
ViewBag.CategoryList = categoryList;
return View();
Now in your view, you will use ViewBag.CategoryList to build the SELECT element
#Html.DropDownList("Categories", ViewBag.CategoryList as IEnumerable<SelectListItem>)

Related

Razor #Html.DropDownList() do not take the selected value from List<SelectListItem> selected value

In my controller a have this:
List<SelectListItem> listItems = new List<SelectListItem>();
listItems.Add(new SelectListItem
{
Text = row["ProgramName"].ToString().Trim(),
Value = row["Id"].ToString().Trim(),
Selected = row["selected"].ToBoolean()
});
but when I send the object to the razor view I get it like this
#Html.DropDownList("ListaProgramas", (IEnumerable<SelectListItem>)ViewData["ListaProgramas"], new {#class = "form-control pull-left", #id = "ListaProgramas", #style = "color:black; width:100%;" })
That look like this:
but Razor not set selected value. What i would do for resolve this issue ?
The HTML is this
<select class="form-control pull-left" id="ListaProgramas" name="ListaProgramas" style="color:black; width:100%;">
<option selected="selected" value="1">VIADR</option>
<option value="2">TweakedBPclient</option>
</select>
But in my controller I selected a different one
List<SelectListItem> listItems = new List<SelectListItem>();
listItems.Add(new SelectListItem
{
Text = row["ProgramName"].ToString().Trim(),
Value = row["Id"].ToString().Trim(),
Selected = valor
});
I want HTML Razor view take as selected the element that I selected in the controller code.
When crafting your SelectList, use this form instead:
new SelectList(ViewData["ListaProgramas"], "Value" , "Text", itemToSelect);
Where itemToSelect is the appropriate row["Id"] - since you don't have a model in play, you can pass this value in via the ViewData, as well. That being said, I also advise using strongly-typed views and helpers and simply setting the value in the model that is passed to the view, thereby cutting out the need to specify the itemToSelect parameter altogether.

DropdownlistFor not getting selected value?

I have a DropdownlistFor that is not getting the value that is chosen in the DDL. I've done some research and tried implementing some of the suggestions I've seen but mine still isn't working.
I'm using an IEnumerable<SelectListItem> as well as a string property to hold that selected value in my view model.
public IEnumerable<SelectListItem> AvailableSeats { get; set; }
public string Seat { get; set; }
I set the Seat property to an initial value when the ViewModel is created.
Seat = "FO";
This is how I'm populating my SelectListItem. "FO" is always an option but they have "CA" I add that to the SelectList as well.
public static List<SelectListItem> GetAvailableSeats(string currentSeat)
{
List<SelectListItem> seats = new List<SelectListItem>();
seats.Add(new SelectListItem { Text = "FO", Value = "FO" });
if (currentSeat.ToUpper() == "CA")
seats.Add(new SelectListItem { Text = "CA", Value = "CA", Selected = true });
return seats;
}
This is my Razor View:
#Html.DropDownListFor(m => m.Seat, Model.AvailableSeats, new { #class = "form-control" })
The HTML that gets produced is:
<select class="form-control" id="Seat" name="Seat">
<option value="FO">FO</option>
<option selected="selected" value="CA">CA</option>
</select>
However, when I select "FO" as my option and then submit my form, the ViewModel still has "CA".
I finally stumbled across the problem after going through this
post.
I'm posting in case it might help someone else. Inside my form I was assigning the the "Seat" property to a hidden field #Html.HiddenFor(m => m.Seat) and I didn't nee to do that. Getting rid of that hidden field fixed the problem.

Why are the initial multiple selections of an Html.ListBox not visible?

I am testing a new plugin that converts a multiple-select ListBox to a set of multiple mutually-exclusive single-select drop-down lists. This should have been very straight-forward, as I just wanted to start with some items selected, but the answer eludes me so far.
I have reduced the problem to the following simple controller code (the plugin was turned off so is not a factor):
List<SelectListItem> selectList2 = db.LookupType.Select(x => new SelectListItem() { Selected = x.LookupTypeId < 4, Value = x.LookupTypeId.ToString(), Text = x.Name }).ToList();
ViewBag.LookupTypeId2 = selectList2;
This will mark Selected = true on the first three items as the IDs start at 1 (confirmed in debugger that the first 3 items have Selected = true).
And the view looks like this:
#Html.ListBox("LookupTypeId2", (IEnumerable<SelectListItem>)ViewBag.LookupTypeId2, htmlAttributes: new { #class = "form-control"})
The resulting output however has no selected items:
<select name="LookupTypeId2" class="form-control" id="LookupTypeId2" multiple="multiple">
<option value="1">Degree</option>
<option value="2">WorkdayLanguage</option>
<option value="3">Language_Ability_Type_ID</option>
<option value="4">National_ID</option>
<option value="5">Phone_Device_Type_ID</option>
<option value="6">Background_Check_Status_ID</option>
<option value="7">Educational_Institution_Type_ID</option>
<option value="8">Gender_Code</option>
<option value="9">Military_Status_ID</option>
<option value="10">Ethnicity_ID</option>
</select>
I have no problem selecting multiples with CTRL-Click etc, but the initial selections are not visible. What am I missing here?
Update: based on answer below I changed it to a ListBoxFor
#Html.ListBoxFor(x=>x.LookupTypeId2, (IEnumerable<SelectListItem>)ViewBag.LookupTypeId2, htmlAttributes: new { #class = "form-control"})
have added the following value initialization:
List<SelectListItem> selectList2 = db.LookupType.Select(x => new SelectListItem() { Selected = x.LookupTypeId < 4, Value = x.LookupTypeId.ToString(), Text = x.Name }).ToList();
lookup.LookupTypeId2 = new string[]{"1","2","3","4"};
ViewBag.LookupTypeId2 = selectList2;
Also tried with int array as suggested:
List<SelectListItem> selectList2 = db.LookupType.Select(x => new SelectListItem() { Selected = x.LookupTypeId < 4, Value = x.LookupTypeId.ToString(), Text = x.Name }).ToList();
lookup.LookupTypeId2 = new int[]{1,2,3,4};
ViewBag.LookupTypeId2 = selectList2;
But still nothing is selected.
Firstly you need a property to bind to. A multiple select will only post back a collection of value types, but your trying to bind to List<SelectListItem>. Add a property (say) public int[] SelectedItems { get; set; } to your model and then use
#Html.ListBoxFor(m => m.SelectedItems, (IEnumerable<SelectListItem>)ViewBag.LookupTypeId2, htmlAttributes: new { #class = "form-control"})
Then if the values of SelectedItems matches any of the options, those options will be selected, for example if model.SelectedItems = new int[] { 2, 10 }; then the 2nd and last options will be selected when you display the page. You do not (and should not) set the Selected property of SelectListItem when your binding to a property.

How set select element's first option value to 0 instead of empty option value?

I want to set first option value to 0 instead leaving it blank. How can I set this?
i.e
<select id="PatentId" name="ParentId">
<option value="0">--Select--</option>
<option value="1">Books</option>
// other options
</select>
My code is as
<div class="editor-field">
#Html.DropDownList("ParentId","--Select--")
#Html.ValidationMessageFor(model => model.ParentId)
</div>
You can't do this with the built-in helper. You will have to write a custom helper or hardcode or whatever.
Or simply use a view model and a nullable integer:
[Required]
public int? ParentId { get; set; }
Now you will no longer have any problems or needs to use 0 as first option.
Also it is better to use the strongly typed version of the helper:
#Html.DropDownListFor(model => model.ParentId, Model.Parents, "--Select--")
But if for some other reason (which I don't see at the moment) you need to use 0 as first option you are on your own in the wilderness.
Finally I found the following code working
private SelectList AddFirstItem(SelectList list)
{
List<SelectListItem> _list = list.ToList();
_list.Insert(0, new SelectListItem() { Value = "0", Text = "--Select--" });
return new SelectList((IEnumerable<SelectListItem>)_list, "Value", "Text", list.SelectedValue);
}
Keep the "Value" and "Text". The Last one list.SelectedValue is to keep selected values as it is.
You can use the above function like
public ActionResult Create()
{
ViewBag.ParentId = AddFirstItem(new SelectList(db.Categories, "Id", "Name"));
return View();
}
It worked.

ASP.NET MVC DropDownListFor does not honour SelectListItem.Selected

I am using DropDownListFor to render a dropdown list in a view. Somehow the rendered list does not select the SelectListItem with Selected set to true.
In the controller action:
var selectList = sortedEntries.Select(entry => new SelectListItem
{
Selected = entry.Value.Equals(selectedValue),
Text = entry.Value,
Value = entry.Id
});
return View(new DropDownListModel
{
ListId = id,
SelectList = selectList,
OptionLabel = "Click to Select"
});
In the view:
<%= Html.DropDownListFor(m => m.ListId,
Model.SelectList,
Model.OptionLabel,
new {#class="someClass"}) %>
I have tried the following:
make sure that there is one and only one items with Selected set to true.
remove the option label argument.
remove the HTML attribute object.
use SelectList in DropDownListFor:
Html.DropDownListFor(m => m.ListId,
new SelectList(Model.SelectList, "Value", "Text",
new List<SelectListItem>(Model.SelectList).Find(s => s.Selected)),
new {#class="someClass"})
Any suggestions as to what went wrong?
EDIT:
more information:
This action is a child action, called by another view with HTML.RenderAction
DropDownListFor will always select the value that the listbox is for, so in this case it will look at the value of ListId and make that item in the list selected. If ListId is not found in the list, the first item (or default text) will be selected. If you want a list that selects based on the selected attribute use DropDownList (without the For, in that case you have to name it yourself).
So in your case this would work:
var selectList = sortedEntries.Select(entry => new SelectListItem
{
Text = entry.Value,
Value = entry.Id
});
return View(new DropDownListModel
{
ListId = selectedValue,
SelectList = selectList,
OptionLabel = "Click to Select"
});
I got the same problem on the same model (with the other models in the decision no problem)
Does not work:
#Html.DropDownListFor(o => o.Drivers.ValueListItems.Value, Model.Drivers.ValueListItems, new { size = Model.Drivers.ValueSizeList, Multiple = "multiple" })
Works perfectly, the elements selected:
#Html.DropDownListFor(o => o.Drivers.ValueListItems.ToDictionary(u=>u.Value).Values, Model.Drivers.ValueListItems, new { size = Model.Drivers.ValueSizeList, Multiple = "multiple" })
Try like this:
var selectList = sortedEntries.Select(entry => new SelectListItem
{
Text = entry.Value,
Value = entry.Id
});
return View(new DropDownListModel
{
// The drop down list is bound to ListId so simply set its value
// to some element value in the list and it will get automatically
// preselected
ListId = selectedValue,
SelectList = selectList,
OptionLabel = "Click to Select"
});
and in the view:
<%= Html.DropDownListFor(
m => m.ListId,
new SelectList(Model.SelectList, "Value", "Text"),
Model.OptionLabel,
new { #class = "someClass" }
) %>
There could be one more gotcha: you are trying to change the selected value in a POST action. For example you rendered a form, the user selected some value in the dropdown, submitted the form and in your POST action you do some processing on this selected value and when you redisplay the view you want the drop down list to have some other value selected. In this case you will have to remove the initial selection which is contained in the ModelState or the Html helper will ignore the selected value in the model:
// do this before returning the view and only if your scenario
// corresponds to what I described above
ModelState.Remove("ListId");
The solution for this problem is simpler that we all think...
All we need to do is set the property on the view model for the element that the dropdown is bound to - i.e: ListId = 3 for example
this way when we do this
Html.DropDownListFor(m => m.ListId,
new SelectList(Model.SelectList, "Value", "Text",
new List<SelectListItem>(Model.SelectList).Find(s => s.Selected)),
new {#class="someClass"})
the HtmlHelper will automatically pick up the default value to display on the DropDownList
simples!
Hope it may help you and all the others - like me! - that have lost a lot of time searching for a solution for this apparent issue.

Resources