Ryan Tobin
Ryan Tobin

Reputation: 63

How to obtain list of selected values from Select2 dropdown list and pass to controller?

I am using MVC to build a website. On this current view, admin can select 1+ users and 1 role to assign to the selected users. I am having trouble obtaining the list of selected users. I am using a model to display all the users and their current roles, so there are no properties that save data from the form. Here is the form within the view ManageRoles.cshtml :

@using IssueTracker.Areas.Identity.Data;
@model List<UserRoleViewModel>

@{
    ViewData["Title"] = "Manage User Roles";
}

@section Scripts2
{
    <link rel="stylesheet" href="../../dist/plugins/select2/css/select2.min.css">
    <link rel="stylesheet" href="../../dist/plugins/sweetalert2-theme-bootstrap-4/bootstrap-4.min.css">
    <link rel="stylesheet" href="../../dist/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css">
    <link rel="stylesheet" href="../../dist/plugins/datatables-responsive/css/responsive.bootstrap4.min.css">
    <link rel="stylesheet" href="../../dist/plugins/datatables-buttons/css/buttons.bootstrap4.min.css">
}
<div class="row">
    <div class="col-md-6">
        <div class="card card-info">
            <div class="card-header">
                <h3 class="card-title">
                    Change or Update User Roles
                </h3>
            </div>
            <div class="card-body">
                <form method="post">
                    <div class="form-group">
                        <label>Select 1 or More Users:</label>
                        <div class="select2-blue">
                            <select class="select2" name="userList" multiple="multiple" data-dropdown-css-class="select2-blue" data-placeholder="Select a User" style="width: 100%;">
                                @if (Model.Any())
                                {
                                    foreach (var user in Model)
                                    {
                                        <option [email protected]>@user.userName</option>
                                    }
                                }
                            </select>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputRole">Select the Role to Assign:</label>
                        <select name="roleName" id="inputRole" class="form-control custom-select">
                            <option selected disabled>N/A</option>
                            <option value="Admin">Admin</option>
                            <option value="Developer">Developer</option>
                            <option value="Project Manager">Project Manager</option>
                            <option value="Submitter">Submitter</option>
                            <option value="Demo Admin">Demo Admin</option>
                            <option value="Demo Developer">Demo Developer</option>
                            <option value="Demo Project Manager">Demo Project Manager</option>
                            <option value="Demo Submitter">Demo Submitter</option>
                        </select>
                    </div>
                    <div class="row">
                        <div class="col-12">
                            <input asp-controller="Home" asp-action="ManageRoles" type="submit" value="Change Role" class="btn btn-success swalDefaultSuccess float-left">
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>

    <div class="col-md-6">
        <div class="card card-info">
            <div class="card-header">
                <h3 class="card-title">
                    Current Personnel
                </h3>
            </div>

            <div class="card-body">
                <table id="example1" class="table table-bordered table-striped dataTable dtr-inline" aria-describedby="example1_info">
                    <thead>
                        <tr>
                            <th class="sorting sorting_asc" tabindex="0" aria-controls="example1" rowspan="1" colspan="1" aria-sort="ascending" aria-label="User: activate to sort column descending">User</th>
                            <th class="sorting" tabindex="0" aria-controls="example1" rowspan="1" colspan="1" aria-label="Role: activate to sort column ascending" style="">Role</th>
                        </tr>
                    </thead>
                    <tbody>
                        @if (Model.Any())
                        {
                            foreach (var user in Model)
                            {
                                <tr class="odd">
                                    <td class="dtr-control sorting_1" tabindex="0">@user.userName</td>
                                    <td style="">@user.roleNames</td>
                                </tr>
                            }
                        }
                    </tbody>
                    <tfoot>
                        <tr>
                            <th rowspan="1" colspan="1">User</th>
                            <th rowspan="1" colspan="1" style="">Role</th>
                        </tr>
                    </tfoot>
                </table>
            </div>

        </div>

    </div>
</div>

