Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pass enum to html.radiobuttonfor MVC3

I Have an Enum Called ActionStatus that has 2 possible values open=0 and closed = 1

public enum ActionStatus {     Open,     Closed } 

I want to build radio button group in my edit and create views that uses the enum to populate the radio buttons with a) a default value in the create view and b) the currently selected option in the edit view.

Do i need an extension method for this, and has anybody already created one?

EDIT: After Darins's answer below this is my Model class

namespace Actioner.Models { [MetadataType(typeof(MeetingActionValidation))] public class MeetingAction {     [Key]     public int MeetingActionId              { get; set; }             [Required]     [Display(Name = "Description")]     public string Description  { get; set; }      [Required]     [Display(Name = "Review Date")]     public DateTime ReviewDate       { get ;set; }      public int Status{ get; set; }      [ScaffoldColumn(false)]     public int MeetingId             { get; set; }       //public virtual Meeting Meeting { get; set; }      //public virtual ICollection<User> Users { get; set; }     public virtual ICollection<ActionUpdate> ActionUpdates { get; set; }      public MeetingActionStatus ActionStatus { get; set; }  }  public enum MeetingActionStatus  {     Open,     Closed } 

and this is my view

@model Actioner.Models.MeetingAction @using Actioner.Helpers   <div class="editor-label"> @Html.LabelFor(model => model.Description) </div> <div class="editor-field"> @Html.EditorFor(model => model.Description) @Html.ValidationMessageFor(model => model.Description) </div>  <div class="editor-label"> @Html.LabelFor(model => model.ReviewDate) </div>  <div class="editor-field"> @Html.EditorFor(model => model.ReviewDate) @Html.ValidationMessageFor(model => model.ReviewDate) </div>  <div class="editor-label"> @Html.LabelFor(model => model.Status) </div> <div class="editor-field">   @Html.RadioButtonForEnum(x => x.ActionStatus)  </div> 

And this is my create controller action

public virtual ActionResult Create(int id)     {          var meetingAction = new MeetingAction         {             MeetingId = id,             ReviewDate = DateTime.Now.AddDays(7)         };          ViewBag.Title = "Create Action";           return View(meetingAction);     }  

The enum displays fine in the view, but the currently selected option is not persisted to the database

like image 783
MrBliz Avatar asked Apr 11 '11 12:04

MrBliz


1 Answers

using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Web; using System.Web.Mvc; using System.Web.Mvc.Html;  namespace YourNamespace {     public static class HtmlExtensions     {         public static MvcHtmlString RadioButtonForEnum<TModel, TProperty>(             this HtmlHelper<TModel> htmlHelper,              Expression<Func<TModel, TProperty>> expression         )         {             var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);             var names = Enum.GetNames(metaData.ModelType);             var sb = new StringBuilder();             foreach (var name in names)             {                 var id = string.Format(                     "{0}_{1}_{2}",                      htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix,                      metaData.PropertyName,                      name                 );                  var radio = htmlHelper.RadioButtonFor(expression, name, new { id = id }).ToHtmlString();                 sb.AppendFormat(                     "<label for=\"{0}\">{1}</label> {2}",                      id,                      HttpUtility.HtmlEncode(name),                      radio                 );             }             return MvcHtmlString.Create(sb.ToString());         }     } }     

You could also enforce a generic constraint to an enum type for this helper method.

and then:

Model:

public enum ActionStatus {     Open,     Closed }  public class MyViewModel {     public ActionStatus Status { get; set; } } 

Controller:

public class HomeController : Controller {     public ActionResult Index()     {         return View(new MyViewModel         {             Status = ActionStatus.Closed         });     }      [HttpPost]     public ActionResult Index(MyViewModel model)     {         return View(model);     } } 

View:

@model MyViewModel @using (Html.BeginForm()) {     @Html.RadioButtonForEnum(x => x.Status)     <input type="submit" value="OK" /> } 
like image 136
Darin Dimitrov Avatar answered Sep 18 '22 17:09

Darin Dimitrov