Steven Sann
Steven Sann

Reputation: 578

how to pass and use C# enum list to Javascript file and use in it

I have C# enum list class like ,

namespace MyProject.MyEnumListClass
{
 public enum MyEnum
  {
    ValueOne,
    ValueTwo,
    ValueThree,
    ValueFour,
    ValueFive,
    ValueSix
   }
 }

And this is how I use this list in javascript inside razor cshtml

@using MyProject.MyEnumListClass

<script>
  .....

if (type != "@((int)MyEnum.ValueThree)") 

 .....
</script>

It's easily done in razor by using razor's @ to reference those enum values in javascript code. But now, I want to seperate this javascript code to .js file and I'm trying to pass this enum list to javascript file and use in it.
What is the best and proper way to use C# enum list inside javascript seperated file ?

Upvotes: 2

Views: 7541

Answers (5)

Andr&#233; Voltolini
Andr&#233; Voltolini

Reputation: 446

public static class EnumHelper
{
    public static HtmlString EnumToString<T>() where T : Enum
    {
        Dictionary<int, string> enumDict = Enum.GetValues(typeof(T))
               .Cast<T>()
               .ToDictionary(e => Convert.ToInt32(e), e => e.ToString());
        
        return new HtmlString(JsonConvert.SerializeObject(enumDict));
    }

    public static HtmlString EnumToJsClass<T>() where T : Enum
    {
        Dictionary<int, string> enumDict = Enum.GetValues(typeof(T))
            .Cast<T>()
            .ToDictionary(e => Convert.ToInt32(e), e => e.ToString());

        StringBuilder js = new StringBuilder();
        js.AppendLine($"class {typeof(T).Name} {{");

        foreach (KeyValuePair<int, string> item in enumDict)
        {
            js.AppendLine($"static #_{item.Value} = {item.Key};");
        }

        foreach (KeyValuePair<int, string> item in enumDict)
        {
            js.AppendLine($"static get {item.Value}() {{ return this.#_{item.Value}; }}");
        }

        js.Append("}");

        return new HtmlString(js.ToString());
    }
}

Upvotes: 0

Uğur Demirel
Uğur Demirel

Reputation: 81

I use this in my own projects.enum value, enum name, enum description, in array format.It offers a lot of freedom when using cs side. Manoj Choudhari you contributed ideas to me thank you

public enum DayOfWeekTR
{
    [Description("Pazar")]
    pzr = 0,
    [Description("Pazartesi")]
    pzts = 1,
    [Description("Salı")]
    sali = 2,
    [Description("Çarşamba")]
    car = 3,
    [Description("Perşembe")]
    per = 4,
    [Description("Cuma")]
    cuma = 5,
    [Description("Cumartesi")]
    cmrts = 6
}
public enum DepoTipi { ana = 1, sube = 2, uretim = 3 }
public class WebTools {
    
     public static object EnumIslems<T>() where T : struct, IConvertible
     {
         IDictionary<string, object> ret = new ExpandoObject();
         var t = typeof(T);
         var vs = Enum.GetValues(t);
         ret["Enum"] = vs.Cast<int>().ToDictionary(x => Enum.GetName(t, x));
         if (t.GetFields().Any(x => x.GetCustomAttributes(typeof(DescriptionAttribute), false).Any()))
         {
             ret["Array"] = ((T[])vs).Select(x => new
             {
                 vl = Convert.ToInt32(x),
                 tx = x.GetDescription()
             }).ToArray();
         }
         return ret;
     }
}
public static class WebExtensions {
    public static string GetDescription<T>(this T value, string defaultvalue = "") where T : struct, IConvertible
    {
        var type = typeof(T);
        if (type.IsEnum)
        {
            var name = Enum.GetName(type, value);
            if (name.IsNullEmpty()) { return defaultvalue; }
            else
            {
                var customAttribute = type.GetField(name).GetCustomAttributes(typeof(DescriptionAttribute), false);
                return (customAttribute.Length > 0 ? ((DescriptionAttribute)customAttribute[0]).Description : name);
            }
        }
        else { throw Genel.NotImplementedExceptionWarning<T>(); }
    }
    public static MvcHtmlString Enums(this HtmlHelper html)
    {
        IDictionary<string, object> ret = new ExpandoObject();
        foreach (var item in new Type[] { typeof(DayOfWeekTR), typeof(DepoTipi) }) { ret[item.Name] = typeof(WebTools).GetMethod(nameof(WebTools.EnumIslems)).MakeGenericMethod(item).Invoke(null, null); }
        return MvcHtmlString.Create(JsonConvert.SerializeObject(ret));
    }
}

