public class DropDown
{
public string[] SelectedItems { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
Am trying to get a DropDown in MVC from DB with above structure.
From DataBase I got the Text and value field and having in IEnumerable<T> where T has 2 properties id and text.
What is the best way convert ienumerable id to array of string and assign id, text to SelectedListItem ?
I thought of looping through the ienumerable and forming the DropDown, but thought there will be better ways.
update
For example :
In DB i have student table with
ID,
Name,
Class,
Section
And i got id and Name in ienumerable<student> . From there i need to convert into a DropDown
IEnumerable<Student> studentList = GetStudentList();
IEnumerable<SelectListItem> dropdownItems = new MultiSelectList(studentList, "ID", "Name",selectedValues);
DropDown dropDown = new DropDown { Items = dropdownItems };
If you want to create a listbox you can do it with HTML helpers like this:
#Html.ListBoxFor(item => item.SelectedStudents, new MultiSelectList(Model.StudentList, "ID", "Name",selectedValues))
I'm unsure why you are trying to create your own DropDown class, why not use the built-in MVC HTML Helper?
If you have an IEnumerable that you want to turn into a SelectList which will be consumed by the helper, something like this would work:
var selectListItems = from t in items
select new SelectListItem{
Text = t.Text,
Value = t.Id
}.ToList();
Then fire it over to your view, you could ideally use a viewmodel, but the ViewBag works too:
ViewBag.SelectListItems = selectListItems;
Finally, have your HTML Helper build your drop down for you in your view:
#Html.DropDownList("SelectListItems")
It looks like maybe you want multiple dropdowns for every array position in selectedItems? If so, I just had this problem last week. I called a foreach inside Html.DropDownListFor(...).
<% for(int i = 0; i < Model.SelectedItems.length; i++) %>
<%: Html.DropDownListFor(m => m.SelectedItems[i], Model.Items %>
Related
I'm trying to work out a best practice for building drop down boxes for values that need to bind to values in a database.
Currently I am about to use the 3rd answer from this list How do you create a dropdownlist from an enum in ASP.NET MVC?
But then I was thinking if I bind strongly against the Enum, and then want to change the order of the items, or add new items, I'll need to make sure the order of the enum isn't actually the value being stored in the db, and have to have a binding layer of some kind.
Does anyone have the definitive way to work with drop down lists that relate to a db?
Personally I avoid using enums in my view models. They don't play well with ASP.NET MVC. So if I need to render a dropdown list in one of my views I define 2 properties on my corresponding view model:
public class MyViewModel
{
public string SelectedValue { get; set; }
public IEnumerable<SelectListItem> Values { get; set; }
}
that are populated in my controller action from the database and in the view:
#Html.DropDownListFor(x => x.SelectedValue, Model.Values)
Have a strongly typed view model for the list with a partial view to match. Have an action in a controller which fills the view model and then returns it to the view. Wherever you want to use the dropdown, insert the partial view in your view.
I'm a fan of using an extension method for this task:
public static List<SelectListItem> ToSelectList<T>( this IEnumerable<T> enumerable, Func<T, string> value, Func<T, string> text, string defaultOption)
{
var items = enumerable.Select(f => new SelectListItem()
{
Text = text(f) ,
Value = value(f)
}).ToList();
if (!string.IsNullOrEmpty(defaultOption))
{
items.Insert(0, new SelectListItem()
{
Text = defaultOption,
Value = "-1"
});
}
return items;
}
Within your controller you select the data that you wan't to represent as items within a drop down. Note, in this example I'm selecting cities from the db:
SomeModel.City =
(from l in _locationRepository.GetAll() select new { l.Area.AreaDescription })
.Distinct()
.ToSelectList(x => x.AreaDescription, x => x.AreaDescription, "All");
And the actual drop down within the view:
#Html.DropDownList("City", Model.City)
First of All Sorry to post the same question thought there are lot of posts already available. I tried all possible ways and finally I dint have any other option other than posting the same question.
I wanted to bind a enum to a DROPDOWNLISTFOR, but the text in a friendly manner. so In the controller I am binding the selectlist like
List<SelectListItem> formTypeSelectList = new List<SelectListItem>();
foreach (FormType type in ItemHelper.EnumToList<FormType>())
{
SelectListItem formTypeList = new SelectListItem();
formTypeList.Text = ItemHelper.GetEnumDescription(type);
formTypeList.Value = Convert.ToString((int)type);
formTypeList.Value = Convert.ToString((int)type);
formTypeSelectList.Add(formTypeList);
}
item.FormTypeSelectListItem = formTypeSelectList;`
My Entity has
public FormType FormType { get; set; }
public List<SelectListItem> FormTypeSelectListItem { get; set; }
public SelectList FinalSelectList
{
get
{
return new SelectList(FormTypeSelectListItem, "Value", "Text", (int)FormType);
}
}
My view has
<%= Html.DropDownListFor(x => x.Item.FormType, Model.Item.FinalSelectList, new { id = "ddlFormType" })%>
I even tried few other option for binding views like
<%= Html.DropDownListFor(x => x.Item.FormType, new SelectListItem(Model.Item.FinalSelectList,"Value","Text",(int)Model.Item.formType)) %>
Nothing works, When I changed to HTML.DropdownList with a name specified it worked perfectly, but i wanted to bind with dropdownlistfor only.
I even tried adding different id, different name in view like
new{id="ddlformType",name="ddlformtype")
nothing worked. Can some one help me to fix this?
Thanks,
Akila
DropDownListFor is looking for an IEnumerable<SelectListItem> for it's items. Try just passing your FormTypeSelectListItem to the DropDownListFor method in place of your FinalSelectList. You may have to cast the model property as an IEnumerable<SelectListItem>
I am developing an ASP.Net MVC 3 Web application and believe my method of returning a list of items to a drop down list in the View is a bit long winded. Let me explain.
I have a ViewModel which contains an Equipment Entity and a SelectList to display a list of Categories.
public class AddEquipmentViewModel
{
public Equipment equipment { get; set; }
public SelectList categoryList { get; set; }
}
In the GET create method of my Equipment Controller, I return my ViewModel to the view, see below:
//Add new select list item named 'Please select option' to the top of list
var categoryList = categoryService.GetAllCategories();
var categorySelectListItems = categoryList.Select(c => new SelectListItem { Value = c.categoryID.ToString(), Text = c.categoryTitle }).ToList();
categorySelectListItems.Insert(0, new SelectListItem { Text = "Please select option", Value = string.Empty });
AddEquipmentViewModel viewModel = new AddEquipmentViewModel
{
equipment = new Equipment(),
categoryList = new SelectList(categorySelectListItems.ToList(), "Value", "Text")
};
I know I could discard the extra code before I create an instance of my ViewModel and just assign my Category List to the relevant ViewModel property like so
categoryList = new SelectList(categoryService.GetAllCategories(), "categoryID", "categoryTitle")
However, this then just returns a list of categories to my drop down list in my View, whereas, I would like to add a new SelectListItem, ie, "Please select option".
I just feel that my approach to manually adding a new SelectListItem to my SelectList is a bit cumbersome and I would greatly appreciate if someone could share a better method?
Thanks for your time.
<%= Html.DropDownList("name", new SelectList(...), "Your Combobox default message")%>
Hope it helps
Learning about dropdown lists, Im trying to add a RSVP create page for nerddinner as in Scott Gu's blog with a Html.DropDownListFor listing available dinners.
I can get the dropdown list populated but I cannot get the dropdown to pre select the value ("Sample Dinner 2") I want. Im using an initilizer to seed a few dinner objects in the db. The database is sql ce 4 using a EF 'code first approach'. Sorry I know this is a v common problem and hate to ask, but honestly have spent quite some time on this but cant get it to work:
ViewModel
public class RSVPViewModel
{
public SelectList DinnersList { get; set; }
public RSVP Rsvp { get; set; }
public string SelectedItem { get; set; }
}
Controller
//
//GET: /RSVP/Create
public ActionResult Create()
{
RSVP rsvp = new RSVP();
string selected = "Sample Dinner 2";
var typeList = new SelectList(dbc.Dinners.ToList(), "DinnerID", "Title", selected);
var viewModel = new RSVPViewModel { DinnersList = typeList, Rsvp = rsvp, SelectedItem = selected };
return View("Create", viewModel);
}
View
#Html.DropDownListFor(model => model.Rsvp.DinnerID, Model.DinnersList)
HTML Result
<select data-val="true" data-val-number="The field DinnerID must be a number." data-val-required="The DinnerID field is required." id="Rsvp_DinnerID" name="Rsvp.DinnerID">
<option value="1">Sample Dinner 1</option>
<option value="2">Sample Dinner 2</option>
</select>
So is not preselecting the dropdownlist with the value "Sample Dinner 2" when the page loads. The list displays ok and sets the correct DinnerID when I make a selection and click Submit.
Tries this also:
#Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)
but doesnt set or bind to Rsvp.DinnerID.
This preselects from the list but doesnt bind (or set Rsvp.DinnerID)
#Html.DropDownList("DinnersList")
I want to keep it mvc3 so want to implement with strong type using ViewModel approach (no ViewData) and preferably using Html.DropDownListFor (not Html.DropDownList).Viewbag seems unnecessary for this case.
Thanks!
Edit1
Thinking I should be using a selectList of selectListItems I tried this verbose approach :
RSVP rsvp = new RSVP();
string selected = "2";
List<SelectListItem> dinners = new List<SelectListItem>();
foreach (Dinner dinner in dbc.Dinners.ToList())
{
SelectListItem slDinner = new SelectListItem();
slDinner.Value = dinner.DinnerID.ToString();
slDinner.Text = dinner.Title;
slDinner.Selected = (slDinner.Value == selected);
dinners.Add(slDinner);
}
var dinnersList = new SelectList(dinners, "Value", "Text", selected);
var viewModel = new RSVPViewModel { DinnersList = dinnersList, Rsvp = rsvp, SelectedItem = selected };
However still no work. Should I be making use of the ViewModel SelectedItem property in: #Html.DropDownListFor.. somehow? Something like :
#Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)
but how to I get a selected value to set Rsvp.DinnerID. I think thats called binding.
After reading here and here, I finally understand how HtmlDropDownlistFor automatically selects the correct item in the dropdown based on your model - selecting a dinnerID in RSVP (foreign key to dinner.dinnerID) will cause the dropdown containing list of Dinner.DinnerIDs to pre select that value. No need yet I think for selectedValue in the SelectList or ViewModel.
Solution:
//
//GET: /RSVP/Create
public ActionResult Create()
{
//automatically preselects matching DinnerID in the Dinner dropdownlist
var rsvp = new RSVP {DinnerID = 2 };
var typeList = new SelectList(dbc.Dinners.ToList(), "DinnerID", "Title");
var viewModel = new RSVPViewModel { DinnersList = typeList, Rsvp = rsvp};
return View("Create", viewModel);
}
The SelectList constructor you're using is supposed to provide the selected value, but you are providing the selected text. You may want to try:
int selected = 2;
Html.DropDownList only works if the bound property is an int. Any other type, such as a named enum, will cause it to default to the first item.
Add a property to your Model, type int, which wraps the enum you are trying to maintain:
public myEnumType myProperty {get; set;} // don't bind this to Html.DropDownList
public myEnumType myPropertyAsInt {
get {return (int)this.myProperty; }
set {this.myProperty = (myEnumType)value; }
} // bind this instead
No need to use Selected in your SelectList - Html.DropDownList will synchronise just fine.
Please take care if there is a QUERY STRING with same name , it will override that behavior, Not sure about HIDDEN FIELDS with same name.
E.g.
DropDownListFor will use the value of Query String of DinnerID if
found
Html.DropDownList accepts int properties, DropDownListFor too, but you have to be careful what you are doing. I examined the SelectExtensions.cs from ASP.NET MVC 3 and found this:
When you use DropDownList("XyField", "default") to create a DropDown, then you must place the select list into ViewBag.XyField and DropDownList() handles this correctly.
When you use DropDownListFor(m=>m.XyField, ... ), you can pass the select list explictly, like this:
DropDownListFor(m=>m.XyField, ViewBag.XyFieldList as IEnumerable)
When you do this, this following happen:
The second parameter of DropDownListFor(...) will be used as source for the options
If there is a ModelState entry for "XyField", this will be used as the model value
If there is no model state AND Html.ViewData.Eval("XyField") returns not null, this value will be used as the model value.
If the found model value is not null, it will be converted to a string, using CultureInfo.CurrentCulture, and this value is compared with your SelectListItem values to preselect the list options.
Attention here: if you stored your select list in ViewBag.XyField, it will be found before the model is accessed. The don't want to compare "selectList.ToString()" with "selectList[i].Value" to preselect your options. Store your selection list in another place!
The funny thing is, you CAN use DropDownListFor with an implicit select list, in the same way as you expect it from DropDownList(). In this case, you will even store your list in ViewBag.XyField. To make this work, you simply have to call the helper with null as second parameter:
DropDownListFor(m=>m.XyField, null)
Then, the select list is pulled from ViewBag.XyField and step 3 in the list above is skipped. So, if XyField is in the model state, this will take precedence before your own Selected properties in the select list, but otherwise, the select list will be used "as is".
Greetings
Rolf
i want to display selected value in drop down list . the value comes from the data base. for ex suppose we want to update user profile then value for gender which is previously provided by the user should get displayed as selected value. the code that i used to display is
<% string val = Convert.ToString(Model.gender);
ViewData["gen"] = val;
%>
<%= Html.DropDownList("genderList", ViewData["gen"] as SelectList) %>
but its not showing the value from the database.but viewdata get value from database but it is not showing on drop down list.
thanks in advance.
You can check this blog post which shows how to use a DropDownList in ASP.NET MVC.
This:
string val = Convert.ToString(Model.gender);
ViewData["gen"] = val;
is not compatible with this:
ViewData["gen"] as SelectList
ViewData["gen"] contains a string value instead of SelectList and when you try to cast it you get null and the drop down contains no values.
You will need an array in order to populate the drop down list. The first step is to have a strongly typed array of some object. Suppose that you have the following class defined:
public class Gender
{
public int Id { get; set; }
public int Text { get; set; }
}
In your controller action:
public ActionResult Index()
{
var genderList = new[]
{
new Gender{ Id = 1, Text = "Male" },
new Gender{ Id = 2, Text = "Female" },
}; // This should come from the database
ViewData["genderList"] = new SelectList(genderList, "Id", "Text");
return View();
}
and in the view:
<%= Html.DropDownList("gen", ViewData["genderList"] as SelectList) %>