Создание поля для выпадающего списка с множественным выбором на основе собственного (без создания новой модели) - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь реализовать функцию множественного выбора для моего BugTracker и не могу найти решение, которое не включает в себя создание другой модели. Вот как это работает:

У меня есть модель с именем Report, которая содержит информацию об ошибке. Эта модель содержит такие поля, как имя ошибки, срочность, дата отправки, решение и т. Д. Я хочу добавить поле, которое фактически будет списком связанных ошибок. Таким образом, когда программист обновляет этот отчет, он может выбрать из списка предыдущих ошибок (отчетов) и добавить несколько номеров отчетов. Когда отчет просматривается (не редактируется), эти номера отображаются в виде ссылки на страницу отчета. Поэтому, возможно, пользователь видит это:

Похожие ошибки: 1, 37, 56

И код, стоящий за ним, будет выглядеть так:

RelatedBugs: @ Html.ActionLink ("1", "Admin", "Report", 1, null), @ Html.ActionLink ("37", "Admin", "Report", 37, null), @ Html.ActionLink ("56", "Admin", "Report", 56, null)

(Где эти цифры на самом деле являются идентификатором Report.cs снизу.)

Таким образом, в представлении «Правка» формы будет раскрывающийся список с множественным выбором, в котором вы сможете выбрать все эти ошибки. Это будет похоже на https://harvesthq.github.io/chosen/,, где в области множественного выбора вы можете увидеть список всех ошибок / отчетов и связанных с ними идентификаторов. Или даже просто список идентификаторов!

А на типичном виде вы увидите то, что у вас есть выше.

Что я могу сделать, чтобы это работало правильно?

Позвольте мне дать вам свой собственный код, чтобы показать вам, что я имею в виду (код значительно сокращен, чтобы облегчить вопрос):

Report.cs (модель)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace BugTracker.Models
{
    public class Report
    {
        //For User
        public int ID { get; set; }
        public String Name { get; set; }
        public String Description { get; set; }
        public String Solution { get; set; }    
    }
}

AdminReport.cshtml (Просмотреть)

@model BugTracker.Models.Report
@{
    ViewBag.Title = "Report";
    Layout = "~/Views/Shared/_Layout.cshtml";
}


<h1>@Model.Name</h1>
Description: @Model.Description <br /> <br />
Solution: @Model.Solution    <br /> <br>

И форма, используемая для редактирования ...

AdminReportForm.cshtml

@model  BugTracker.ViewModels.UserReportViewModel

@{
    ViewBag.Title = "Issue Form";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Update Issue</h1>    
@Model.Report.Name <br />    
@using (Html.BeginForm("SaveAdmin", "Report"))
{
    <div class="form-group">
        <label>Solution</label>
        @Html.TextAreaFor(m => m.Report.Solution, new { @class = "form-control", @rows="10"})
    </div>
    @Html.HiddenFor(m => m.Report.ID)
    <button type="submit" class="btn btn-primary">Save</button>
}

Моя viewmodel (реальная ViewModel содержит несколько дополнительных полей):

UserReportViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using BugTracker.Models;
using System.Web.Mvc;

namespace BugTracker.ViewModels
{
    public class UserReportViewModel
    {
        public Report Report { get; set; }    
    }
}

Контроллеры ...

(для AdminReport.cshtml)

    public ActionResult Admin(int id)
    {
        var report = _context.Reports.SingleOrDefault(c => c.ID == id);
        if (report == null)
            return HttpNotFound();

        var viewModel = new UserReportViewModel
        {
            Report = report,
        };

        return View("AdminReport", report);
    }

Для AdminReportForm.cshtml

    public ActionResult EditAdmin(int id)
    {
        var report = _context.Reports.SingleOrDefault(c => c.ID == id);
        if (report == null)
            return HttpNotFound();

        var viewModel = new UserReportViewModel
        {
            Report = report,
        };

        return View("AdminReportForm", viewModel);
    }

И наконец мой пост:

    [HttpPost]
    [ValidateInput(false)]
    public ActionResult SaveAdmin(UserReportViewModel viewModel)
    {
        if (viewModel.Report.ID == 0)
            _context.Reports.Add(viewModel.Report);
        else
            var reportInDb = _context.Reports.Single(c => c.ID == viewModel.Report.ID);

        _context.SaveChanges();
        return RedirectToAction("ReportAll", "Report");

    }

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Мне удалось наконец решить эту проблему - спасибо всем за помощь, всем! Вот как я решил это:

Сначала в моем файле " Report.cs " я добавил следующее:

public String RelatedBugs {get; set;}
public String[] RelatedBugsArray {get; set;}

В моей модели представления " UserReportViewModel.cs " я добавил следующее:

public IEnumerable<Report> Report {get; set;}

Форма дала мне некоторые проблемы. Сначала я использовал DropDownBoxFor, но для множественного выбора вам действительно нужно использовать ListBoxFor (он все равно будет работать с DropDownBoxFor, но проблема в том, что он не может предварительно заполнить его при попытке редактировать форму.) Итак, в AdminReportForm.cshtml , у меня есть следующее:

@Html.ListBoxFor(m => m.Report.RelatedBugsArray, new MultiSelectList(Model.Reports, "ID", "Name"), new {id = "relatedbugs"})

Чтобы использовать выбранный скрипт, я сначала настроил его по этой ссылке: Используйте плагин Chosen jQuery в MVC Asp Net

В том же отчете я сделал свой ListBox для использования моего скрипта Chosen со следующим:

@section scripts{
<script>
$(function () {
$("#relatedbugs").chosen();
});
</script>
}

Теперь все, что осталось, это контроллер. Меня волнуют два действия: редактирование и сохранение. Действия EditAdmin и Admin будут иметь одинаковый код:

if (report.RelatedBugs != null)
     report.RelgatedBugsArray = report.RelatedBugs.Split(',');

Для действия SaveAdmin нам просто нужно сделать это:

if (viewModel.Report.RelatedBugsArray == null)
     viewModel.Report.RelatedBugs = null;
else
     viewModel.Report.RelatedBugs = string.Join(",", viewModel.Report.RelatedBugsArray);

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

Еще раз спасибо за все предложения!

0 голосов
/ 30 августа 2018

Вы можете добавить коллекцию отчетов к вашей модели представления? Затем вы можете использовать linq для фильтрации отчетов и заполнения выпадающего списка.

namespace BugTracker.ViewModels
{
    public class UserReportViewModel
    {
        public Report Report { get; set; }
        public List<Report> Reports {get; set;}
    }
}
...