अजपा योग क्रिया आणि ध्यान : श्वास, मंत्र, मुद्रा आणि ध्यान यांच्या सहाय्याने मनःशांती, एकाग्रता, चक्र संतुलन आणि कुंडलिनी जागृती. अधिक माहिती आणि आगामी तारखांसाठी येथे जा.


Group Dropdown list items in ASP.NET Core

Displaying a list of options in a dropdown list or a listbox is quite common in ASP.NET Core forms. You can use the Select Tag Helper to render a <select> element and its options. If you want to display a large number of options to choose from, it would be better to group those options to make it easier for the end user to make the selection. In this article we will learn two ways to group dropdown list items.

Consider a dropdown list that displays a list of branch offices to the end user.

Although the end user can pick an option from the list shown above, wouldn't it be nice to render the list by grouping the branch offices as shown below:

As you can see the items are now grouped by country. This will be especially handy when there are many items to pick from.

To display a dropdown list in ASP.NET Core you use the Select Tag Helper. The Select tag helper renders the <select> element in the browser. We will see two ways to group the dropdown list items.

So, begin by creating a new ASP.NET Core MVC application.

Then add Models, Views, and Controllers folder as you normally do.

In the first approach of grouping the dropdown list items, we will use GroupBy() method of LINQ to group the data based on countries. We will then use this grouped data to render the dropdown list.

Add a new view model class named Branch in the Models folder and add the following properties in it:

public class Branch
{
    public int BranchId { get; set; }
    public string BranchType { get; set; }
    public string Country { get; set; }
    public string City { get; set; }
}    

The Branch class has four properties namely BranchId, BranchType, Country, and City. The property names are quite self explanatory. We would like to group branches by their Country.

Add a controller named HomeController and write the following code in its Index() action.

public IActionResult Index()
{
    List<Branch> branches = new List<Branch> {
        new Branch
        {
            BranchId=1,
            BranchType="Manufacturing Unit" ,
            Country="India",
            City="Mumbai"
        },
        new Branch
        { 
            BranchId=2, 
            BranchType="Sales Office", 
            Country="India", 
            City="Delhi" 
        },
        new Branch
        { 
            BranchId=3, 
            BranchType="Head Office", 
            Country="India", 
            City="Bengaluru" 
        },
        new Branch
        { 
            BranchId=4, 
            BranchType="Spare Parts", 
            Country="United States", 
            City="Houston" 
        },
        new Branch
        { 
            BranchId=5, 
            BranchType="Sales Office", 
            Country="United States", 
            City="Chicago" 
        },
        new Branch
        { 
            BranchId=6, 
            BranchType="Showroom", 
            Country="United States", 
            City="Phoenix" 
        },
        new Branch
        { 
            BranchId=7, 
            BranchType="Showroom", 
            Country="United Kingdom", 
            City="London" 
        },
        new Branch
        { 
            BranchId=8, 
            BranchType="Assembling Unit", 
            Country="United Kingdom", 
            City="Manchester" 
        },
        new Branch
        { 
            BranchId=9, 
            BranchType="Sales Office", 
            Country="United Kingdom", 
            City="Bristol" 
        }
    };
    
    var groupedBranches = branches
                            .GroupBy(i => i.Country)
                            .Select(i => new 
                                {
                                    Country = i.Key,
                                    Branches = i.ToList()
                                })
                            .ToList();
                                
    return View(groupedBranches);
}

Inside the Index() action we create Branch objects the feed our dropdown list. In a more real world case this data will be fetched from some database table.

Notice the code shown in bold letters. We group the List<Branch> on the basis of Country. After grouping we form a new anonymous object with two properties -- Country and Branches. The Country property is the grouping Key and the Branches property holds a List of Branch object belonging to that Key.

This List is then passed to the Index view through the View() method.

Next, add the Index.cshtml view and write the following markup and code to it.

<h1>Option Group Demo</h1>
<form asp-controller="Home" asp-action="Index">
    <select name="branch">
        <option value="">Please select a branch</option>
            @foreach(var group in Model)
            {
            <optgroup label="@group.Country">
                @foreach(var branch in group.Branches)
                {
                    <option value="@branch.BranchId">
                        @branch.City -- @branch.BranchType
                    </option>
                }
            </optgroup>
            }
    </select>
    <button type="submit">Submit</button>
</form>
<h2>@TempData["message"]</h2>

Here, there is a form tag helper that submits to the Index() POST action of the HomeController. We will write the Index() POST action shortly after discussing this form.

The form houses a select tag helper named branch. It contains a default option -- Please select a branch. The <select> element can make use of <optgroup> (Option Group) element for grouping its <option> elements. The <optgroup> element has label attribute that sets the group label in the dropdown list.

