Search code examples
c#asp.netasp.net-mvcasp.net-mvc-4razorengine

Multiple DropDownList in an IEnumerable Model


I'm developing a mini-survey with ASP.NET MVC. I created my models Question, QuestionCategory, Response, ResponseCategory and populated them with seed data.

The Index View of the Question Model is working pretty well but I need to add an extra field which will contain a drop-down list for each questions where users can be able to answer the question with the option selected with the drop down list.

Below is my Question Model

public class Question
{
    [Key]
    public byte Id { get; set; }
    [Required]
    [Display(Name = "Survey Question")]
    public string SurveyQuestion { get; set; }
    public QuestionCategory QuestionCategory { get; set; }
    [Display(Name = "Question Category")]
    public byte QuestionCategoryId { get; set; }             
}

And here is my QuestionCategory Model

public class QuestionCategory
{
    public byte Id { get; set; }
    public string QuestionCat { get; set; }
}

Here is the Response Model

public class Response
{
    public byte Id { get; set; }
    public string ResponseName { get; set; }
    public byte Weight { get; set; }
    public ResponseCategory ResponseCategory { get; set; }
    public byte ResponseCategoryId { get; set; }
}

And here is the ResponseCategory Model

public class ResponseCategory
{
    public byte Id { get; set; }
    public string ResponseCat { get; set; }
}

Below is the Index Action of the QuestionController.

    public ActionResult Index()
    {
        var questions = _context.Question.Include(q => q.QuestionCategory).ToList();
        return View(questions);
    }

And finally below is the view which displays the questions with the

@model IEnumerable<WorkPlaceBullying.Models.Question>
@{
    ViewBag.Title = "Survey Questions";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Questions</h2>
@if (!Model.Any())
{
    <p>We don't have any Questions yet!.</p>
}

@Html.ActionLink("Question", "New", "Question", "", new { @class = "btn btn-primary" })

<table class="table table-striped table-hover ">
    <thead>
        <tr>
            <td>ID</td>
            <td>Questions</td>
            <td>Response Category</td>
        </tr>
    </thead>
    @foreach (var question in Model)
    {
        <tr>
            <td>@question.Id</td>
            <td>
                @Html.ActionLink(@question.SurveyQuestion, "Edit", "Question", new { id = @question.Id }, null)
            </td>
            <td>
                @question.QuestionCategory.QuestionCat
            </td>
            <td>               
                @*@Html.DropDownListFor(q => q.Question.QuestionCategoryId, new SelectList(Model.QuestionCategory, "Id", "QuestionCat"), "Select Question Category", new { @class = "form-control" })*@
            </td>
        </tr>
    }
</table>

I can't seem to fit in the dropdownlist for the responses in the Index view of the Question Controller. All help will be deeply appreciated.


Solution

  • The SelectList Constructor takes an IEnumerable, not a class.

    Create a List of Model.QuestionCategory's in your model and create a SelectList from that.

    public static IEnumerable<QuestionCategory> QuestionCategoryList = new List<QuestionCategory> { 
        new QuestionCategory {
            Id = 1,
            QuestionCat = "Red"
        },
        new QuestionCategory {
            Id = 2,
            QuestionCat = "Blue"
        }
    };
    

    Change the code in the View to:

    @Html.Hidden(@question.Id + "_QuestionCategoryId", @question.QuestionCategoryId)
    @Html.DropDownList(@question.Id + "_QuestionCategoryId", new SelectList(QuestionCategoryList, "Id", "QuestionCat"), "Select Question Category", new { @class = "form-control", onchange="setQuestionCategoryId(this)" })
    

    You will probably need some javascript to update a hidden input when the OnChange event fires.

    See this jsfiddle for how to update QuestionCategoryId value with javascript.

    function setQuestionCategoryId(selectObject) 
    {   
       $("input#" + selectObject.id).val(selectObject.value);
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <input id="1_QuestionCategoryId" name="1_QuestionCategoryId" value="0" />
                
    <select class="form-control" id="1_QuestionCategoryId" name="1_QuestionCategoryId" onchange="setQuestionCategoryId(this)">
        <option>Select Question Category</option> 
        <option value="1">Red</option> 
        <option value="2">Blue</option> 
    </select>