Blazor Dynamic Linked Dropdown Controls

 

Main banner image


I recently came across a unique use case: 

Our marketing department wants to be able to send out email promotions to users.  That is simple enough.

Additionally, they want to be able to select the recipients by some or all of the following:

    1. All
    2. Name
    3. City
    4. Zip Code

In addition, they want to be able to select all matching users of a city or zip code or just the Point of Contact (POC) for the account.

The last requirement is that if Name is selected with POC no other users can be selected and vice versa.  If the POC is not selected, the user can add names.


Backend Design

The backend system design is simple, get a list of users and send each one an email.  If the user chooses city or zip code and POC, we will need to filter by those variables.  We will not cover that code in this post.

I want to focus on the UI for this solution.


Possible UIs

There are many ways we could go with the UI.  Ranging from a radio button group for name, city, or zip code.  Then a check box for POC or not.  But then we would need a separate UI for names.

We could do the left/right data list selection boxes where you move a name from the left to the right to add them or right to left to remove them.

Left to right selection

Or we could use a dropdown list instead of the list boxes.

With this UI, you still must have checkboxes for POC and “ALL”.  But for Users, you could disable the list boxes if POC is checked.

From a UX point of view, you are looking at multiple clicks to add and remove selections from the list boxes.  I was aiming for a better experience.


Chosen UI

I decided to go with a single dropdown, that holds All, Users, City, and Zip. 


Select user group

 

Then based on the selection of the dropdown, I populate the list box with the items that the user can select from.


Second selection list


When the user selects “ALL” we will not show the list box choices. 

When the user selects either “City” or “Zip” and “POC”, they would still need to select at least 1 city or 1 zip code.  This selection will result in the POCs for the accounts that are in those cities or Zip codes.  If POC is not selected, all users in the selected city and zip code will receive the email.

For this example:

City Selection

Only these POCs in Essex and Reno will be sent the promotional emails.


Name Selection

We have the All, City, Zip, and POC handled with the UI, now let’s see how we can handle that.

When the user selects “Name”, we automatically turn on the user-selected POC flag.  In the razor page, we set up a condition to just display a POC check box when the flag is set:

          @if (SelectedItem == "Name" && userNamePOCOnly)
                    {
                    <li>
                        <div class="flex items-center">
                            <input id="checkbox-item-1" type="checkbox" checked=userNamePOCOnly @onchange='eventArgs => { CheckboxClicked("POC", eventArgs.Value); }' >
                            <label for="checkbox-item-1" >POC</label>
                        </div>
                    </li>
                    }
                    else
                    {
                        @foreach (var item in DisplayItems)
                        {
                            var text = item;
                            bool isChecked = selectedItems.Contains(text);
                            <li>
                                <div class="flex items-center">
                                    <input id="checkbox-item-1" type="checkbox" checked=@isChecked @onchange="eventArgs => { CheckboxClicked(text, eventArgs.Value); }" >
                                    <label for="checkbox-item-1" >@item</label>
                                </div>
                            </li>
                        }
                    }


When the user turns the flag off, we display the list of names and a POC item at the top in the second half of the list.

If the user selects POC again from the list, we set the flag and clear out any selected users.  This resets the process back to how it was displayed originally.


Name and POC

Just POC Selection



Name with full list

Full name with POC selection

Dynamic Linking Dropdown to list

Hopefully, you have noticed that when changing the drop-down between possible values the list box changes the possible items to choose from.

We have attached an event handler on the drop-down control to the on-click event, which is just a button.  Once it fires, we update the collection we are using for the list items, “DisplayItems”.  This allows us to use only a single collection of data bound to the list box. We have separate collections for Users, Cities, and Zip codes.  We use these collections to populate the display items.  You must clear out the old display items before using the AddRange function to populate the display items collection or you will end up with multiple items in the list that get displayed.

 

Summary

I like the solution I have for this problem.  It was a fun problem to solve.  It did take several iterations to get to the final solution, but from a UX perspective, I believe it makes a complex issue simple for the user. While keeping the user clicks to a minimum. 

I have not turned this into a reusable control because I am just not sure how often it would be used.  If I find another use case for it, I will most likely turn it into a component.

 

[source code]



Comments

Popular posts from this blog

Yes, Blazor Server can scale!

Blazor new and improved Search Box

Blazor Wizard Step Component