Reputation: 2063
Drop down lists in ASP.NET MVC confuse me. I have a model class. The model class has a string called SelectedValue. This string represents that previously selected value. I have a collection of items I've pulled from the database. Each item of the collection has an ID and a Name value. My problem is, I don't know what the recommended way of getting this information into the UI is.
I'm not sure if I should use the ViewBag or the Model. Once the value is there though, I'm not even sure what the best way to populate the UI is. I've seen HTML helpers and people using RAZOR syntax. I'm very confused. What do people recommend?
Thank you
Upvotes: 9
Views: 41893
Reputation: 1
In addition to the methods above, you can also use this approach in order to use multi Foreign Key in a Lookup table. It is very clear and effective as far as I have seen.
Upvotes: 0
Reputation: 197
If you are using VB.Net - MVC4- Razor This answer is almost same as Frigik( Thanks Frigik)
In your model create two fields one is the field which will hold the SelectedItem(here it is TagType of string) and the second is the drop down values (TagTypeList)
Imports System.Web.Mvc
Private _tagType As String
Private _tagTypeList As List(Of SelectListItem)
Public Property TagType() As String
Get
Return _tagType
End Get
Set(ByVal value As String)
_tagType = value
End Set
End Property
Public Property TagTypeList() As List(Of SelectListItem)
Get
Return _tagTypeList
End Get
Set(value As List(Of SelectListItem))
_tagTypeList = value
End Set
End Property
'In the constructor
Sub New()
TagTypeList = CommonUtility.LoadDropDownByName("TAGTYPE")
End Sub
Imports System.Web.Mvc
Imports System.Collections.Generic
Public Shared Function LoadDropDownByName(ByVal DropDownName As String) As List(Of SelectListItem)
Dim dt As DataTable
Dim ds As DataSet
Dim results As List(Of SelectListItem) = Nothing
Try
ds = objSignOn.LoadDropDown(DropDownName) 'Pass the dropdown name here and get the values from DB table which is - select ddlId, ddlDesc from <table name>
If Not ds Is Nothing Then
dt = ds.Tables(0)
If (dt.Rows.Count > 0) Then
results = (From p In dt Select New SelectListItem With {.Text = p.Item("ddlDesc").ToString(), .Value = p.Item("ddlId").ToString()}).ToList()
End If
End If
Catch ex As Exception
End Try
Return results
End Function
@Html.DropDownListFor(Function(x) x.TagType, Model.TagTypeList, "", New With {.id = "ddlTagType",.class = "dropDown", .style = "width: 140px"})
Here the 3rd parameter(optional) as empty which will insert the 1st item as empty in the drop down. The 1st parameter is the selectedItem which helps to populate once the value is already present in DB table.
Hope this helps who are using VB.Net
Upvotes: 0
Reputation: 3774
This is how i do it, lets say you have 2 models Team and Player
:
Player.cs
public class Player
{
[HiddenInput(DisplayValue = false)]
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[ForeignKey("Team")]
[Display(Name = "Team")]
public int TeamId { get; set; }
[Display(Name = "First name")]
public string FirstName { get; set; }
[Display(Name = "Last name")]
public string LastName { get; set; }
public virtual Team Team { get; set; }
}
Team.cs
public class Team
{
[Key]
[HiddenInput(DisplayValue = false)]
public int TeamId { get; set; }
[Display(Name = "Full Name:")]
public string Name { get; set; }
public virtual ICollection<Player> Players { get; set; }
}
Then in your PlayerController: Note: team need to exist to create a player
private void PopulateTeamsDropDownList(object selectedTeams = null)
{
var teamsQuery = from d in _dataSource.Teams
orderby d.Name
select d;
ViewBag.TeamID = new SelectList(teamsQuery, "TeamId", "Name", selectedTeams);
}
[HttpGet]
public ActionResult Create()
{
PopulateTeamsDropDownList();
return View();
}
[HttpPost]
public ActionResult Create(Player model)
{
if (ModelState.IsValid)
{
using (EFootballDb db = new EFootballDb())
{
try
{
var player = new Player
{
FirstName = model.FirstName,
LastName = model.LastName
};
db.Players.Add(player);
db.SaveChanges();
return RedirectToAction("About", "Home");
}
catch (Exception)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}
}
PopulateTeamsDropDownList(model.TeamId);
return View(model);
}
And lastly your Create View for Player would look like this:
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Player</legend>
<div class="editor-label">
@Html.LabelFor(model => model.TeamId, "Pick Your Team")
</div>
<div class="editor-field">
@Html.DropDownList("TeamId", String.Empty)
@Html.ValidationMessageFor(model => model.TeamId)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.FirstName)
@Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.LastName)
@Html.ValidationMessageFor(model => model.LastName)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Upvotes: 10
Reputation: 7539
The way I do it is making the dropdown a part of my ViewModel .... say it is Products.... so in my ViewModel I have a
public SelectList Products { get; set;}
public int ProductId { get; set; } // For the the selected Product
So when the View loads, and I am populating the model to return to the view in the controller, I do something like this:
model.Products = new SelectList(MyEnumerableofProducts, "ValueField", "TextField", {value of the selected item in the dropdown, as a string)
In my view, I would have:
@Html.DropDownListFor(model => model.ProductId, Model.Products, "Please Select")
return View(model)
Upvotes: 8