Reputation: 2230
In my MVC application, I've created a helper which should take an enum from the model and then display radio buttons for all of the other available enums of that type.
For example, you have the enum Satus which has Active, Inactive, Closed
and the model for the page has Status = Status.Active
so you want to display radio buttons for Inactive
and Closed
.
Going forward with this example, the MVC view calls helper RadioButtonForEnum:
@Html.RadioButtonForEnum(model => model.Status)
RadioButtonForEnum then gets the list of all Enums of that type and prints them out as radio buttons; however, I'm not sure how to get to the enum that was passed to exclude it from names
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=\"{1}\">{0}{2}</label>", radio, id, HttpUtility.HtmlEncode(StringHelpers.PascalCaseToSpaces(name)));
}
return MvcHtmlString.Create(sb.ToString());
}
Upvotes: 0
Views: 443
Reputation: 16723
Completely untested here as I don't have my own computer, but what about changing your signature to:
public static MvcHtmlString RadioButtonForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Enum Status)
This will allow you to pass in the Status enum and interrogate its value:
public static MvcHtmlString RadioButtonForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Enum Status){
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var names = Enum.GetNames(metaData.ModelType);
var sb = new StringBuilder();
foreach (var name in names)
{
if (!name.Equals(Status.ToString()){
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=\"{1}\">{0}{2}</label>", radio, id, HttpUtility.HtmlEncode(StringHelpers.PascalCaseToSpaces(name)));
}
}
And you would call it from your view like this:
@Html.RadioButtonForEnum(model => model.Status, Model.Status)
Upvotes: 0
Reputation: 11252
Quick and dirty way:
foreach (var name in names)
{
if (name == metaData.Model.ToString())
continue;
...
}
Upvotes: 0
Reputation: 5024
Something like
var modelValue = expression.Compile()(htmlHelper.ViewData.Model);
...
foreach (var name in names.Where(s => s != modelValue.ToString())
...
You need the model instance to get the current enum value to avoid, you could get to it inside the HtmlHelper
by using HtmlHelper.ViewData.Model
as above.
Upvotes: 1
Reputation: 56536
I don't think you have the model object, as-is. You could add it as another parameter:
@Html.RadioButtonForEnum(Model, model => model.Status)
public static MvcHtmlString RadioButtonForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, TModel model, Expression<Func<TModel, TProperty>> expression)
{
string currentStatusName = expression.Compile()(model).ToString();
...
Upvotes: 1