Julian S
Julian S

Reputation: 215

Preselecting value of DropDownList doesn't work

Got a problem with preselecting the value for DropDownList. Basicaly I have a ViewModel class which encapsulates an isntance of class that I wan't to create later on and all possible values for the DropDownList to select from. Here is the code

Model classes:

public abstract class Entity
{ 
    public virtual int Id { get; set; }        
}

public class Project : Entity
{
    public virtual string Name { get; set; }

    public virtual string Comments { get; set; }

    public virtual IList<Activity> Activities { get; set; }
}

public class Activity : Entity
{
    public virtual string Comments { get; set; }

    public virtual Project Project { get; set; }
}

ViewModel:

public class ActivityViewModel
{
    public Activity Instance { get; set; }

    public IList<Project> AllProjects { get; set; }
}

View:

@model Desk.Mvc3.Models.ActivityViewModel

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Activity</legend>
        <p>
            <input type="submit" value="Create" />
        </p>

        <div class="editor-label">
            @Html.LabelFor(model => model.Instance.Comments)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Instance.Comments)
            @Html.ValidationMessageFor(model => model.Instance.Comments)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.AllProjects)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.Instance.Project, 
                new SelectList(Model.AllProjects, "Id", "Name", Model.Instance.Project.Id ))
            @Html.ValidationMessageFor(model => model.AllProjects)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

... and the Controller's Action:

public class ActivityController : PersistanceController
{
    // ...

    //
    // GET: /Activity/Create/2

    public ActionResult Create(int projectId)
    {
        var projects = GetRep<Project>().GetAll();
        var activity = new Activity();
        activity.Project = projects.SingleOrDefault(p => p.Id == projectId);

        var item = new ActivityViewModel { 
            Instance = activity,
            AllProjects = projects };

        return View(item);
    }   
}

Why when shown inside of a browser the DropDownList is populated with the default Project item rather than with preselcted one (i.e. one that has been assigned in the Action method)?

Upvotes: 1

Views: 3480

Answers (2)

Michael Johnson
Michael Johnson

Reputation: 226

The first parameter in "DropDownListFor" is for binding, and that is overriding your selected value. You are using the "Project" object, but you would have to use the project's "Id" instead.

@Html.DropDownListFor(model => model.Instance.Project.Id, 
        new SelectList(Model.AllProjects, "Id", "Name", Model.Instance.Project.Id ))

If you don't want this behavior then use the "DropDownList" helper.

Update (in response to your comment):

There is a way to make the following work.

@Html.DropDownListFor(model => model.Instance.Project, new SelectList(Model.AllProjects, "Id", "Name", Model.Instance.Project.Id ))            

You will need to override the "ToString()" function in the "Project" class to return the "Id".

public class Project : Entity  
{ 
    public virtual string Name { get; set; } 
    public virtual string Comments { get; set; } 
    public virtual IList<Activity> Activities { get; set; }

    public override string ToString()
    {
        return Id.ToString();
    }
}

Again another option would be to use the "DropDownList" helper.

@Html.DropDownList("Instance.Project", 
        new SelectList(Model.AllProjects, "Id", "Name", Model.Instance.Project.Id ))

This will produce the same html.

Upvotes: 3

Azargoth
Azargoth

Reputation: 395

I don't know what method of database asscess you're using, buy I think Model.Instance.Project may be null after leaving controller's part. Try pass selected value throgh ViewData (or ViewBag):

public ActionResult Create(int projectId)
{
    var projects = GetRep<Project>().GetAll();
    var activity = new Activity();

    var selProj = projects.SingleOrDefault(p => p.Id == projectId);

    ViewData[SelectedProjectID] = selProj != null ? selProj.ID : -1;

    var item = new ActivityViewModel { 
        Instance = activity,
        AllProjects = projects };

    return View(item);
} 

View:

   @Html.DropDownListFor(model => model.Instance.Project, 
        new SelectList(Model.AllProjects, "Id", "Name", (int)ViewData[SelectedProjectID] ))

Hope this will help.

Upvotes: 1

Related Questions