Sunday, June 30, 2013

How to Use CheckBoxListFor With ASP.net MVC 4 ?


Introduction
  • One of the cool features of Microsoft MVC web development framework since its inception, was its rich Html helpers library
  • It provided helpers to create most common html controls like text boxes, drop down lists, text areas, etc.
  • But there is No html helper extension for creation of a checkbox lists
  • No such extension for Latest .Net Framework 4.5 (MVC 4) also
  • So, here I am explaining Nice and Cool Plugin,Which fills that missing MVC HtmlHelper

What is it?
  • It is a custom extension of Microsoft MVC Framework's HtmlHelper class, which creates a POSTable Model-based list of check boxes
  • It was created because there is no built-in MVC way to do this at all (including MVC4)

What are the Features of CheckBoxListFor Plugin ?
  • Easy to use
  • Creates POSTable check boxes from any set of data
  • Strongly-typed, based on View Model
  • Extensive control over layout and appearance
  • Right-to-left language support (e.g. for Arabic, Hebrew, etc.)
  • It's Free (Open source)

How to Use CheckBoxListFor with ASP.net MVC 4 ?
  • Here I have used Visual Studio 2012 and ASP.net MVC 4 Web Application
  • Please Follow the inline comments for better understanding

Step 1 : How to Install CheckBoxListFor Plugin ?

              Tools ==> Library Package Manger ==> Package Manager Console

Package Manager Console

  • Type Install-Package MvcCheckBoxList and press Enter

Install-Package MvcCheckBoxList

  • When It's Successful

Successful

  • After that You could see that, it adds MvcCheckBoxList assembly into your project

MvcCheckBoxList assembly


Step 2 : Create class 'Fruit'

Fruit.cs
Complete project
namespace CheckBoxListForApp.Models
{
 /// <summary>
 /// model for Fruit
 /// </summary>
 public class Fruit
 {
  //Integer value of a checkbox
  public int Id { get;set;}

  //String name of a checkbox
  public string Name { get;set; }

  //Boolean value to select a checkbox
  //on the list
  public bool IsSelected{get;set;}

  //Object of html tags to be applied
  //to checkbox, e.g.:'new{tagName = "tagValue"}'
  public object Tags { get;set;}
                                
 }
}
   
Step 3 : Create 'FruitViewModel' View Model

FruitViewModel.cs

using System.Collections.Generic;

namespace CheckBoxListForApp.Models
{
    /// <summary>
    /// for View Model of FruitViewModel 
    /// </summary>
    public class FruitViewModel
    {
        public IEnumerable<Fruit> AvailableFruits { get; set; }
        public IEnumerable<Fruit> SelectedFruits { get; set; }
        public PostedFruits PostedFruits { get; set; }
    }
}


Step 4 : Create 'PostedFruits' Helper class to make posting back selected values easier

PostedFruits.cs

namespace CheckBoxListForApp.Models
{
    /// <summary>
    /// for Helper class to make posting back selected values easier
    /// </summary>
    public class PostedFruits
    {
        //this array will be used to POST values from the form to the controller
        public string[] FruitIds { get; set; }
    }
}

Step 5 : 'HomeController' Looks like below

HomeController.cs

using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
using CheckBoxListForApp.Models;

namespace CheckBoxListForApp.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// for get all fruits
        /// </summary>
        [HttpGet]
        public ActionResult Index()
        {
            return View(GetFruitsInitialModel());
        }

        /// <summary>
        /// for post user selected fruits
        /// </summary>
        [HttpPost]
        public ActionResult Index(PostedFruits postedFruits)
        {
            return View(GetFruitsModel(postedFruits));
        }

        /// <summary>
        /// for setup view model, after post the user selected fruits data 
        /// </summary>
        private FruitViewModel GetFruitsModel(PostedFruits postedFruits)
        {
            // setup properties
            var model = new FruitViewModel();
            var selectedFruits = new List<Fruit>();
            var postedFruitIds = new string[0];
            if (postedFruits == null) postedFruits = new PostedFruits();

            // if a view model array of posted fruits ids exists
            // and is not empty,save selected ids
            if (postedFruits.FruitIds != null && postedFruits.FruitIds.Any())
            {
                postedFruitIds = postedFruits.FruitIds;
            }

            // if there are any selected ids saved, create a list of fruits
            if (postedFruitIds.Any())
            {
              selectedFruits = FruitRepository.GetAll()
               .Where(x => postedFruitIds.Any(s => x.Id.ToString().Equals(s)))
               .ToList();
            }

            //setup a view model
            model.AvailableFruits = FruitRepository.GetAll().ToList();
            model.SelectedFruits = selectedFruits;
            model.PostedFruits = postedFruits;

            return model;
        }

        /// <summary>
        /// for setup initial view model for all fruits
        /// </summary>
        private FruitViewModel GetFruitsInitialModel()
        {
            //setup properties
            var model = new FruitViewModel();
            var selectedFruits = new List<Fruit>();

            //setup a view model
            model.AvailableFruits = FruitRepository.GetAll().ToList();
            model.SelectedFruits = selectedFruits;

            return model;
        }

    }
}

