jQuery для передачи данных в Ajax вызове MVC метода действия - PullRequest
1 голос
/ 02 августа 2020

У меня есть два подготовленных и заполненных списка (список слева и справа). Затем у меня есть код JS для перемещения элементов из одного списка в другой. И он работает нормально.

$(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();
        }        
    });
});

Но, честно говоря, я не знаю, как передать результат обратно в codebehind, когда пользователь нажимает кнопку отправки в форме?

Это мой cs html код:

@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>
}

И мой контроллер:

       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);
        }

Для действия [HttpPost] Edit требуется объект RoleModification с двумя массивами строк (изменения в списках -> теперь на основе предыдущего решения без jquery). Также было бы целесообразно передать только одно право списка.

 public class RoleModification
    {
        [Required]
        public string RoleName { get; set; }
        public string RoleId { get; set; }
        public string[] AddIds { get; set; }
        public string[] DeleteIds { get; set; }
    }

Ответы [ 3 ]

0 голосов
/ 05 августа 2020
  $('#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)};}
}); 
}

и ваш контроллер muset будет таким

public ActionResult Edit(List<string> input)
0 голосов
/ 12 августа 2020

cs html

@model HelloWorldMvcApp.SampleViewModel
    @{
        Layout = null;
    }

<!DOCTYPE html>
<!-- template from http://getbootstrap.com/getting-started -->

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>Bootstrap 101 Template</title>
    </head>
    
    <body>
        @using(Html.BeginForm("GetAnswer","Home"))
        {
            
            <ul>
                @foreach(var item in Model.questions)
                {
                <input type="hidden" value="@item" name="questions"/>
                <li>@item</li>
                }
                @foreach(var item2 in Model.questions2)
                {
                <input type="hidden" value="@item2"  name="questions"/>
                <li>@item2</li>
                }
            </ul>
        @Model.text
        <input type="hidden" value="asd3" name="text"/>
        <input type="submit" value="submit"/>
        }
      
        <!-- JS includes -->
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
        <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
    
        <script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
        <script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"></script>
        
    
    </body>
</html>

ViewModel

using System;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
namespace HelloWorldMvcApp
{
    public class SampleViewModel
    {
        public SampleViewModel()
        {
            this.questions = new string[2];
            this.questions2 = new string[2];
        }
        public string[] questions { get; set; }
        public string[] questions2 { get; set; }
        public string text {get;set;}
    }

    
}

контроллер

using System;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Linq;
namespace HelloWorldMvcApp
{
    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            SampleViewModel model = new SampleViewModel();
            model.questions.SetValue("Test Data",0);
            model.questions.SetValue("Test Data2",1);
            model.questions2.SetValue("Test Data",0);
            model.questions2.SetValue("Test Data2",1);
            return View(model);
        }


        [HttpPost]
        public ActionResult GetAnswer(SampleViewModel model)
        {               
            
                return View(model);
            
        }
        
    
    }
}

как вы можете видеть, он передает массив строк и строк как объект в mvc контроллер

0 голосов
/ 02 августа 2020
измените это на
@using(Html.BeginForm("Action","Controller")){your html here}

, вы также можете сделать это

$.ajax({
url:'/controller/action',
data:form,
success:function(){alert('submitted');},
error:function(x,y,z){console.log(x,y,z);}
});

в основном mvc поиск парсером элементов с тегом имени, таким же, как у модели btw

 public string[] AddIds { get; set; }
 public string[] DeleteIds { get; set; }

эти два поля сложно

var addIds = ['a','b'];

и то же самое для DeleteIds, а затем создать родительский объект, который содержит все поля, необходимые для бэкэнда, стоит сказать, что вы можете использовать бритву в js с @ и js в бритве с @ : так что вы можете сделать что-то вроде этого

@foreach(var id in AddIds){
 @:addIds.add(@id);
}

и, наконец, что не менее важно, вы можете перехватить событие, прослушать его и запустить submit

$('window').ready(function(){
$('#yourSubmitButtonId').on('click',function(){
$('form').submit();
});
});
...