.cshtml(I usually place it in the main layout under the head tag) side

<script type="text/javascript">
      var _enums = @Html.Raw(Html.Enums());
      /*
      var _enums = { "DayOfWeekTR": { "Enum": { "pzr": 0, "pzts": 1, "sali": 2, "car": 3, "per": 4, "cuma": 5, "cmrts": 6 }, "Array": [{ "vl": 0, "tx": "Pazar" }, { "vl": 1, "tx": "Pazartesi" }, { "vl": 2, "tx": "Salı" }, { "vl": 3, "tx": "Çarşamba" }, { "vl": 4, "tx": "Perşembe" }, { "vl": 5, "tx": "Cuma" }, { "vl": 6, "tx": "Cumartesi" }] }, "DepoTipi": { "Enum": { "ana": 1, "sube": 2, "uretim": 3 } } }; the result should be like this! */
      (function () {
          let ob, rt, t = this;
          $.each(Object.keys(t), function (index, vs) {
              if (typeof t[vs].Desc !== 'function') {
                  t[vs].Desc = function (vl, tp) {
                      if (typeof t[vs].Array !== 'object' || (typeof tp === 'boolean' && !tp)) {
                          rt = '';
                          for (ob in t[vs].Enum) {
                              if (t[vs].Enum[ob] === vl) {
                                  rt = ob;
                                  break;
                              }
                          }
                          return rt;
                      }
                      else { return (t[vs].Array.find(x => x.vl === vl) || { tx: '' }).tx; }
                  };
              }
          });
      }).call(_enums);    
    </script>

examples

<script type="text/javascript">
var vl = _enums.DayOfWeekTR.Enum.pzr; //result 0;
var array = _enums.DayOfWeekTR.Array;
var desc = _enums.DayOfWeekTR.Desc(2); // result: 'Salı' if it returned description value
var tx = _enums.DayOfWeekTR.Desc(2, false) // result: 'sali' enum name
</script>

Upvotes: 0

Post Impatica
Post Impatica

Reputation: 16413

Here is a solution I used:

public enum FunValues
{
    Fish,
    Turkey,
    Hotdog,
    Trash
}

In the cshtml I used:

var funValues = '@Html.Raw(Json.Encode(EnumHelper.GetSelectList(typeof(FunValues))))';

Then in JS I used:

// someInt is the past in int that is 1 but I need to get the string 
// "Turkey" out of it so I used the following
var fns = JSON.parse(funValues);
var result = '';
fns.map(val => { if(val.Value == someInt) result = val.Text });
// result now equals "Turkey"

Upvotes: 0

Kalpesh Dabhi
Kalpesh Dabhi

Reputation: 802

You can get Enum value in javascript in simple way

<script>
var aggregateFunctions= @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Enum.GetNames(typeof(Address.AggregateFunc))));

Here in aggregateFunctions get array of enum value

Upvotes: 2

Manoj Choudhari
Manoj Choudhari

Reputation: 5634

C# code is executed on the server. JS code is executed on the browser.

You will not be able to get the C# enum reference in the javascript.

Best way is to define an object in javascript which has same values present in Enum. Then that object can be used in your JavaScript Code.

JS code will be something like below if you are using pure javascript:

var SizeEnum = {
  SMALL: 1,
  MEDIUM: 2,
  LARGE: 3,
};

Refer this article if you want more information on syntax in javascript

EDIT:

If you dont want to specify them explicitly in the JS files, then you can write the extension method as specified in this article. This would convert C# enum to JS enum. This would also help you to keep your JS code always in sync with c# enums.

public static class EnumHelper
{
    public static HtmlString EnumToString<T>()
    {
        var values = Enum.GetValues(typeof(T)).Cast<int>();
        var enumDictionary = values.ToDictionary(value => Enum.GetName(typeof(T), value));
        return new HtmlString(JsonConvert.SerializeObject(enumDictionary));
    }
}

You can then use it in the razor file as shown below. Because this is a script, this variable should be available in your JS files.

<script>
    var assetStatusEnum = @(EnumHelper.EnumToString<SizeEnum>())
</script>

Note: This creates a JSON object that you can use in your javascript. This solution is applicable only if you are using plain javascript. If you are using typescript, i would suggest to use parallel classes in typescript as they would provide better type checks during compile time.

Upvotes: 7

Related Questions