Skip to content

Instantly share code, notes, and snippets.

@KevM
Created September 10, 2012 18:38
Show Gist options
  • Save KevM/3692811 to your computer and use it in GitHub Desktop.
Save KevM/3692811 to your computer and use it in GitHub Desktop.
FubuMVC html convention element builder to create select elements from enum properties
public class EnumDropdownBuilder : ElementBuilder
{
protected override bool matches(AccessorDef def)
{
var type = def.Accessor.PropertyType;
return type.IsEnum;
}
public override HtmlTag Build(ElementRequest request)
{
return new SelectTag(tag =>
{
buildOptions(request, tag);
tag.AddClass("enum-list");
});
}
private static void buildOptions(ElementRequest request, SelectTag tag)
{
var enumType = request.Accessor.PropertyType;
foreach (var name in Enum.GetNames(enumType))
{
tag.Option(name, name);
}
var requestValue = request.StringValue();
var defaultValue = requestValue.IsNotEmpty() ? requestValue : getDefaultValue(request, enumType);
tag.SelectByValue(defaultValue);
}
private static string getDefaultValue(ElementRequest request, Type enumType)
{
var propertyDefaultValueFromAttribute = "";
if (request.Accessor.HasAttribute<DefaultValueAttribute>())
{
var defaultValueFromAttribute = request.Accessor.GetAttribute<DefaultValueAttribute>().Value.ToString();
if (Enum.GetNames(enumType).Any(n => n == defaultValueFromAttribute))
propertyDefaultValueFromAttribute = defaultValueFromAttribute;
//else log a nice trace warning but I'd rather this type of thing be a compiler or lint type warning??
}
return propertyDefaultValueFromAttribute;
}
}
/// Import this in your ConfigureFubuMVC.cs file via:
//
/// Import<MyHtmlConventions>();
//
public class MyHtmlConventions : HtmlConventionRegistry
{
public static readonly string EDIT_PROFILE = "edit";
public MyHtmlConventions()
{
setUpFormConventions();
}
private void setUpFormConventions()
{
Editors.Builder<EnumDropdownBuilder>();
Editors
.If(prop => prop.Accessor.FieldName.ToLower().Contains("password"))
.Modify(tag => tag.Attr("type", "password"));
Editors.If(prop => prop.Accessor.FieldName.Equals("Text"))
.Modify(tag => tag.TagName("textarea"));
}
}
public class MyModel
{
[DefaultValue("Customer")]
public SiteType Type { get; set; }
}
public enum SiteType
{
Customer,
Internal,
Reseller,
Individual,
Vendor,
}
@KevM
Copy link
Author

KevM commented Sep 10, 2012

Weeee

Example of it in action:
example

  • Default value is from System.ComponentModel.DefaultValueAttribute

@drusellers
Copy link

The only other thing I can think of is what if we want a 'Please Select' ?

@jeremydmiller
Copy link

Dru, you could do that with a "Modifier" later.

@ahjohannessen
Copy link

Is the value from DefaultValueAttribute a string? If so, perhaps you could do a sanity check using Enum.GetNames(enumType)?

@KevM
Copy link
Author

KevM commented Sep 11, 2012

Gist updated with a registration example and the sanity check suggested by @ahjohannessen

@dru the Please select could be added if no default was specified. Personally I agree with Jeremy that is a particular use case that some people like and others don't.

@KevM
Copy link
Author

KevM commented Sep 11, 2012

^^^ I guess that should have been @drusellers

@drusellers
Copy link

coolio

@KevM
Copy link
Author

KevM commented Sep 11, 2012

Dru mentioned that it could accept a enum value as well. Throwing together an update and some tests now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment