1
votes

I create a @Html.DropDownListFor and populate it from the database. How can I set a selected value to the drop down?

My View:

@Html.DropDownListFor(m => m.Forms, new SelectList(Model.Forms, "FormsCreatorID", "FormName"),
            "Select a Form", new { @class = "form-control" })

My Controller:

var forms = db.formscreators.Where(fp => fp.PropertyID == id || fp.PropertyID == 0)
            .OrderByDescending(x => x.PropertyID).GroupBy(x => x.FormName).Select(x => x.FirstOrDefault()).ToList();
var viewModel = new ListFormsCreator { Forms = forms };

My ViewModel:

public class ListFormsCreator
{
    public List<formscreator> Forms { get; set; }
}

My Database Model:

public partial class formscreator
{
    public int FormsCreatorID { get; set; }
    public string FormName { get; set; }
    public int PropertyID { get; set; }
}

Thanks

4

4 Answers

2
votes

You should add another property to your view model for the store/pass the selected option.

public class ListFormsCreator
{
    public int SelectedFormId  { set;get;}
    public List<formscreator> Forms { get; set; }
}

Now in your GET action, you can set that value

var viewModel = new ListFormsCreator() { Forms = forms };
viewModel.SelectedFormId  = 2 ; // This will select the option with 2 as FormsCreatorID
return View(viewModel);

And in the view use the lambda expression with that property as the first parameter of the DropDownListFor helper method.

@model ListFormsCreator

@Html.DropDownListFor(m => m.SelectedFormId  , 
                         new SelectList(Model.Forms, "FormsCreatorID", "FormName"),
                        "Select a Form", new { @class = "form-control" })

The DropDownListFor helper method will use the value of SelectedFormId property and select the option which has the same value attribute value from the list of options of that SELECT element.

You can also remove the dependency on formscreator class from the view model, by replacing it with a list of SelectListItem

public class ListFormsCreator
{
    public int SelectedFormId  { set;get;}
    public List<SelectListItem> Forms { get; set; }
}

Now in your GET action, you can use the Select method to generate the lsit of SelectListItem from your other collection.

var viewModel = new ListFormsCreator();
viewModel.Forms = someCollection.Select(a=>new SelectListItem { 
                                           Value=a.FormsCreatorId.ToString(), 
                                           Text=a.FormName})
                 .ToList();
viewModel.SelectedFormId  = 2 ; // This will select the option with 2 as FormsCreatorID
return View(viewModel);

Assuming someCollection is a collection of formscreator objects Now in the view code is much simpler

@Html.DropDownListFor(m => m.SelectedFormId, Model.Forms ,"Select a Form")
1
votes
  1. Conform with C#/.NET naming conventions:
    1. Rename formscreator to FormsCreator
    2. Replace ID with Id (as it's an abbreviation, not an initialism)
    3. Rename ListFormsCreator to something like ListFormsCreatorViewModel so it's obvious it's a ViewModel type and not a Model/Entity type.
  2. Modify your ViewModel to add a property to store the selected FormsCreatorId value:

    public class ListFormsCreatorViewModel
    {
        [Required] // add or remove the 'Required' attribute as necessary
        public int? SelectedFormsCreatorId { get; set; }
    
        ...
    }
    
  3. Set the SelectedFormsCreatorId property value in your controller action if necessary if you know what the value should be.

  4. In your POST handler, ensure the SelectedFormsCreatorId value is maintained, either by directly passing-through the model action parameter back through the View(Object viewModel) method or manually repopulating it.

  5. The view-model property in DropDownListFor should be the SelectedFormsCreatorId property. You do not need new SelectList(...)

    @Html.DropDownListFor( m => m.SelectedFormsCreatorId, this.Model.Forms );
    
1
votes

Update your viewModel and add an Int SelectId for the dropdown selected value.

In your controller:

var viewModel = new ListFormsCreator { SelectId = PropertyId, Forms = FormSelectList(forms, PropertyId.ToString()) };

I would create a function passing in a list:

    public static SelectList FormSelectList(IEnumerable<formscreators> types, string selected = null)
    {
        return new SelectList(from f in forms
                              select new SelectListItem
                              {
                                  Text = f.FormName,
                                  Value = f.FormsCreatorID.ToString()
                              }, "Value", "Text", selected);

    }

And in your .cshtml

@Html.DropDownListFor(m => m.PropertyId, Model.forms, "Select a Form", new { @class = "form-control", required = "required" })
1
votes

You should generate a 'SelectListItem' list on the controller with setting 'Selected' value and pass it via ViewBag or ViewModel. In my sample, for simplicity, I used ViewBag. Here is the shortened Controller:

public ActionResult Edit(int? id)
{
    if (id == null)
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

    Album album = context.Albums.Find(id);

    if (album == null)
    {
        return HttpNotFound();
    }

    ViewBag.GenreId = context.Genres.Select(
        g => new SelectListItem()
        {
            Value = g.GenreId.ToString(),
            Text = g.Name,
            Selected = g.GenreId == album.GenreId ? true : false
        }).ToList();

    return View(album);
}

Here is the shortened View Code

@using MvcMusicStore2017.Models;
@model Album
@Html.DropDownList("GenreId", null, new { @class = "form-control" })