How to sort and group json domtree for select option list

Andrus 121 Reputation points
2023-05-19T17:50:01.58+00:00
ASP.NET 7 C# MVC shopping cart controller gets DPD picup point list using

      using HttpClient client = new() { BaseAddress = new Uri("http://ftp.dpdbaltics.com") };
      var domTree = await client.GetFromJsonAsync<JsonNode>("PickupParcelShopData.json");


Result is array of json objects sorted by parcelShopId property:

    [
      {
        "parcelShopId": "EE90001",
        "legacyShopId": "190001",
        "parcelShopType": "PickupStation",
        "companyName": "Automat 1 place xxx",
        "companyShortName": "Automat1",
        "street": "\u00D5ism\u00E4e tee 46",
        "houseNo": "",
        "addressLine2": "London",
        "countryCode": "UK",
        "zipCode": "13512",
        "city": "Tallinn",
        "longitude": "24.64727",
        "latitude": "59.411726",
        "openingHours": [
          {
            "weekday": "Monday",
...
           "openMorning": "0001",
            "closeMorning": "1200",
            "openAfternoon": "1200",
            "closeAfternoon": "2359"
          },
          {
            "weekday": "Tuesday",
            "openMorning": "0001",
            "closeMorning": "1200",
            "openAfternoon": "1200",
            "closeAfternoon": "2359"
          },
          {
            "weekday": "Wednesday",
            "openMorning": "0001",
            "closeMorning": "1200",
            "openAfternoon": "1200",
            "closeAfternoon": "2359"
          },
          {
            "weekday": "Thursday",
            "openMorning": "0001",
            "closeMorning": "1200",
            "openAfternoon": "1200",
            "closeAfternoon": "2359"
          },
          {
            "weekday": "Friday",
            "openMorning": "0001",
            "closeMorning": "1200",
            "openAfternoon": "1200",
            "closeAfternoon": "2359"
          },
          {
            "weekday": "Saturday",
            "openMorning": "0001",
            "closeMorning": "1200",
            "openAfternoon": "1200",
            "closeAfternoon": "2359"
          },
          {
            "weekday": "Sunday",
            "openMorning": "0001",
            "closeMorning": "1200",
            "openAfternoon": "1200",
            "closeAfternoon": "2359"
          }
        ]
      },
      {
        "parcelShopId": "EE90002",
        "legacyShopId": "190002",
        "parcelShopType": "PickupStation",
        "companyName": "Automa3 xxx ",
        "companyShortName": "Automa3",
        "street": "Endla 45",
        "houseNo": "",
        "addressLine2": "Riga",
        "countryCode": "EE",
        "zipCode": "10615",
        "city": "Riga",
        "longitude": "24.7227",
        "latitude": "59.42714",
        "openingHours": [
     ....

Razor View renders select element from it using

    <select id='dpd_select'>
    @foreach ( var esi in domTree.AsArray() ) {
      <option value='@esi["parcelShopId"]'>@esi["companyName"]</option>
      }
    </select>

It is difficult to find pickup point from this order.

How to order and group by select elemnt option list by 3 properties:

     countryCode
     city
     companyName

Should domTree sorted and grouped?

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,356 questions
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,148 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,248 questions
0 comments No comments
{count} votes

Accepted answer
  1. Zhi Lv - MSFT 32,011 Reputation points Microsoft Vendor
    2023-05-22T06:39:59.4766667+00:00

    Hi @Andrus

    How to order and group by select elemnt option list by 3 properties: countryCode, city ,companyName Should domTree sorted and grouped?

    Yes, to group related options in a drop-down list, it is better to sort and group the domTree.

    Try to create the following view model, use them to store the grouped and sorted result.

        public class CountryDataViewModel
        {
            public string CountryCode { get; set; }
            public List<CityDataViewModel> Data { get; set; }
        }
    
        public class CityDataViewModel
        {
            public string City { get; set; }
            public JsonNode[] SubData { get; set; }
        }
    

    Then, in the controller, use the following code to sort and group the json data:

            public async Task<IActionResult> Index()
            {
                using HttpClient client = new() { BaseAddress = new Uri("http://ftp.dpdbaltics.com") };
                var domTree = await client.GetFromJsonAsync<JsonNode>("PickupParcelShopData.json");
    
                var result = domTree.AsArray().GroupBy(c => (string)c["countryCode"]).Select(c=> 
                    new CountryDataViewModel()
                    { 
                        CountryCode = c.Key, 
                        Data = c.GroupBy(d => (string)d["city"]).Select( e=> 
                        new CityDataViewModel()
                        { 
                            City = e.Key, 
                            SubData = e.OrderBy(d => (string)d["companyName"]).ToArray()
                        }
                        ).ToList()
                    }).ToList();
    
                ViewBag.domtree = result;
                return View();
            }
    

    In the view page, use optgroup element to add groups in the drop-down list.

    @{
        var domTree = ViewBag.domtree as List<CountryDataViewModel>;  
    }
    <select id='dpd_select'>
        @foreach (var country in domTree)
        {
            <optgroup label="@country.CountryCode">
                @foreach (var city in country.Data)
                {
                    <optgroup label="&nbsp;&nbsp;&nbsp;&nbsp;@city.City">
                        @foreach (var esi in city.SubData)
                        {
                            <option value='@esi["parcelShopId"]'>@esi["companyName"]</option>
                        }
                    </optgroup>
                }
    
            </optgroup>
        }
    </select>
    

    The result as below:

    image2


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,

    Dillion

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful