代码之家  ›  专栏  ›  技术社区  ›  Mantracker

如何创建在ASP.NET EF中增长的动态下拉框?

  •  0
  • Mantracker  · 技术社区  · 6 年前

    我正在尝试实现Dropbox,它可以显示为预先填充的,并且可以在您按下按钮时动态增长。我从一个不动态增长的基本下拉框实现开始。这是我的控制器+DTO代码段:

    public class TaskDTO
    {
         public string TaskTemplateName { get; set;}
    }
    
    public IActionResult Create()
    {
            ViewData["TaskTemplateId"] = new SelectList(_context.TaskTemplates, "Id", "Name");
            return View();
    }
    
    public async Task<IActionResult> Create([Bind("Id,TaskTemplateName")] TaskDTO task)
        {
            if (ModelState.IsValid)
            {
                //Do some stuff
            }
            ViewData["TaskTemplateId"] = new SelectList(_context.TaskTemplates, "Id", "Name", task.TaskTemplateName);
            return View(task);
        }
    

    这是我的create.cshtml Razor代码:

    <h2>Create</h2>
    
    <h4>TemplateTask</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="Create">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="TaskTemplateName" class="control-label"></label>
                `  `<select asp-for="TaskTemplateName" class="form-control" asp-items="ViewBag.TaskTemplateId"></select>
                </div>
    

    然后我环顾四周发现了这个 link 这说明了如何创建可以增长的动态表单。我试着把这个想法和下拉框结合起来。基于该教程,以下是我的新DTO+控制器代码:

    public class TaskTemplateDTO
    {
        public string TaskTemplateName { get; set; }
    }
    
    public class TaskDTO
    {
        public List<TaskTemplateDTO> TaskTemplateNames { get; set; }
    }
    
    
    public IActionResult Create()
        {
            var vm = new TaskDTO() { };
            ViewData["TaskTemplateId"] = new SelectList(_context.TaskTemplates, "Id", "Name");
            return View(vm);
        }
    
    public async Task<IActionResult> Create([Bind("Id,TaskName,TaskTemplateNames,ParentTasks,IsBasicTask,EstimatedTime,RequiredResources")] TaskDTO task)
        {
            if (ModelState.IsValid)
            {
                //Do some stuff
            }
    
            ViewData["TaskTemplateId"] = new SelectList(_context.TaskTemplates, "Id", "Name", task.TaskTemplateNames);
            return View(task);
        }
    

    这是我的额外编辑模板Razor,taskTemplatedto.cshtml:

    @model Namespace.TaskTemplateDTO
    
    <select asp-for="TaskTemplateName" class="TaskTemplate" asp-items="ViewBag.TaskTemplateId"></select>
    

    这是我的create.cshtml Razor代码:

    <h2>Create</h2>
    
    <h4>TemplateTask</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="Create">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <table class="table table-bordered" id="TaskTemplateTable">
                        <tr>
                            <th>Task Templates</th>
                            <th><button type="button" name="add" id="btn_AddTaskTemplate" class="btn btn-success btn-sm add"><span class="glyphicon glyphicon-plus"></span></button></th>
                            @Html.EditorFor(f => f.TaskTemplateNames)
                        </tr>
                    </table>
                </div>
            </form>
        </div>
    </div>
    
    
    
    @section Scripts {
        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    
        <script>
    
            $("#btn_AddTaskTemplate").click(function () {
                var i = $(".TaskTemplate").length;
                var html = '';
                html += '<tr>';
                html += '<td><select type="text" name="TaskTemplateNames[' + i + '].TaskTemplateName" class="TaskTemplate" /></td>';
                html += '<td></td></tr>';
            });
    
    $('#TaskTemplateTable').append(html);
        </script>
    }
    

    上面的代码在单击时添加了新的下拉列表,但是下拉列表没有预先填充数据,我做错了什么?

    0 回复  |  直到 6 年前
        1
  •  0
  •   Saharsh    6 年前

    您将需要在新控件中选择您希望对JavaScript方法可用的选项。有几种方法可以做到这一点,最简单的方法是将其隐藏在HTML页面的隐藏选择控件中。

    您的CSHTML:

    <h2>Create</h2>
    
    //Added the hidden HTML control here
        @Html.DropDownList("hidden-select", 
            new SelectList((IEnumerable) ViewData["TaskTemplateId"]), 
            null, new Dictionary<string, object>
                {
                    { "id", "task-template-names" },
                    { "style", "display: none" }
                })
    <h4>TemplateTask</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
    ////other things you were doing
    

    这将在HTML中呈现为一个预填充的隐藏模板,您可以通过单击按钮上的选项从中构建新的下拉列表。

        $("#btn_AddTaskTemplate").click(function () {
            var i = $(".TaskTemplate").length;
            var html = '';
            html += '<tr>';
            html += '<td><select type="text" name="TaskTemplateNames[' + i + '].TaskTemplateName" class="TaskTemplate">';
            html += document.querySelector("#task-template-names").innerHTML;
            html += '</select></td>';
            html += '<td></td></tr>';
        }); 
    

    我无法测试这段代码,因为这里的设置超出了我的范围,所以您可能需要稍微调整一下。如果你遇到任何困难的错误,请告诉我。