I have a gender select field (--Select--, Male, Female) and I'm populating that in my controller. When the page loads, I want the gender that is selected in the model pm.Gender to be automatically selected when the page loads.
The values from pm.Gender come back as:
" "
"M"
"F"
View:
<%: Model.Gender %>
<%: Html.DropDownListFor(m => m.Gender, (IEnumerable<SelectListItem>)ViewData["gender"], new { #class = "span2" })%>
Controller:
gender = new[] { "Select", "Male", "Female" };
List<SelectListItem> genderselectList = new List<SelectListItem>();
foreach (string item in gender)
{
SelectListItem sli = new SelectListItem { Text = item, Value = item };
if (item.Trim().StartsWith(pm.Gender))
sli.Selected = true;
genderselectList.Add(sli);
}
ViewData["gender"] = genderselectList;
After debugging the application, I can see that genderselectList contains the proper data with Selected = true for the proper value that is supposed to be selected. But when the page loads, nothing is selected in the dropdown list that was supposed to be generated with the Html.DropDownListFor.
Edit: Does not work in any browser.
Anyone know what could be causing this problem? Any help would be appreciated.
Cheers.
EDIT: (After implementing Kaf's solution)
Ok so this is what I'm doing after implementing Kaf's solution.
View:
<%: Html.DropDownListFor(m => m.Gender, (SelectList)(ViewData["gender"]), new { #class = "span2" }) %>
Controller:
gender = new[] { "Select", "Male", "Female" };
List<SelectList> genderselectList = new List<SelectList>();
foreach (string item in gender)
{
SelectList sli;
if (item.Trim().StartsWith(pm.Gender))
sli = new SelectList(GetGender(), item, item, item);
else
sli = new SelectList(GetGender(), item, item);
//without selectedValue
genderselectList.Add(sli);
}
ViewData["gender"] = genderselectList;
When I do that, I get the following exception:
Unable to cast object of type 'System.Collections.Generic.List`1[System.Web.Mvc.SelectList]' to type 'System.Web.Mvc.SelectList'.
Anyone know what I'm doing wrong?
I suggest it's better if you use strongly typed property for SelectList (rather than using ViewBag/ViewData). I believe what you are expecting is that your dropdownlist to be pre-selected with the gender selection made in the model. Here is a solution (code is not 100% clean. But this will work)
Model
public class TestModel
{
public string Gender { get; set; }
public IEnumerable<SelectListItem> GenderList
{
get
{
List<SelectListItem> list = new List<SelectListItem> { new SelectListItem() { Text = "Select", Value = "Select" }, new SelectListItem() { Text = "Male", Value = "Male" }, new SelectListItem() { Text = "Female", Value = "Female" } };
return list.Select(l => new SelectListItem { Selected = (l.Value == Gender), Text = l.Text, Value = l.Value });
}
}
}
Controller Action
public ActionResult MyView()
{
TestModel m = new TestModel();
m.Gender = "Female";
return View(m);
}
MyView.cshtml
#model TestModel
#{
ViewBag.Title = "MyView";
}
<h2>MyView</h2>
#using (Html.BeginForm())
{
<div>
#Html.DropDownListFor(model => model.Gender, Model.GenderList)
</div>
}
OUTPUT
dropdown with 'Female' option selected
EDIT
Based on comments find below links to sample projects
1) https://github.com/prashanth-t/DropdownDemo_BareBones (Using the MVC 4 empty template. Smaller file size with bare minimum)
2) https://github.com/prashanth-t/DropdownDemo (Using the MVC 4 internet application template. Bigger file size)
This is a known bug in ASP.NET MVC Razor View. As per the known bug documentation
"The reason behind this problem is that asp.net MVC first looks for a match between the name of the drop down and property on the model. If there’s a match, the selected value of the SelectList is overridden. Changing the name of the drop down is all it takes to remedy the issue."
I'm here giving a small example which you can use to test the resolution.
var paymentTypeList = new List<SelectListItem>
{
new SelectListItem { Text = "Select Payment Type", Value = "NA" },
new SelectListItem { Text = "Card", Value = "Card" },
new SelectListItem { Text = "Paytm Wallet", Value = "Paytm Wallet" },
new SelectListItem { Text = "Cash", Value = "Cash", Selected = true },
new SelectListItem { Text = "Credit", Value = "Credit" },
new SelectListItem { Text = "Other", Value = "Other" }
};
ViewBag.paymentTypeList = paymentTypeList;
Resolution Option 1 (Easiest) - Change the Name of declaration id of select list id in MVC view e.g
#Html.DropDownList("paymentTypeListNew", (List<SelectListItem>)ViewBag.paymentTypeList, new { #class = "form-control select2 select1" })
Resolution 2: (Use only single constructor of #Html.DropDownList that matches viewbag/viewdata property)
To ensure that selected item (cash in this example) gets selected do the following in MVC Razor View. Use only the following constructor without any CSS or new object values
#Html.DropDownList("paymentTypeList")
Now if you are worried that you cannot initialize the CSS then you need to initialize the css programitally. For example if you are using Jquery then can you can use
$("#paymentTypeList").addClass("form-control");
$("#paymentTypeList").addClass("select2");
Method to get genders with select:
private Dictionary<string,string> GetGender(){
Dictionary<string, string> myDic = new Dictionary<string, string>();
myDic.Add(System.DBNull.Value.ToString(), "Select");
myDic.Add("Male", "Male");
myDic.Add("Female", "Female");
return myDic;
}
In the controller:
//without selectedValue
ViewData["gender"] = new SelectList(GetGender(), "Key", "Value");
OR
//"Male" as selectedValue
ViewData["gender"] = new SelectList(GetGender(), "Key", "Value", "Male");
In the view:
Html.DropDownListFor(m => m.Gender, (SelectList)(ViewData["gender"]),
new { #class = "span2" })
Try this instead in the controller:
string[] gender = new string[] {"Male", "Female"};
string selectedGender = gender.Where(x => x.StartsWith(pm.gender)).FirstOrDefault();
ViewData["gender"] = new SelectList(gender, selectedGender);
And in the view:
<%: Html.Dropdownlist(x => x.Gender, ViewData["gender"], "Select") %>
After searching myself for answer to this problem - I had some hints along the way but this is the resulting solution. It is an extension Method. I am using MVC 5 C# 4.52 is the target. The code below sets the Selection to the First Item in the List because that is what I needed, you might desire simply to pass a string and skip enumerating - but I also wanted to make sure I had something returned to my SelectList from the DB)
Extension Method:
public static class SelectListextensions
{
public static System.Web.Mvc.SelectList SetSelectedValue
(this System.Web.Mvc.SelectList list, string value)
{
if (value != null)
{
var selected = list.Where(x => x.Text == value).FirstOrDefault();
selected.Selected = true;
}
return list;
}
}
And for those who like the complete low down (like me) here is the usage.
The object Category has a field defined as Name - this is the field that will show up as Text in the drop down. You can see that test for the Text property in the code above.
Example Code:
SelectList categorylist = new SelectList(dbContext.Categories, "Id", "Name");
SetSelectedItemValue(categorylist);
select list function:
private SelectList SetSelectedItemValue(SelectList source)
{
Category category = new Category();
SelectListItem firstItem = new SelectListItem();
int selectListCount = -1;
if (source != null && source.Items != null)
{
System.Collections.IEnumerator cenum = source.Items.GetEnumerator();
while (cenum.MoveNext())
{
if (selectListCount == -1)
{
selectListCount = 0;
}
selectListCount += 1;
category = (Category)cenum.Current;
source.SetSelectedValue(category.Name);
break;
}
if (selectListCount > 0)
{
foreach (SelectListItem item in source.Items)
{
if (item.Value == cenum.Current.ToString())
{
item.Selected = true;
break;
}
}
}
}
return source;
}
You can make this a Generic All Inclusive function / Extension - but it is working as is for me.
Try this;
public static List<SelectListItem> ListSexo { get; } = new List<SelectListItem>
{
new SelectListItem{Selected =true, Value="N", Text="Seleccione"},
new SelectListItem{Value="F", Text="Femenino"},
new SelectListItem{Value="M", Text="Masculino"}
};
<select asp-for="Sexo" asp-items="Commons.ListSexo" class="form-control"></select>
Related
I'm trying to do a multiple selection with ListBoxFor of Razor, but the select does not allow me to select multiple items (I can do that only selecting my items with Ctr+click the second item). I've reduced my code to minimal like the exemple shown in this answer (my code is above). Anyone can help me?? I'm desperate.
My Model
public IEnumerable<int> ParoleChiave { get; set; }
public IEnumerable<SelectListItem> ListaParoleChiave { get; set; }
My Controller
model.ListaParoleChiave = new List<SelectListItem>() {
new SelectListItem(){ Text = "Pro", Value = "2"},
new SelectListItem(){ Text = "Test", Value = "3"}
};
My View
<div class="form-group form-group-sm">
<label class="col-xs-12">Parole chiave</label>
<div class="col-xs-12">
#Html.ListBoxFor(m => m.ParoleChiave, Model.ListaParoleChiave, new { #class = "form-control", style = "width: 100%" })
</div>
</div>
I found the error. It's not depending from my ListBoxFor element, it was caused by the js code that I wrote to post to the server action my formData with additional data.
Basically it was like:
data: function (d) {
var fd = new FormData(myForm[0]);
for (var pair of fd.entries()) {
d[pair[0]] = pair[1];
}
return d;
}
I realized that the multiple values where posting like two entries (key/value pairs) of the FormData but with the same key name, so my code was overwriting the first entry with the second. I replaced with the code above and now it works like a charm.
data: function (d) {
var fd = new FormData(myForm[0]);
for (var pair of fd.entries()) {
var occurenceOfKey = Array.from(fd.keys()).reduce(function (n, val) {
return n + (val === pair[0]);
}, 0);
if (occurenceOfKey > 1)
d[pair[0]] = fd.getAll(pair[0]);
else
d[pair[0]] = pair[1];
}
return d;
}
This question already has answers here:
MVC5 - How to set "selectedValue" in DropDownListFor Html helper
(5 answers)
Closed 5 years ago.
I have a IEnumerable<SelectListItem>
My ViewModel
public class StatusClass
{
public string Status { get; set; }
public IEnumerable<SelectListItem> StatusList { get; set; }
}
I set values in to StatusList from my controller.
StatusClass statusObj = new CRM.StatusClass();
List<SelectListItem> Discountdata = new List<SelectListItem>();
Discountdata.Add(new SelectListItem() { Value = "All", Text = "All" });
Discountdata.Add(new SelectListItem() { Value = "Draft", Text = "Draft" });
Discountdata.Add(new SelectListItem() { Value = "Issued", Text = "Issued" });
Discountdata.Add(new SelectListItem() { Value = "Partial", Text = "Partially Received" });
Discountdata.Add(new SelectListItem() { Value = "Received", Text = "Received" });
Discountdata.Add(new SelectListItem() { Value = "PAID", Text = "Paid" });
Discountdata.Add(new SelectListItem() { Value = "Billed", Text = "Billed" });
statusObj.StatusList = new SelectList(Discountdata, "Value", "Text");
This works fine and my HTML is like this:
#Html.DropDownListFor(model => model.Status, Model.StatusList)
What i want is, I need to set the selected value from the controller when the list get created.
Suppose I have a string like this:
string newwStatus = "Issued";
How can I set it as selected in the SelectListItem.
I tried this, but its not working in my case:
foreach(var item in StatusList)
{
if(item.value == status)
{
item.Selected = true;
}
}
and tries this too:
IEnumerable<SelectListItem> selectList =
from s in StatusList
select new SelectListItem
{
Selected = (s.Value == status),
Text = s.Text,
Value = s.Value
};
I dont know if these are the right way if someone know how to do this, please help.
Thanks in advance.
The Selected property of SelectListItem is ignored when binding to a model property. You need to set the value of your Status property in the GET method before you pass the model to the view
List<SelectListItem> Discountdata = new List<SelectListItem>
{
new SelectListItem() { Value = "All", Text = "All" },
new SelectListItem() { Value = "Draft", Text = "Draft" },
new SelectListItem() { Value = "Issued", Text = "Issued" },
....
};
StatusClass model = new CRM.StatusClass
{
StatusList = Discountdata,
Status = "Issued"
};
return View(model);
and the 2nd option in your <select> element will be selected.
Note that Discountdata is already IEnumerable<SelectListItem> and using new SelectList(Discountdata, "Value", "Text") to create an identical IEnumerable<SelectListItem> is unnecessary extra overhead.
Note also that since you have the same value for both the value attribute and display text, you could simply use
List<string> Discountdata = new List<string>{ "All", "Draft", "Issued", ... };
and in the model constructor
StatusList = new SelectList(Discountdata),
You're binding Status property to the dropdown. So set the value either from database, or in your case, a default value "Issued" like this:
statusObj.Status = "Issued"
I have a class called [SchoolingLevels], with this code:
public List<SelectListItem> schoolingLevels = new List<SelectListItem>();
public List<SelectListItem> Populate()
{
schoolingLevels.Add(new SelectListItem { Text = "Primary incomplete", Value = "Primary incomplete" });
schoolingLevels.Add(new SelectListItem { Text = "Primary", Value = "Primary" });
schoolingLevels.Add(new SelectListItem { Text = "Secondary incomplete", Value = "Secondary incomplete" });
schoolingLevels.Add(new SelectListItem { Text = "Secondary", Value = "Secondary" });
schoolingLevels.Add(new SelectListItem { Text = "Higher education incomplete", Value = "Higher education incomplete" });
schoolingLevels.Add(new SelectListItem { Text = "Higher education", Value = "Higher education" });
schoolingLevels.Add(new SelectListItem { Text = "Post-graduation/MBA", Value = "Post-graduation/MBA" });
return schoolingLevels;
}
And I want to populate my RadioButton based on this List..
In my controller:
ViewBag.Scholarity = new SchoolingLevels().Populate();
In my view:
#Html.RadioButton("Scholarity", "a")
It's not working.. (I tested with DropDown and works perfectly), isn't it possible to RadioButton?
EDIT
I tried it:
#foreach (var myValue in ViewBag.Scholarity)
{
Html.RadioButton("Scholarity","Value")
}
It seems work, but where can I put the NAME of the radiobuttons?
Ty.
I think the below code will help you:
#foreach (var myValue in ViewBag.Scholarity)
{
string text = myValue.Text.ToString();
string val = myValue.Value.ToString();
#Html.RadioButton("ScholarityList", val);
<span>#text</span>
}
or Create your custom HTML helper like below:
public static MvcHtmlString RadioButtonList(this HtmlHelper helper,
string NameOfList, List<string> RadioOptions) {
StringBuilder sb = new StringBuilder();
// put a similar foreach here
foreach(var myOption in RadioOptions) {
sb.Append(helper.RadioButton(NameOfList, myOption));
}
return new MvcHtmlString(sb.ToString());
}
#Html.RadioButtonList("ScholarityList", ViewBag.Scholarity);
Please follow the link to know more : http://www.codeproject.com/Tips/657164/Radio-Button-List-for-MVC
you can also iterate through your list and change the code below according to the data you have.
foreach (var item in Model)
{
#Html.RadioButtonFor(m => m.item, "Yes") #:Yes
#Html.RadioButtonFor(m => m.item, "No") #:No
}
I have two actions and i am passing data one to another. When i pass data second action to first action dropdown's selected value disappears. I googled many hours but i failed. Here is my codes:
First action which has selectlist and action codes.
First action:
List<SelectListItem> list= new List<SelectListItem>
{
new SelectListItem { Text = "--- Seçiniz----", Value = ""},
new SelectListItem { Text = "text1", Value = "11"},
new SelectListItem { Text = "text2", Value = "12"},
new SelectListItem {Text = "text3", Value = "13"},
new SelectListItem {Text = "text4", Value = "14"},
new SelectListItem { Text = "text5", Value = "15"}
};
if (TempData["daire"] != null)
{
int daire = Convert.ToInt32(TempData["daire"]);
ViewBag.daire = new SelectList(list, "Value", "Text", TempData["daire"]);
model= (folderBL.getAll().Where(k=>k.Id==daire)).ToList();
}
else
{
ViewBag.daire = new SelectList(list, "Value", "Text","");
model= folderBL.getAll();
}
Second action, I get the daire value for my SelectList and send data to first action.
public ActionResult SecondAction(string daire)
{
TempData["daire"] = daire;
return RedirectToAction("FirstAction");
}
And View.
#using (Html.BeginForm("SecondAction","MyDashboard",FormMethod.Post))
{
#Html.DropDownList("daire", (SelectList)ViewBag.daire, new { id = "mydrop" })
<td><input type="submit" value="Send" />
}
How can i keep selected ListItem when user clicks button and after page refreshes?
-----------------------------------------EDİT----------------------------------------------
Here is the solution if someone needs--> Just change the View.
#using (Html.BeginForm("SecondAction", "MyDashboard", FormMethod.Post))
{
#Html.DropDownList("daire")
<input type="submit" value="Send" />
}
If TempData has value in it then you can pass the int:
if (TempData["daire"] != null)
{
int daire = Convert.ToInt32(TempData["daire"]);
ViewBag.daire = new SelectList(list, "Value", "Text", daire);
and remember TempData is single read it will be removed after you read the value, if you want to persist it, call TempData.Keep("daire")
The problem was that ModelState was holding the dropdownlist's passed in value
Try this before redirect to first controller.Refere This
ModelState.Remove("Page");
I have the following code but it never selects the value I want.
List<SelectListItem> list = new List<SelectListItem>();
SelectListItem one = new SelectListItem() { Text = "MyTest", Value = "MyTest"};
SelectListItem two= new SelectListItem() { Text = "Test2", Value = "Test2" };
if (id == "MyTest")
{
one .Selected = true;
}
else
{
two.Selected = true;
}
list.Add(one);
list.Add(two);
ViewData["DDL"] = new SelectList(list, "value", "text");
So I am not sure what I am doing wrong
in my view I have
<%= Html.DropDownList("DDL") %>
You should use:
ViewData["DDL"] = new SelectList(list, "value", "text", id == "MyTest" ? "MyTest" : "Test2");
You should define selected value in SelectList constructor.
EDIT
Answer to question:
You don't have to provide List to SelectList constructor. It can be collection of any object. You just have to provide key, value propery and selected value. Your code could also look like:
var selectItems = new Dictionary<string, string> {{"MyTest", "MyTest"}, {"Test2", "Test2"}};
ViewData["DDL"] = new SelectList(selectItems, "Key", "Value", id == "MyTest" ? "MyTest" : "Test2");