Although I've already answered this question, I want to bring up a relatively more complex scenario and show how could we manage checkboxes to affect on each others by using jQuery.
Scenario
- Imagine we have a list of book (from a database or any other repository)
- User can say: "I like this book."
- User can say: "I LOVE this book."
Rules:
- If user LOVEs a book, it means s/he likes it too.
- If user does NOT like a book, s/he canNOT LOVE it either.
Code
Models:
namespace MvcApplication1.Models
{
public class Book
{
public string Title { get; set; }
public bool IsLikeIt { get; set; }
public bool IsLoveit { get; set; }
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
ViewModel:
namespace MvcApplication1.ViewModels
{
public class BookViewModel
{
public Models.Person User { get; set; }
public List<Models.Book> Books { get; set; }
public BookViewModel()
{
Books = new List<Models.Book>();
}
}
}
Controlers:
public class HomeController : Controller
{
public ActionResult Index()
{
BookViewModel viewModel = new BookViewModel();
viewModel.User = new Models.Person()
{ FirstName = "John", LastName = "Smith" };
viewModel.Books.Add(new Models.Book()
{ Title = "Beginning ASP.NET 4: in C# and VB" });
viewModel.Books.Add(new Models.Book()
{ Title = "Professional ASP.NET 4 in C# and VB" });
viewModel.Books.Add(new Models.Book()
{ Title = "Pro ASP.NET MVC 3 Framework" });
viewModel.Books.Add(new Models.Book()
{ Title = "Microsoft ASP.NET CODING STRATEGIES-W/ ASP .NET TEAM" });
viewModel.Books.Add(new Models.Book()
{ Title = "Pro ASP.NET 4 in C# 2010, Fourth Edition" });
return View(viewModel);
}
[HttpPost]
public ActionResult Index(BookViewModel viewModel)
{
//save data.
return View(viewModel);
}
}
View (\Home\Index.cshtml):
@using MvcApplication1.Models
@model MvcApplication1.ViewModels.BookViewModel
<div>
<p>
User name: @Html.DisplayFor(u => u.User.FirstName)
@Html.DisplayFor(u => u.User.LastName)</p>
</div>
<div>
@using (Html.BeginForm())
{
@Html.HiddenFor(u => u.User.FirstName)
@Html.HiddenFor(u => u.User.LastName)
<table border="1">
<thead>
<tr>
<th>
I like it
</th>
<th>
I Love it
</th>
<th>
Book title
</th>
</tr>
</thead>
<tbody>
@for (int index = 0; index < Model.Books.Count; index++)
{
<tr>
<td>@Html.CheckBoxFor(b => b.Books[index].IsLikeIt, new { id = string.Format("like-it-{0}", index), data_index = index })
</td>
<td>@Html.CheckBoxFor(b => b.Books[index].IsLoveit, new { id = string.Format("love-it-{0}", index), data_index = index })
</td>
<td>@Html.DisplayFor(b => b.Books[index].Title)
@Html.HiddenFor(b => b.Books[index].Title)
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Submit" />
}
</div>
<script type="text/javascript">
$(function () {
$('input[id^="like-it-"]').change(function (e) { likeit_clicked(e); });
$('input[id^="love-it-"]').change(function (e) { loveit_clicked(e); });
});
function likeit_clicked(event) {
if (!event.target.checked) {
var index = $(event.target).attr('data-index');
var loveitid = '#love-it-' + index;
$(loveitid).attr('checked', false);
}
}
function loveit_clicked(event) {
if (event.target.checked) {
var index = $(event.target).attr('data-index');
var likeitid = '#like-it-' + index;
$(likeitid).attr('checked', true);
}
}
</script>
View might look crappy. You can develop a better view based on your demands.
By the way, in the rendered html that MVC view engine generates, you can see long names for checkboxes:
name="Books[0].IsLikeIt"
name="Books[1].IsLikeIt"
name="Books[2].IsLikeIt"
.
.
.
but by generating our own id (id = string.Format("like-it-{0}", index)) and defining data-index attribute, jQuery is being enabled to select and change this checkboxes in appropriate manner.
Also read: HTML5 Custom Data Attributes (data-*)
Viewcode as well., new { id = "viewAllReports"}is useless! remove it. and for someone using jQuery and tagging the question with jQuery, you're not using it too much...