DropDownList with Enum Kendo UI
Asked Answered
L

8

6

I'm working on updating an application to use Kendo UI and have run into an issue with binding to an Enum with the DropDownList. The two issues I am having is 1) the value does not contain the Enum value and instead contains "Today" (should be 0), and 2) The display value is always "Last10Days" instead of "Last 10 Days" in the description tag. I looked and couldn't find another place where someone has used Kendo UI to display the description as the text and include the numerical value instead of the text. Any help is appreciated.

View

<div class="span6">
  @Html.LabelFor(m=> m.DateRanges)
  @(Html.Kendo().DropDownListFor(m => m.DateRanges)
      .BindTo(Enum.GetNames(typeof(SearchDateRanges)).ToList())
      .HtmlAttributes(new { value = "Today" })
      .DataTextField("Text")
      .Events(e => e.Change("DateChange")))
</div>

<div class="span6">
  @Html.LabelFor(m => m.Status)
  @(Html.Kendo().DropDownListFor(m=> m.Status)
      .BindTo(Enum.GetNames(typeof(SearchStatusCriteria)).ToList())
      .HtmlAttributes(new {value = "All"}))
</div>

Model

    public enum SearchDateRanges
{
    [Description("Today")]
    Today = 0,

    [Description("Last 10 Days")]
    Last10Days = 1,

    /// <summary>
    /// The last 30 days.
    /// </summary>
    [Description("Last 30 Days")]
    Last30Days = 2,

    [Description("Last 60 Days")]
    Last60Days = 3,

    [Description("Last 90 Days")]
    Last90Days = 4,

    [Description("Custom Date Range")]
    CustomRange = 5
}

}

Long answered 5/4, 2013 at 17:19 Comment(0)
K
5

It appears that you are asking for the Variable Name of the enum and not the description attribute:

.BindTo(Enum.GetNames(typeof(SearchDateRanges)).ToList())

To get the description attribute you'll have to do a little work. Here is some code I found:

public static string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

DescriptionAttribute[] attributes =
    (DescriptionAttribute[])fi.GetCustomAttributes(
    typeof(DescriptionAttribute),
    false);

if (attributes != null &&
    attributes.Length > 0)
    return attributes[0].Description;
else
    return value.ToString();
}

You also are binding the Text Field to "Text" which doesn't exist in your enum.

Hope this helps.

Kirovograd answered 5/4, 2013 at 17:53 Comment(1)
Thanks, but only binds enum values instead of Descriptions. Any idea?Coextensive
L
5

AFAIK, this isn't supported automatically.

You can write a little helper method that takes an Enum type and converts it to a List<SelectListItem> like this:

public static List<SelectListItem> EnumToSelectList( Type enumType )
{
  return Enum
    .GetValues( enumType )
    .Cast<int>()
    .Select( i => new SelectListItem
      {
        Value = i.ToString(),
        Text = Enum.GetName( enumType, i ),
      }
    )
    .ToList()
}

Then you can bind your DropDownList to the Select List:

.BindTo( EnumToSelectList( typeof( SearchDateRanges ) ) )

If you want the text to come from the Description attributes, you'll have to modify this to get the attribute values - probably via Reflection.

Loosen answered 5/4, 2013 at 17:39 Comment(1)
Thanks, but only binds enum values instead of Descriptions. Any idea?Coextensive
K
5

It appears that you are asking for the Variable Name of the enum and not the description attribute:

.BindTo(Enum.GetNames(typeof(SearchDateRanges)).ToList())

To get the description attribute you'll have to do a little work. Here is some code I found:

public static string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

DescriptionAttribute[] attributes =
    (DescriptionAttribute[])fi.GetCustomAttributes(
    typeof(DescriptionAttribute),
    false);

if (attributes != null &&
    attributes.Length > 0)
    return attributes[0].Description;
else
    return value.ToString();
}

You also are binding the Text Field to "Text" which doesn't exist in your enum.

Hope this helps.

Kirovograd answered 5/4, 2013 at 17:53 Comment(1)
Thanks, but only binds enum values instead of Descriptions. Any idea?Coextensive
P
3

NET MVC 5.1 with the @Html.EnumDropDownListFor.

Just make a new .cshtml in the Views/EditorTemplate folder.

For example, in a cshtml with the grid,

