Spitfire5793 Spitfire5793 - 1 month ago 7
ASP.NET (C#) Question

Only last radio button control in list being set as checked

I have a list with each element of the list containing a star rating control which allows the user to set their preference for that element. The rating control is basically just 5 radio buttons. The problem I am having is that when I retrieve the preferences the user has previously made, only the last preference is shown, the radio buttons for all elements before that are unchecked.

This is how it looks, showing 4 stars for the last element, however it should also show one for the first and three stars for the second:

enter image description here

This is the code for the view:

@foreach (var item in Model.TaskEntities)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Code)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.AspNetUser.Forename)
@Html.DisplayFor(modelItem => item.AspNetUser.Surname)
</td>
<td>
@Html.DisplayFor(modelItem => item.AspNetUser.Email)
</td>
<td>
@{
var list = new TaskEntityAndPreferencesModel(item, Model.Preferences);
}
@Html.Partial("_Rating", list)
</td>
<td>
@*@Html.ActionLink("Edit", "Edit", new { id = item.CourseID }) |
@Html.ActionLink("Details", "Details", new { id = item.CourseID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.CourseID })*@
</td>
</tr>
<tr>

<td colspan="5">
@Html.DisplayFor(modelItem => item.Description)
</td>
</tr>
}


This is the code for the rating control (_Rating):

@using Microsoft.AspNet.Identity
@model AssignerWebTool.Models.TaskEntityAndPreferencesModel

@{
var checkedOne = false;
var checkedTwo = false;
var checkedThree = false;
var checkedFour = false;
var checkedFive = false;


foreach (var preference in Model.Preferences)
{
if (preference.UserID == User.Identity.GetUserId() && preference.TaskEntityID == Model.Task.ID)
{
if (preference.Rating == 1)
{
checkedOne = true;
}
else if (preference.Rating == 2)
{
checkedTwo = true;
}
else if (preference.Rating == 3)
{
checkedThree = true;
}
else if (preference.Rating == 4)
{
checkedFour = true;
}
else if (preference.Rating == 5)
{
checkedFive = true;
}
}
}
}
<div class="ratting-item" data-pid="@Model.Task.ID">
@{
if (checkedOne)
{
<input class="rating" name="vote" type="radio" checked="checked" value="1"/>
}
else
{
<input class="rating" name="vote" type="radio" value="1" />
}
if (checkedTwo)
{
<input class="rating" name="vote" type="radio" checked="checked" value="2" />
}
else
{
<input class="rating" name="vote" type="radio" value="2" />
}
if (checkedThree)
{
<input class="rating" name="vote" type="radio" checked="checked" value="3" />
}
else
{
<input class="rating" name="vote" type="radio" value="3" />
}
if (checkedFour)
{
<input class="rating" name="vote" type="radio" checked="checked" value="4" />
}
else
{
<input class="rating" name="vote" type="radio" value="4" />
}
if (checkedFive)
{
<input class="rating" name="vote" type="radio" checked="checked" value="5" />
}
else
{
<input class="rating" name="vote" type="radio" value="5" />
}
}

</div>
<span class="result"></span>


Im not sure why this is only working for the last element and not any previous, so any help would be much appreciated.

Edit:

Models:

public class TaskEntityAndPreferencesModel
{

public TaskEntity Task { get; set; }
public IEnumerable<UserTaskEntityPreference> Preferences { get; set; }

public TaskEntityAndPreferencesModel(TaskEntity task, IEnumerable<UserTaskEntityPreference> preferences)
{
Task = task;
Preferences = preferences;
}
}


public partial class TaskEntity
{
public TaskEntity()
{
this.UserAssignedToTaskEntities = new HashSet<UserAssignedToTaskEntity>();
this.UsersUserPreferences = new HashSet<UsersUserPreference>();
this.UserTaskEntityPreferences = new HashSet<UserTaskEntityPreference>();
}

public int ID { get; set; }
public string Name { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public string RelatedSubjects { get; set; }
public int MaxNumberOfUsers { get; set; }
public int TaskGroupID { get; set; }
public string SupervisorID { get; set; }

public virtual Task_Group Task_Group { get; set; }
public virtual ICollection<UserAssignedToTaskEntity> UserAssignedToTaskEntities { get; set; }
public virtual ICollection<UsersUserPreference> UsersUserPreferences { get; set; }
public virtual ICollection<UserTaskEntityPreference> UserTaskEntityPreferences { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
}


public partial class UserTaskEntityPreference
{
public string UserID { get; set; }
public int TaskEntityID { get; set; }
public int Rating { get; set; }
public int ID { get; set; }

public virtual AspNetUser AspNetUser { get; set; }
public virtual TaskEntity TaskEntity { get; set; }
}

Answer

The reason that only the last radio button is selected is because all your radio buttons have the same name (group) and you can only select one radio button from a group.

In the 1st iteration of your loop, the radio button withvalue="1" is selected for that Preference. In the 2nd iteration, the radio button withvalue="3" is selected, but because only one radio button can be selected, the checked attribute is removed from the previous one. The process continues for each iteration and only the radio button matching the last Preference is selected.

To solve this, you need to give each 'grouping' a different name attribute, so that the 5 radio buttons for the 1st Preference will have (say) name="vote1" and the 2nd (say) name="vote2" etc.

However, none of your javascript is necessary if your just generate the view correctly in the first place by binding to your model, and in your case you should be using a view model (I would hate to see the scripts you must be using to convert it all back to to your model when you post the values).

For a simple example of how to generate you view correctly with 2-way model binding, refer this DotNetFiddle.

Comments