@section Scripts{
    <script src="../../dist/plugins/select2/js/select2.full.min.js"></script>
    <script src="../../dist/plugins/sweetalert2/sweetalert2.min.js"></script>
    <script>$(function () {
            $('.select2').select2()
            $('#mySelect2').find(':selected');
        })</script>
    <script>$(function () {
            var Toast = Swal.mixin({
                toast: true,
                position: 'top-end',
                showConfirmButton: false,
                timer: 3000
            });

            $('.swalDefaultSuccess').click(function () {
                Toast.fire({
                    icon: 'success',
                    title: "Ryan Tobin's role has been changed to Admin."
                })
            });
        });</script>
    <script src="../../dist/plugins/datatables/jquery.dataTables.min.js"></script>
    <script src="../../dist/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js"></script>
    <script src="../../dist/plugins/datatables-responsive/js/dataTables.responsive.min.js"></script>
    <script src="../../dist/plugins/datatables-responsive/js/responsive.bootstrap4.min.js"></script>
    <script src="../../dist/plugins/datatables-buttons/js/dataTables.buttons.min.js"></script>
    <script src="../../dist/plugins/datatables-buttons/js/buttons.bootstrap4.min.js"></script>
    <script src="../../dist/plugins/jszip/jszip.min.js"></script>
    <script src="../../dist/plugins/pdfmake/pdfmake.min.js"></script>
    <script src="../../dist/plugins/pdfmake/vfs_fonts.js"></script>
    <script src="../../dist/plugins/datatables-buttons/js/buttons.html5.min.js"></script>
    <script src="../../dist/plugins/datatables-buttons/js/buttons.print.min.js"></script>
    <script src="../../dist/plugins/datatables-buttons/js/buttons.colVis.min.js"></script>
    <script>$(function () {
            $("#example1").DataTable({
                "responsive": true, "lengthChange": false, "autoWidth": false,
            }).buttons().container().appendTo('#example1_wrapper .col-md-6:eq(0)');
        });</script>
}

Here is the controller:

using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using IssueTracker.Models;
using Microsoft.AspNetCore.Authorization;
using IssueTracker.Areas.Identity.Data;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;

namespace IssueTracker.Controllers;

[Authorize]
public class HomeController : Controller
{
    private IssueTrackerIdentityDbContext application;
    private UserManager<ApplicationUser> userManager;
    private RoleManager<IdentityRole> roleManager;

    public HomeController(IssueTrackerIdentityDbContext app, UserManager<ApplicationUser> userManager,
        RoleManager<IdentityRole> roleManager)
    {
        application = app;
        this.userManager = userManager;
        this.roleManager = roleManager;
    }

    public IActionResult Index()
    {
        return View();
    }

    [Authorize(Roles = "Admin,Demo Admin")]
    public IActionResult ManageRoles()
    {
        var model = new List<UserRoleViewModel>();

        foreach (var user in userManager.Users)
        {
            var roleList = userManager.GetRolesAsync(user).Result;
            var roles = string.Join(", ", roleList);

            var userRoleViewModel = new UserRoleViewModel
            {
                userName = user.FirstName + " " + user.LastName,
                roleNames = roles
            };

            model.Add(userRoleViewModel);
        }

        return View(model);
    }

    [HttpPost]
    public async Task<IActionResult> ManageRoles(List<string> userList, string roleName)
    {
        foreach (string userName in userList)
        {
            ApplicationUser user = await userManager.FindByNameAsync(userName);
            var roles = await userManager.GetRolesAsync(user);
            await userManager.RemoveFromRolesAsync(user, roles.ToArray());
            await userManager.AddToRoleAsync(user, roleName);
        }

        return RedirectToAction("ManageRoles");
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}

and here is the model UserRoleViewModel.cs being used:

using System;
namespace IssueTracker.Models
{
    public class UserRoleViewModel
    {
        public String userName { get; set; }

        public String roleNames { get; set; }
    }
}

I understand that the name property can be used within the form (I used that to successfully obtain the selected role); however, I am not sure how to use that for the select2 list. How can I obtain a list of the selected options and send that to the controller to parse into ApplicationUsers. Thank you!

Upvotes: 0

Views: 1082

Answers (1)

Dmyto Holota
Dmyto Holota

Reputation: 386

In this case you will need to add a name tag as name='userList' and modify the list parameter in ManageRoles method to List<String> userList.

Any inputs in the form you want to submit need to have a name and it needs to be the same as the param name in you're controller.

And the list change is because when you select a value, the value is an string not the view model. <option [email protected]>

Hope this helps :)

Upvotes: 1

Related Questions