I have two lists (list-left and list-right) prepared and populate. Then I have this JS code to move elements from one list to another. And it works fine.
$(function () { $('body').on('click', '.list-group .list-group-item', function () { $(this).toggleClass('active'); }); $('.list-arrows button').click(function () { var $button = $(this), actives = ''; if ($button.hasClass('move-left')) { actives = $('.list-right ul li.active'); actives.clone().appendTo('.list-left ul'); actives.remove(); } else if ($button.hasClass('move-right')) { actives = $('.list-left ul li.active'); actives.clone().appendTo('.list-right ul'); actives.remove(); } }); });
But honestly I don’t know how to pass the result back to codebehind when user clicks the submit button on the form?
This is my cshtml code:
@using AuthDatabase.Entities @using Identity.Models @model RoleEdit @{ ViewData["Title"] = "Edit role"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h1>@ViewData["Title"]</h1> <br /> <h4>Roles</h4> <hr /> <div asp-validation-summary="All" class="text-danger"></div> <form method="post"> <input type="hidden" name="roleName" value="@Model.Role.Name" /> <input type="hidden" name="roleId" value="@Model.Role.Id" /> <div class="row"> <div class="dual-list list-left col-md-5"> <h5>No roles</h5> <div class="well text-right"> <div class="row"> <div class="col-md-10"> <div class="input-group"> <span class="input-group-addon glyphicon glyphicon-search"></span> <input type="text" name="SearchDualList" class="form-control" placeholder="search" /> </div> </div> </div> <ul class="list-group"> @foreach (AppUser user in Model.NonMembers) { <li class="list-group-item">@user.UserName</li> } </ul> </div> </div> <div class="list-arrows col-md-1 text-center"> <button class="btn btn-default btn-sm move-left" type="button"> <span class="btn btn-primary"><</span> </button> <button class="btn btn-default btn-sm move-right" type="button"> <span class="btn btn-primary">></span> </button> </div> <div class="dual-list list-right col-md-5"> <h5>With roles</h5> <div class="well"> <div class="row"> <div class="col-md-10"> <div class="input-group"> <input type="text" name="SearchDualList" class="form-control" placeholder="search" /> <span class="input-group-addon glyphicon glyphicon-search"></span> </div> </div> </div> <ul class="list-group"> @foreach (AppUser user in Model.Members) { <li class="list-group-item">@user.UserName</li> } </ul> </div> </div> </div> <br /> <a asp-action="Index" class="btn btn-secondary">Back to List</a> <button type="submit" class="btn btn-primary">Save</button> </form> @section Scripts { <script src="~/js/lists.js" asp-append-version="true"></script> }
And my controller:
public async Task<IActionResult> Edit(string id) { IdentityRole role = await _roleManager.FindByIdAsync(id); List<AppUser> members = new List<AppUser>(); List<AppUser> nonMembers = new List<AppUser>(); foreach (AppUser user in _userManager.Users) { var list = await _userManager.IsInRoleAsync(user, role.Name) ? members : nonMembers; list.Add(user); } return View(new RoleEdit { Role = role, Members = members, NonMembers = nonMembers }); } [HttpPost] public async Task<IActionResult> Edit(RoleModification model) { IdentityResult result; if (ModelState.IsValid) { foreach (string userId in model.AddIds ?? new string[] { }) { AppUser user = await _userManager.FindByIdAsync(userId); if (user != null) { result = await _userManager.AddToRoleAsync(user, model.RoleName); if (!result.Succeeded) Errors(result); } } foreach (string userId in model.DeleteIds ?? new string[] { }) { AppUser user = await _userManager.FindByIdAsync(userId); if (user != null) { result = await _userManager.RemoveFromRoleAsync(user, model.RoleName); if (!result.Succeeded) Errors(result); } } } if (ModelState.IsValid) return RedirectToAction(nameof(Index)); else return await Edit(model.RoleId); }
The [HttpPost] Edit action requires RoleModification object with two arrays of strings (changes on the lists -> it is now based on previous solution without jquery). It would be also suitable to have only one list-right passed.
public class RoleModification { [Required] public string RoleName { get; set; } public string RoleId { get; set; } public string[] AddIds { get; set; } public string[] DeleteIds { get; set; } }
Advertisement
Answer
$('#submitBtn').on('click', function () { let addIds = []; $('.list-right ul li').each(function (index) { addIds.push($(this).text()); }); ajaxSubmit(addIds); }); }); function ajaxSubmit(input){ $.ajax({ url:'/controller/action', method:'POST', data:input --- or {input} success:function(){ console.log('success');}, error:function(x,y,z){ console.log(x,y,z)};} }); }
and your controller muset be like this
public ActionResult Edit(List<string> input)