Search code examples
asp.netasp.net-mvcasp.net-mvc-5radio-buttonhtml-helper

How i can group my @Html.RadioButtonFor according to the Item foreign key value


I have 2 models inside my asp.net mvc-5 web application:-

public partial class Anwer
    {
        public Anwer()
        {
            this.UserFormsAnswers = new HashSet<UserFormsAnswer>();
        }

        public int Id { get; set; }
        public string AnwerDesc { get; set; }
        public int QuestionID { get; set; }
        public bool Correct { get; set; }

        public virtual Question Question { get; set; }
        public virtual ICollection<UserFormsAnswer> UserFormsAnswers { get; set; }
    }

 public partial class Question
    {
        public Question()
        {
            this.Anwers = new HashSet<Anwer>();
        }

        public int Id { get; set; }
        public string QuestionDesc { get; set; }
        public int Order { get; set; }
        public bool Active { get; set; }

        public virtual ICollection<Anwer> Anwers { get; set; }
    }

now i want to show all the questions inside the view and for each question to show its answers in a radio buttons, so i tried the following:-

@model IEnumerable<QuestionsDemo.Models.Question>


@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">

        @{int i = 0;

            foreach (var item in Model)
{
                <div class="form-group">
                    @(i+1) <spn>-</spn> @Html.DisplayFor(modelItem => item.QuestionDesc) <br />
                    @foreach (var answer in item.Anwers)
        {
                        <div class="col-md-10">
                            @Html.RadioButtonFor(modelitem2 => answer.QuestionID, answer.Id) @answer.AnwerDesc  <br /> 
                        </div>
        }
                </div><hr/>
}

        }
    </div>
}

I thought that all the answers' radio buttons for a question will have the same name. so users can only select one option for each question. but seems all the answers radio-buttons got the same name as follow:-

<input id="answer_QuestionID" name="answer.QuestionID" type="radio" value="1" /> 10  <br />

so can any one adivce on this ? how i can group the radio buttons per question?

second question. how i can post back all the answers ids to my post action method? should i use indexer ??


Solution

  • You cannot use a foreach loop to generate the form controls for Question. You need to use a for loop, or better a custom EditorTemplate for typeof Question. Refer Post an HTML Table to ADO.NET DataTable for a detailed explanation.

    Your Question model also needs a property to bind the selected Answer to, for example

    public class Question
    {
        public int Id { get; set; }
        ....
        public int SelectedAnswer { get; set; }
    }
    

    And note that your editing data so you should be creating view models for both Question and Answer, not using data models in your view.

    Create a partial view Views/Shared/EditorTemplates/QuestionVM.cshtml with the following code

    @model QuestionsDemo.Models.Question
    
    @Html.HiddenFor(m => m.Id)
    // Add additional hidden inputs for any properties of Question that you want to be posted
    @Html.DisplayFor(m => m.QuestionDesc)
    @foreach(var answer in Model.Anwers)
    {
        <label>
            @Html.RadioButtonFor(m => m.SelectedAnswer, answer.Id, new { id = "" })
            <span>@answer.AnwerDesc</span>
        </label>
    }
    

    Then the main view will be

    @model IEnumerable<QuestionsDemo.Models.Question>
    ....
    @using (Html.BeginForm())
    {
        ....
        @Html.EditorFor(m => m)
        <input type="submit" value="Save" />
    }
    

    Note the EditorFor() method will correctly generate the html for each item in the collection.