@foreach (v" /> @foreach (v" /> @foreach (v"/>

How to preserve selected value of a select controller in a Razor Component?

74 Views Asked by At

There is the following Razor Component:

@using System.Collections
<h3>User</h3>

<div>
    <label>Role:</label>
    <select @bind="SelectedRoleId">
        @foreach (var role in Roles)
        {
            <option value="@role.Id">@role.Name</option>
        }
    </select>
</div>

<div>
    <label>Permission:</label>
    <select @bind="selectedPermissionId">
        @foreach (var permission in Permissions)
        {
            <option value="@permission.Id">@permission.Name</option>
        }
    </select>
</div>

@code {
    private int selectedPermissionId;
    private int _selectedRoleId;
    private List<Role> Roles { get; set; }
    private List<Permission> Permissions { get; set; }

    private int SelectedRoleId
    {
        get => _selectedRoleId;
        set
        {
            _selectedRoleId = value;
            switch (_selectedRoleId)
            {
                case 1:
                    Permissions = new List<Permission>
                    {
                        new () { Id = 1, Name = "Write" },
                        new () { Id = 2, Name = "Read" }
                    };
                    selectedPermissionId = 1;
                    break;
                case 2:
                    Permissions = new List<Permission>
                    {
                        new() { Id = 2, Name = "Read" }
                    };
                    selectedPermissionId = 2;
                    break;
            }
        }
    }

    protected override void OnInitialized()
    {
        Roles = new List<Role>
        {
            new() { Id = 1, Name = "Admin" },
            new() { Id = 2, Name = "User" }
        };
        SelectedRoleId = 1;
    }

    public class Role
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    
    public class Permission
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

Output

enter image description here

The problem is:

  1. User selects Role=User => Permission=Read
  2. User selects Role=Admin => Permission=Write

How can I preserve the selected value of Permission=Read after the second step, since the Admin role also has this Read permission?

1

There are 1 best solutions below

0
MrC aka Shaun Curtis On

Here's your code with two main changes to make it work and a few other formatting changes:

  1. I've added @ref to each option so that the Renderer can track each option properly as they are dynamically changed.

  2. I've removing the setting of //selectedPermissionId = 1; which will always set it Admin whenever you change the role.

  3. I've shown how you can do a -- Select a Value -- when the value is 0.

@page "/"

|<h3>User</h3>

<div class="mb-3">
    <label>Role:</label>
    <select class="form-select" @bind="SelectedRoleId">
        @if (SelectedRoleId == 0)
        {
            <option selected disabled value="0"> -- Select a Role -- </option>
        }
        @foreach (var role in Roles)
        {
            <option @key=role.Id value="@role.Id">@role.Name</option>
        }
    </select>
</div>

<div class="mb-3">
    <label>Permission:</label>
    <select class="form-select" @bind="selectedPermissionId">
        @if (selectedPermissionId == 0)
        {
            <option selected disabled value="0"> -- Select a Permission -- </option>
        }
        @foreach (var permission in Permissions)
        {
            <option @key=permission.Id value="@permission.Id">@permission.Name</option>
        }
    </select>
</div>

@code {
    private int selectedPermissionId;
    private int _selectedRoleId;
    private List<Role> Roles { get; set; } = new();
    private List<Permission> Permissions { get; set; } = new();

    private int SelectedRoleId
    {
        get => _selectedRoleId;
        set
        {
            _selectedRoleId = value;
            switch (_selectedRoleId)
            {
                case 1:
                    Permissions = new List<Permission>
                    {
                        new () { Id = 1, Name = "Write" },
                        new () { Id = 2, Name = "Read" }
                    };
                    //selectedPermissionId = 1;
                    break;
                case 2:
                    Permissions = new List<Permission>
                    {
                        new() { Id = 2, Name = "Read" }
                    };
                    selectedPermissionId = 2;
                    break;
            }
        }
    }

    protected override void OnInitialized()
    {
        Roles = new List<Role>
        {
            new() { Id = 1, Name = "Admin" },
            new() { Id = 2, Name = "User" }
        };
        SelectedRoleId = 1;
    }

    public class Role
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
    }

    public class Permission
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
    }
}