Reputation: 789
In my MVC application, I need to add a dropdown that would show a list of domain names.
I already have a ViewModel that contains multiple properties. I am not sure what the sequence of the steps should be:
ViewModel
? What should be the type? List?HTML.DropdownFor
?I know I should put some code in my Question, but right now I am having difficulty getting started with this...
EDIT: Added the following property to the ViewModel:
public IEnumerable<SelectListItem> DomainList { get; set; }
and implemented a method to return a list of Domains:
internal static List<Domain> FetchAllDomains()
Next in my controller action, I have:
var domains = FetchAllDomains().Select(d => d.DomainName);
return new EmailModel() {DomainList = domains };
But I get the following error:
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.IEnumerable'. An explicit conversion exists (are you missing a cast?)
Upvotes: 2
Views: 15848
Reputation: 1038810
1) Add a new property to my ViewModel? What should be the type? List?
You need 2 properties to be more precise: an IEnumerable<SelectListItem>
to hold all the available options and a scalar property to hold the selected value
2) Define a method that populates the above property with values.
Yes.
3) Use that property in the View? Use HTML.DropdownFor?
No, not in the view. The view doesn't call any methods. A view works with the view model. It is the responsibility of the controller to pass a properly filled view model to the view.
So for example:
public class MyViewModel
{
public string SelectedValue { get; set; }
public IEnumerable<SelectListItem> Values { get; set; }
... some other properties that your view might need
}
and then a controller action that will populate this view model:
public ActionResult Index()
{
var model = new MyViewModel();
model.Values = new[]
{
new SelectListItem { Value = "1", Text = "item 1" },
new SelectListItem { Value = "2", Text = "item 2" },
new SelectListItem { Value = "3", Text = "item 3" },
};
return View(model);
}
and finally the strongly typed view in which you will display the dropdown list:
@model MyViewModel
@Html.DropDownListFor(x => x.SelectedValue, Model.Values)
UPDATE:
According to your updated question you are have an IEnumerable<SelectListItem>
property on your view model to which you are trying to assign a value of type IEnumerable<string>
which obviously is impossible. You could convert this to an IEnumerable<SelectListItem>
like this:
var domains = FetchAllDomains().Select(d => new SelectListItem
{
Value = d.DomainName,
Text = d.DomainName
});
return new EmailModel { DomainList = domains };
Upvotes: 10
Reputation: 218732
You are in the right track, Have 2 properties in your ViewModel. One to hold the list of items and other for the selected Item Id from the UI
public class ProductViewModel
{
public IEnumerable<SelectListItem> Items { get; set; }
public string SelectedItemId { get; set; }
//Other Properties
}
And in your Get Action method, Return the ViewModel with the data
public ActionResult Index()
{
var objProduct = new ProductViewModel();
objProduct.Items = new[]
{
new SelectListItem { Value = "1", Text = "Domain 1" },
new SelectListItem { Value = "3", Text = "Domain 2" },
new SelectListItem { Value = "3", Text = "Domain 3" }
};
// can replace the above line with loading data from Data access layer.
return View(objProduct);
}
and in your view which is strongly typed to ProductViewModel
@model ProductViewModel
@using (Html.BeginForm())
{
@Html.DropDownListFor(x => x.SelectedItemId, new SelectList(Model.Items,"Value","Text"), "Select..")
<input type="submit" value="save" />
}
and in your HTTPpost Action, You will have the selected value available
[HttpPost]
public ActionResult Index(ProductViewModel model)
{
// check model.SElectedItemId here
}
Upvotes: 0
Reputation: 18237
DropDownList
@Html.DropDownListFor()
refers to an attribute of your model for guarantee that the view was stronglyTypedUpvotes: 0
Reputation: 4361
In your ViewModel
public class ViewModelClass
{
public string DomainName { get; set; }
public IEnumerable<SelectListItem> DomainList
{
get
{
return GetDomainNames() //your method to get domain names
.Select(d => new SelectListItem() { Text = d, Value = d });
}
}
}
your strongly typed view
@model ViewModelClass
@Html.DropDownListFor(model => model.DomainName, Model.DomainList)
Upvotes: 0
Reputation: 996
If you do not mind, I'll show you an example list of exams
public class SomeClass
{
//Properties
public int ExamId { get; set; }
public SelectList ExamList { get; set; }
}
Helper:
public static void PopulateExamList(MarkEditViewModel model,
List<Exam> examList)
{
model.ExamList = new SelectList(examList, "Id", "ExamName");
}
You must to add to marks, in my example, list of all exams. After this in View you will get a dropdown list of exams
And View (foreach every element in Model):
@Html.DropDownListFor(model => model.ExamId,
Model.ExamList,
"Choose exam")
Upvotes: 3
Reputation: 15557
Once you have the list on your controller pass it to the view (as model or using ViewBag) and then use the helper:
Html.DropDownList(
string name,
IEnumerable<SelectListItem> selectList,
string optionLabel,
object htmlAttributes)
Or (MVC 3)
@Html.DropDownListFor(model => model.Property.ID,
new SelectList(model.PropertyList, "ID", "Type"))
Upvotes: 1