@(Html.Kendo().Grid<NameProved.Models.Issuer>()
.Name("IssuerGrid")
.Columns(columns =>
{
    columns.Bound(issuer => issuer.ID);
    columns.Bound(issuer => issuer.Name);
    columns.Bound(issuer => issuer.IssuerType);

    columns.Command(commands =>
        {
            commands.Edit();
            commands.Destroy();
        }).Title("Commands");
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable
    .Mode(GridEditMode.PopUp)
    )
.DataSource(datasource =>
    datasource
    .Ajax()
    .Events(events => events.Error("grid_error"))
    .Model(model =>
    {
        model.Id(issuer => issuer.ID);
        model.Field(issuer => issuer.ID).Editable(false).DefaultValue(0);
    })
    .Create(create => create.Action("Issuer_Create", "Admin"))
    .Read(read => read.Action("Issuer_Read", "Admin"))
    .Update(update => update.Action("Issuer_Update", "Admin"))
    .Destroy(destroy => destroy.Action("Issuer_Destory", "Admin"))
    )
.Pageable()

)
)

Here you would have to add the UIHint to the issuerType, which is a enum.

Then in the Views/Shared/EditorTemplate/IssuerTypeEditor.cshtml,

@model NameProved.Models.IssuerType

@Html.EnumDropDownListFor(issuerType => issuerType)

Then in the model, add the UIHint.

public class Issuer
{

    public int ID { get; set; }
    public string Name { get; set; }

    [UIHint("IssuerTypeEditor")]
    public IssuerType IssuerType { get; set; }
}

Then you will get it.

Pathic answered 30/5, 2014 at 14:26 Comment(1)
Thanks! I was able to avoid using UIHint by making the name of the editor template made the name of the enum exactly.Frustration
W
2

I know this thread is old but in case someone googles for the same proble, here is another solution:

@(Html.Kendo().DropDownList()
    .Name("subscriptionTypeTest")
    .DataTextField("Text")
    .DataValueField("Value")
    .BindTo(Html.GetEnumSelectList(typeof(SubscriptionType)))
    .Deferred()
)
Wisnicki answered 17/6, 2016 at 19:41 Comment(1)
Side note: If using this in an Editor Template, you may have issues with .Deferred(). It took me hours to realize that was my problem.Hyperploid
G
1

You can try this one

@(Html.Kendo().DropDownListFor(model => model.NoticePeriodType)
      .DataTextField("Text")
      .DataValueField("Value")
      .DataSource(source =>
         {
           source.Read(read =>
           {
              read.Action("LoadPeriodTypesAjax", "ControllerName"); //put controller name
            });
         })
   )


public JsonResult LoadPeriodTypesAjax()
{
    var values = Enum.GetValues(typeof(PeriodType)).Cast<int>(); //PeriodType= enum name
    var converter = TypeDescriptor.GetConverter(typeof(PeriodType));
    var datas = from value in values
                select new SelectListItem
                {
                    Text = converter.ConvertToString(value),
                    Value = value.ToValue(),
                };
    return Json(datas, JsonRequestBehavior.AllowGet);
}
Grisons answered 24/2, 2016 at 21:5 Comment(0)
H
1

The Answer from Andre works only with ASP.Net MVC 5.1 and above. With older versions you can use EnumHelper.GetSelectList

@(Html.Kendo().DropDownList()
    .Name("subscriptionTypeTest")
    .DataTextField("Text")
    .DataValueField("Value")
    .BindTo(EnumHelper.GetSelectList(typeof(SubscriptionType)))
    .Deferred()
)
Helianthus answered 30/11, 2016 at 17:48 Comment(2)
When you say MVC 5.1, do you mean ASP.NET Core MVC?Hyperploid
With MVC 5.1 I mean ASP.Net MVC 5.1 (I changed my answer). I did not test it with ASP.NET Core MVC.Helianthus
G
1

This is very similar to Nikolay Kostov answer. This works for Telerik asp.net core. This is the code for your editor template.

@model Enum

@(Html.Kendo().DropDownListFor(m => m)
        .DataTextField("Text")
        .DataValueField("Value")
        .BindTo(Html.GetEnumSelectList<Web.Models.YourEnumType>())
        
    )
Giffard answered 2/7, 2021 at 20:28 Comment(1)
Tested with .Net5 - works like a charm. At least in .Net5 DataTextField() and DataValueField() are not required. BindTo honors SelectListItem enumerable returned by Html.GetEnumSelectList().Implantation
E
0

In case you need editor template for enum in Kendo UI and ASP.NET Core, you can use this editor template code in Enum.cshtml:

@model Enum
@{
    var values = Enum.GetValues(this.ViewData.ModelMetadata.ModelType).Cast<object>()
        .Select(v => new SelectListItem
                     {
                         Selected = v.Equals(this.Model),
                         Text = v.ToString(),
                         Value = ((int)v).ToString()
                     });                               
}

@(this.Html.Kendo().DropDownListFor(m => m)
    .DataTextField("Text")
    .DataValueField("Value")
    .BindTo(values))
Endodontist answered 22/11, 2019 at 14:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.