Step 6 : Create data retrieval Repository as 'FruitRepository'

FruitRepository.cs

using System.Collections.Generic;
using System.Linq;

namespace CheckBoxListForApp.Models
{
    /// <summary>
    /// work as fruit repository
    /// </summary>
    public static class FruitRepository
    {
        /// <summary>
        /// for get fruit for specific id
        /// </summary>
        public static Fruit Get(int id)
        {
            return GetAll().FirstOrDefault(x => x.Id.Equals(id));
        }

        /// <summary>
        /// for get all fruits
        /// </summary>
        public static IEnumerable<Fruit> GetAll()
        {
            return new List<Fruit> {
                              new Fruit {Name = "Apple", Id = 1 },
                              new Fruit {Name = "Banana", Id = 2},
                              new Fruit {Name = "Cherry", Id = 3},
                              new Fruit {Name = "Pineapple", Id = 4},
                              new Fruit {Name = "Grape", Id = 5},
                              new Fruit {Name = "Guava", Id = 6},
                              new Fruit {Name = "Mango", Id = 7}
                            };
        }
    }
}

Step 7 : View Page is as below

Index.cshtml

@using MvcCheckBoxList.Model
@model CheckBoxListForApp.Models.FruitViewModel

@{
    ViewBag.Title = "Home Page";
}

<section class="checkBoxListFor">
    <p>
        <label>Please Select Fruits:</label>
        @using (Html.BeginForm("Index", "Home", FormMethod.Post))
        {
            @Html.CheckBoxListFor(model => model.PostedFruits.FruitIds,
                                  model => model.AvailableFruits,
                                  fruit => fruit.Id,
                                  fruit => fruit.Name,
                                  model => model.SelectedFruits,
                                  Position.Horizontal)


            <input class="green" type="submit" value="POST to Controller" />
        }
    </p>
</section>

Note : You saw that, You have to add reference to the 'MvcCheckBoxList.Model' as above

Step 8 : When you run the Application

  • When Page loads for the First Time
Page loads for the First Time

  • When Post the Page
When Post the Page


That's It.You're Done.

Do you need to Dive Deep ends of CheckBoxListFor ?


MVC 4 on LinkedinDownload file


Conclusion
  • On this article I have showed basic usage of CheckBoxListFor
  • There are number of overload methods exist for this Extension
  • So if you need to learn all of them,You have to browse above mentioned Url 
  • Some of them are, can change Orientation (Horizontal/Vertical),can use Custom Layouts,Templates and much much more ....
  • So enjoy with this Great Missing MVC Extension

I hope this helps to You.Comments and feedback greatly appreciated.

If you feel it was a good article,Give me a +1.Thank You.


You Might Also Like


12 comments:

  1. Hi Innovapath,

    Thanks for your feedback.
    Keep in Touch.

    ReplyDelete
  2. Hi, I would like to see some checked values (edit) when loading the page. I don't see any checked property here.

    ReplyDelete
    Replies
    1. private CheckBoxListViewModel GetInitialModel()
      {
      //setup properties
      var model = new CheckBoxListViewModel();
      var selectedActions = new List();

      //setup a view model
      model.AvailableActions = ActionsRepositoryForExceptions.GetAll().ToList();
      model.SelectedActions = ActionsRepositoryForExceptions.GetAll().Where(x => x.IsSelected == true).ToList();

      return model;
      }

      Delete
    2. This comment has been removed by the author.

      Delete
  3. This comment has been removed by the author.

    ReplyDelete
  4. How do you get client-side validation with this?

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Hi, I would like to see some checked values (edit) when loading edit page. I don't see any checked property here.I'm use you post CODE PROJECT example.

    ReplyDelete
  8. can you show me to validate input in checkboxlistfor

    ReplyDelete
  9. How to bind the CheckboxListFor using jQuery?

    ReplyDelete
  10. Hi sir nice article,
    Is there any way to set Disable attribute by Code, best is if it is in Fruit.??class.

    ReplyDelete

Thanks for your Feedback.