Отправка данных с помощью мультиселекции ViewData в ASP. NET Core 3.0 MVC - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь создать множественный выбор DropDownList, который должен загружать данные из базы данных. Все поля должны быть выбраны при первом запуске. Я хотел бы отправить обратно в контроллер параметр List<string> selectedStatus, сделать там несколько логов c и отправить обратно в представление по ViewData["Status"]. Основываясь на этом параметре, я хотел бы заполнить множественный выбор DropDownList ... Я использую jQuery select2.

При первом запуске ничего не выбрано в DropDownList. Когда я выбираю более одной опции и отправляю в контроллер, первое значение будет отображаться только в DropDownList.

У меня есть метод Index со следующим кодом

        var status = new List<SelectListItem>();

        if (!selectedStatus.Any())
        {
            status = (from t in _context.Status
                      select new SelectListItem()
                      {
                          Text = t.Status,
                          Value = t.StatusId.ToString(),
                          Selected = true
                      }).OrderBy(t => t.Text)
                         .ToList();
        }
        else
        {
            status = (from t in _context.Status
                      select new SelectListItem()
                      {
                          Text = t.Status,
                          Value = t.StatusId.ToString(),
                          Selected = false
                      }).OrderBy(t => t.Text)
                         .ToList();

            foreach (var item in status)
            {
                if (selectedStatus.Any(s => s.Contains(item.Value)) == true)
                {
                    item.Selected = true;

                }
            }

        }

        ViewData["Status"] = status;

В Индекс

<form asp-controller="Home" asp-action="Index" method="get">
    <div class="input-group">
        @Html.DropDownList("selectedStatus", new SelectList((IEnumerable<SelectListItem>)ViewData["Status"], "Value", "Text"), htmlAttributes: new { @class = "form-control", multiple = "multiple", id = "select" })
        <div class="input-group-append">
            <button class="btn btn-outline-secondary" type="submit">Submit</button>
            <a asp-action="Index" class="btn   btn-outline-secondary">Cancel</a>
        </div>
    </div>
</form>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");
        <script>
                $('select').select2({
                    theme: 'bootstrap4',
                    multiple: true,
                });
        </script>
    }
}

Что я делаю не так? Чего там не хватает?

Спасибо.

Ответы [ 2 ]

1 голос
/ 09 апреля 2020

Как предложил Фабиан Камп, вы должны использовать модель представления, чтобы содержать Status и selectedStatus. Вот обходной путь, который, используя js для выделения всех полей, можно использовать:

ViewModel

public class Status
{
    public int StatusId { get; set; }
    public string StatusName { get; set; }
}

public class StatusVM
{
    public List<string> selectedStatus { get; set; }
    public List<SelectListItem> Status { get; set; }
}

Контроллер

 public IActionResult MultiSelectDropDownList(List<string> selectedStatus)
    {
        var model = new StatusVM();

        if (!selectedStatus.Any())
        {
            model.Status = (from t in _context.Status
                      select new SelectListItem()
                      {
                          Text = t.StatusName,
                          Value = t.StatusId.ToString(),
                      }).OrderBy(t => t.Text)
                         .ToList();
            model.selectedStatus = _context.Status.Select(s => s.StatusId.ToString()).ToList();
        }
        else
        {
            model.Status = (from t in _context.Status
                      select new SelectListItem()
                      {
                          Text = t.StatusName,
                          Value = t.StatusId.ToString(),
                      }).OrderBy(t => t.Text)
                         .ToList();
            model.selectedStatus = new List<string>();
            foreach (var item in model.Status)
            {
                if (selectedStatus.Any(s => s.Contains(item.Value)) == true)
                {
                    model.selectedStatus.Add(item.Value);
                }
            }
        }
        return View(model);
    }

Просмотр

@model Demo1.Models.StatusVM

<form asp-controller="Home" asp-action="MultiSelectDropDownList" method="get">
  <div class="input-group">
    @Html.DropDownListFor(m => m.selectedStatus, new SelectList((IEnumerable<SelectListItem>)Model.Status, "Value", "Text", Model.selectedStatus), htmlAttributes: new { @class = "js-example-theme-multiple", multiple = "multiple", id = "select" })
    <div class="input-group-append">
        <button class="btn btn-outline-secondary" type="submit">Submit</button>
        <a asp-action="Index" class="btn   btn-outline-secondary">Cancel</a>
    </div>
  </div>
</form>

@section Scripts {
  @{await Html.RenderPartialAsync("_ValidationScriptsPartial");

    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>

    <script>
        var stringArray = @Html.Raw(Json.Serialize(Model.selectedStatus));

        $(document).ready(function () {

            $("select").select2({
                theme: "classic",
                multiple: true,
          });
          $("select").val(stringArray).trigger('change');
        });

    </script>
  }
}

Результат enter image description here

Ссылка: Установка нескольких значений с помощью jQuery select2

1 голос
/ 08 апреля 2020

При первом запуске он пуст, потому что у вас есть не равный символ перед вашим selectedStatus.Any() или вы случайно изменили истинное ложное в первом if, но более простым решением для этого будет

 var status  = (from t in _context.Status
                      select new SelectListItem()
                      {
                          Text = t.Status,
                          Value = t.StatusId.ToString(),
                          Selected = !selectedStatus.Any()
                      }).OrderBy(t => t.Text)
                         .ToList();

без запроса if.

Во-вторых, вы должны действительно использовать ViewModel, а не ViewData или что-то подобное для этого объема данных.

...