DataTables / Editor-NET

.NET Framework and .NET Core server-side libraries for Editor
Other
15 stars 12 forks source link

Add support for using Enums as options for SearchPanes, SearchBuilder and Options #10

Closed gotmoo closed 10 months ago

gotmoo commented 10 months ago

I was looking for a way to use an enum as a way to filter in SearchPanes, where my database stores only the int, but I want the user to be able to search using the name they are used to seeing elsewhere. In the end I added this functionality to SearchBuilder and Options as well.

What's Added

I added a new class to EditorUtil called Enums that houses the method ConvertToStringDictionary. This takes care of converting the supplied enum to a Dictionary<string, string>. It also reads an optional Description attribute from the enum and uses that as the Value of the dictionary. This checks to make sure the supplied item is an enum, and if not it throws an ArgumentException(typeof(T).Name + " must be an enum type.") . I did not figure out how to have this be a "nice" error, but on the other hand this is something that will break immediately when the dev first runs this.

What's Changed

SearchPaneOptions

I added FromEnum<T>(bool useValueAsKey = true) as a method to SearchPaneOptions. This method is supported by a new private field _fromEnum and is instantiated with a new Dictionary. In the Exec method, after the valid options for a field are retrieved, each row is looped and the label from the database is replaced with the name (or description) from the enum.

SearchBuilderOptions

Pretty much a copy/paste from SearchPaneOptions, I added FromEnum<T>(bool useValueAsKey = true) as a method to SearchBuilderOptions. This method is supported by a new private field _fromEnum and is instantiated with a new Dictionary. In the Exec method, after the valid options for a field are retrieved, each row is looped and the label from the database is replaced with the name (or description) from the enum.

Options

in Options, I've added the AddFromEnum<T>(bool useValueAsKey = true) method. This method adds each item from the enum to _manualOpts, but not before checking if the value could be an integer.

Then I added a check at the beginning of the Exec method to see if the _table is null and just return the manual options after a quick sort.

If the table is supplied with value and label I noticed duplicate values once the manual options were added, so I added a check for _manualOpts presence and then remove duplicates based on the value.

Usage

This example uses the users table with the UploadManyModel. I stared with the SearchBuilder example

.Field(new Field("users.site")
    .SearchBuilderOptions(new SearchBuilderOptions()
        .FromEnum<SitesEnum>()
    )
    .SearchPaneOptions(new SearchPaneOptions()
        .FromEnum<SitesEnum>()
    )
    .Options(new Options()
        .AddFromEnum<SitesEnum>()
        .Add("Unknown", 0)
    )
)
.Field(new Field("users.title")
    .SearchBuilderOptions(new SearchBuilderOptions()
        .FromEnum<Salutations>(false) //use the name of the enum as value
    )
    .SearchPaneOptions(new SearchPaneOptions()
        .FromEnum<Salutations>(false)
    )
    .Options(new Options()
        .AddFromEnum<Salutations>(false)
    )
)

Example of an input enum:

public enum SitesEnum
{
    Edinburgh = 1,
    London = 2,
    Paris = 3,
    [Description("New York")]
    NewYork = 4,
    Singapore = 5,
    [Description("Los Angeles")]
    LosAngeles = 6,
    Pittsburgh = 7
}
public enum Salutations
{
    Mr,
    Mrs,
    Ms,
    Miss,
    Dr,
    Sir,
    [Description("Ma'am")]
    Madam
}

Running this generates these options: image

and these builders: image

I hope this helps explain what I did. I will be happy to answer further questions, or of any changes are needed to properly fit in the style of the project.

Thanks!

gotmoo commented 10 months ago

I noticed that my first commit on options.cs got weird, and it removed and re-added the entire file. I can try to revert that and re-apply my changes and then retry if you'd like.

AllanJard commented 10 months ago

You say this is your first PR? You are a natural! It looks great!

Are you happy for this to be included under the MIT license?

gotmoo commented 10 months ago

Yes, I am good for this to be under the MIT license.

AllanJard commented 10 months ago

Awesome - thank you so much.