Wednesday, May 18, 2016

ASP.NET MVC ListBoxFor() with optgroup Tag support

Here's a simple ListBoxFor helper that supports optgroup tag. See versions for C# and VB.NET.
C# Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public static class HtmlExtensions
{
    public static IHtmlString ListBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TProperty>> expression, Dictionary<string, IEnumerable<SelectListItem>> selectList, 
        object htmlAttributes = null)
    {
        var select = new TagBuilder("select");
        select.Attributes.Add("name", ExpressionHelper.GetExpressionText(expression));
 
        if (htmlAttributes != null)
        {
            RouteValueDictionary routeValues = new RouteValueDictionary(htmlAttributes);
            if(!routeValues.ContainsKey(("size").ToLower()))
            {
                select.Attributes.Add("size", selectList.Sum(x=> x.Value.Count()).ToString());
            }
 
            foreach (var item in routeValues)
            {
                select.Attributes.Add(item.Key, item.Value.ToString());
            }
        }
        else
            select.Attributes.Add("size", selectList.Sum(x => x.Value.Count()).ToString());
 
        var optgroups = new StringBuilder();
 
        foreach (var kvp in selectList)
        {
            var optgroup = new TagBuilder("optgroup");
            optgroup.Attributes.Add("label", kvp.Key);
 
            var options = new StringBuilder();
 
            foreach (var item in kvp.Value)
            {
                var option = new TagBuilder("option");
 
                option.Attributes.Add("value", item.Value);
                option.SetInnerText(item.Text);
 
                if (item.Selected)
                {
                    option.Attributes.Add("selected", "selected");
                }
 
                options.Append(option.ToString(TagRenderMode.Normal));
            }
 
            optgroup.InnerHtml = options.ToString();
 
            optgroups.Append(optgroup.ToString(TagRenderMode.Normal));
        }
 
        select.InnerHtml = optgroups.ToString();
 
        return MvcHtmlString.Create(select.ToString(TagRenderMode.Normal));
    }
}

VB.NET Code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
Public Module HtmlExtensions
 
    <Extension()>
    Public Function ListBoxFor(Of TModel, TProperty)(htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TProperty)), _
        selectList As Dictionary(Of String, IEnumerable(Of SelectListItem)), Optional htmlAttributes As Object = Nothing) As IHtmlString
 
        Dim selectTag = New TagBuilder("select")
        selectTag.Attributes.Add("name", ExpressionHelper.GetExpressionText(expression))
 
        If htmlAttributes IsNot Nothing Then
            Dim routeValues As New RouteValueDictionary(htmlAttributes)
            If Not routeValues.ContainsKey(("size").ToLower()) Then
                selectTag.Attributes.Add("size", selectList.Sum(Function(x) x.Value.Count()).ToString())
            End If
 
            For Each item In routeValues
                selectTag.Attributes.Add(item.Key, item.Value.ToString())
            Next
        Else
            selectTag.Attributes.Add("size", selectList.Sum(Function(x) x.Value.Count()).ToString())
        End If
 
        Dim optgroups = New StringBuilder()
 
        For Each kvp In selectList
            Dim optgroup = New TagBuilder("optgroup")
            optgroup.Attributes.Add("label", kvp.Key)
 
            Dim options = New StringBuilder()
 
            For Each item In kvp.Value
                Dim optionTag = New TagBuilder("option")
 
                optionTag.Attributes.Add("value", item.Value)
                optionTag.SetInnerText(item.Text)
 
                If item.Selected Then
                    optionTag.Attributes.Add("selected", "selected")
                End If
 
                options.Append(optionTag.ToString(TagRenderMode.Normal))
            Next
 
            optgroup.InnerHtml = options.ToString()
 
            optgroups.Append(optgroup.ToString(TagRenderMode.Normal))
        Next
 
        selectTag.InnerHtml = optgroups.ToString()
 
        Return MvcHtmlString.Create(selectTag.ToString(TagRenderMode.Normal))
 
    End Function
End Module

Screenshot Detailed usage of the custom helper: ASP.NET MVC ListBoxFor() with optgroup Tag support
Source codes:
C# Version
VB.NET Version

0 comments:

Post a Comment