In our example, we iterate through all the groups and add option groups depending on the Country values. Inside the option group we add option elements for each Branch belonging to that country. Notice that the value attribute of the option element is set to the BranchId property and it displays a combination of City and BranchType.

There is a submit button to POST the form back to the Index() action. Below the submit button we output a TempData["message"] value that we set in the Index() action. The Index() POST action is shown below:

[HttpPost]
public IActionResult Index(string branchId)
{
    TempData["message"] = "You selected : " + branchId;
    return RedirectToAction("Index");
}    

The Index() POST action receives tge BranchId selected by the end user via the branchId parameter. Inside, we simply set a message in the TempData and redirect the control to the Index() GET action so that the dropdown list is displayed again.

Here is a sample run of this form:

In the above example we used <option> and <optgroup> elements manually in the view. ASP.NET Core provides SelectListItem and SelectListGroup classes that represent these elements respectively. Let's use these classes to achieve the same result.

Modify the first Index() action as shown below:

public IActionResult Index()
{
    List<Branch> branches = new List<Branch> {
        new Branch
        {
            BranchId=1,
            BranchType="Manufacturing Unit" ,
            Country="India",
            City="Mumbai"
        },
        new Branch
        { 
            BranchId=2, 
            BranchType="Sales Office", 
            Country="India", 
            City="Delhi" 
        },
        new Branch
        { 
            BranchId=3, 
            BranchType="Head Office", 
            Country="India", 
            City="Bengaluru" 
        },
        new Branch
        { 
            BranchId=4, 
            BranchType="Spare Parts", 
            Country="United States", 
            City="Houston" 
        },
        new Branch
        { 
            BranchId=5, 
            BranchType="Sales Office", 
            Country="United States", 
            City="Chicago" 
        },
        new Branch
        { 
            BranchId=6, 
            BranchType="Showroom", 
            Country="United States", 
            City="Phoenix" 
        },
        new Branch
        { 
            BranchId=7, 
            BranchType="Showroom", 
            Country="United Kingdom", 
            City="London" 
        },
        new Branch
        { 
            BranchId=8, 
            BranchType="Assembling Unit", 
            Country="United Kingdom", 
            City="Manchester" 
        },
        new Branch
        { 
            BranchId=9, 
            BranchType="Sales Office", 
            Country="United Kingdom", 
            City="Bristol" 
        }
    };
    
        var selectListGroups = branches
                    .Select(i => i.Country)
                    .Distinct()
                    .ToDictionary(i => i,
                        i => new SelectListGroup
                        {
                            Name = i
                        });

        var selectListItems = branches
                    .Select(i => new SelectListItem
                    {
                        Text = i.City + " -- " + i.BranchType,
                        Value = i.BranchId.ToString(),
                        Group = selectListGroups[i.Country]
                    })
                    .ToList();
                                
    return View(selectListItems);
}

Notice the code shown in bold letters. The first LINQ query selects Distinct() countries and converts them into a Dictionary. Each item of the Dictionary has Country as its key and SelectListGroup as its value. The SelectListGroup class has a name property that specifies the label of the group. So, this LINQ query gives us the SelectListGroups required for our dropdown list.

The second LINQ query forms a List of SelectListItem objects from the branches. The Text property is a combination of the City and BranchType whereas the value property holds the BranchId. The Group property of SelectListItem points to the SelectListGroup it belongs to. We pick this SelectListGroup from the Dictionary created at the previous step.

The List<SelectListItem> is then passed to the Index view.

Now open the Index view and modify it as shown below:

<h1>Option Group Demo</h1>
<form asp-controller="Home" asp-action="Index">
    <select name="branch" 
            asp-items="@Model as List<SelectListItem>">
        <option value="">Please select a branch</option>
    
    <button type="submit">Submit</button>
</form>
<h2>@TempData["message"]</h2>

Since we are using SelectListItem and SelectListGroup classes we don't need to iterate through the model. We set the asp-items attribute of the select tag helper to the model object passed to the view. The default option element is also added as before.

Here is a sample run of this example:

So, you can group the dropdown list items either using <optgroup> element manually or using the SelectListGroup class and the Group property of SelectListItem.

That's it for now! Keep coding!!


Bipin Joshi is an independent software consultant and trainer by profession specializing in Microsoft web development technologies. Having embraced the Yoga way of life he is also a meditation teacher and spiritual guide to his students. He is a prolific author and writes regularly about software development and yoga on his websites. He is programming, meditating, writing, and teaching for over 27 years. To know more about his ASP.NET online courses go here. More details about his Ajapa Japa and Shambhavi Mudra online course are available here.

Posted On : 05 June 2023