【问题标题】:ASP.NET Core 2.1 Populating dropdownlist created by jqueryASP.NET Core 2.1 填充由 jquery 创建的下拉列表
【发布时间】:2018-12-07 16:17:28
【问题描述】:

我有这个按钮,当单击它时,会创建一个包含多个下拉列表的新 div 行。如何从加载到我的视图中的视图模型中填充这些下拉列表?

@model App.Data.ViewModels.FilterDocumentsViewModel

<button type="button" class="btn btn-outline-secondary" data-toggle="collapse" data-target="#datatable-search-input-container-rowtwo" aria-expanded="false" aria-controls="datatable-search-input-container-rowtwo">
        <i class="fa fa-plus"></i>
</button>

$("#datatable-search-input-container-rowone-coltwo").on("click", "#add-row", function (e) {
    var htmlElements = "<div class='col-sm-10 row'>";
    htmlElements = htmlElements + "<div class='col-sm-3 search-spacing'>";
    htmlElements = htmlElements + "<label>Document Categories</label>";
    htmlElements = htmlElements + "<select class='form-control' name='CategoryId[]' asp-items='@Model.Categories'>Select Category</select>"
    htmlElements = htmlElements + "<label>Document Fields</label>";
    htmlElements = htmlElements + "<select class='form-control' name='FieldId[]' asp-items='@Model.DocumentFields'>Select Document Fields</select>"
    htmlElements = htmlElements + "</div>";
    htmlElements = htmlElements + "</div>";
    $(htmlElements).appendTo("#datatable-search-input-container-rowone-colone-sub");
    return false;
});

我上面的内容只是创建了一个空的下拉列表。另外,是否可以对将重新填充文档字段的文档类别进行 onchange?

编辑:基于@TetsuyaYamamotos 的答案是我所做的

部分视图:

@model App.Data.ViewModels.FilterDocumentsViewModel
<div class="col-sm-12 row">
    <div class="col-sm-3 search-spacing">
        <label>Document Categories</label>
        @Html.DropDownListFor(m => m.CategoryId, (SelectList)Model.Categories, "Select Category", new { @class = "form-control Categories" })
    </div>
    <div class="col-sm-3 search-spacing">
        <label>Document Fields</label>
        @Html.DropDownListFor(m => m.FieldId, (SelectList)Model.DocumentFields, "Select Field", new { @class = "form-control Fields" })
    </div>
    <div class="col-sm-3 search-spacing">
        <label for="Data">Data</label>
        <input type="text" id="Data" placeholder="Search" />
    </div>
</div>

jquery:

function refreshDropdown(Input) {
    $.ajax({
            url: "@Url.Action("GetFields", @ViewContext.RouteData.Values["controller"].ToString())",
            method: "POST",
            data: JSON.stringify(Input),
            contentType: "application/json",
            success: function (result) {
                $(".Fields").empty();
                $(".Fields").append("<option value>Select Field</option>");
                $.each(result.fields, function (key, value) {
                    $(".Fields").append("<option value="+value.Id+">"+value.Name+"</option>");
                });
            },
            error: function (error) {
                console.log(error);
            }
        });
}

$("#datatable-search-input-container").on("change", ".Categories", function (e) {
    console.log("changed");
    selected = $(".Categories").find(":selected").val();
    var form_data = selected;
    refreshDropdown(form_data);
    return false;
});

添加行:

$("#datatable-search-input-container-rowone-coltwo").on("click", "#add-row", function (e) {
    $.ajax({
        url: "@Url.Action("AddSearchFilterRow", @ViewContext.RouteData.Values["controller"].ToString())",
        method: "GET",
        contentType: "application/json",
        success: function (result) {
            $(result).appendTo("#datatable-search-input-container-rowone-colone-sub");
        },
        error: function (error) {
            console.log(error);
        }
    });
    return false;
});

剩下的唯一问题是唯一有效的 onchange 是主要的,而不是在更改时添加的 jquery

【问题讨论】:

  • 为什么不只添加部分视图并使用append() 来添加现有元素?请注意,asp-items 是 ASP.NET Core 辅助属性,它必须使用预定义的 select 标签在服务器端创建(它在客户端呈现为选项标签)。
  • @TetsuyaYamamoto 您的建议奏效了,但是如何解决 onchange 的第二个问题?

标签: javascript jquery asp.net asp.net-core


【解决方案1】:

ASP.NET Core MVC 标签助手的行为类似于@Html.DropDownListFor() 助手,它们都是在服务器端呈现的,应该像asp-for 服务器端属性一样对待。您需要使用包含要附加的元素的局部视图,并附有控制器操作方法来返回它,如下例所示:

SelectPartialView.cshtml

@model App.Data.ViewModels.FilterDocumentsViewModel

<div class='col-sm-10 row'>
   <div class='col-sm-3 search-spacing'>
       <label>Document Categories</label>
       <select class='form-control category' asp-for='CategoryId' asp-items='@Model.Categories'>Select Category</select>
       <label>Document Fields</label>
       <select class='form-control field' asp-for='FieldId' asp-items='@Model.DocumentFields'>Select Document Fields</select>
   </div>
</div>

控制器动作

public IActionResult GetSelectList()
{
    // do something
    return PartialView("SelectPartialView");
}

然后使用 AJAX 回调将部分视图元素附加到目标元素中:

$("#datatable-search-input-container-rowone-coltwo").on("click", "#add-row", function (e) {
    $.get('@Url.Action("GetSelectList", "ControllerName")', function (result) {
        $("#datatable-search-input-container-rowone-colone-sub").append(result);
    });
});

关于级联&lt;select&gt;标签助手,您需要在两个下拉列表中定义class选择器并使用AJAX填充选项列表:

$('.category').on('change', function() {
    $.ajax({
       type: 'GET',
       url: '@Url.Action("GetFields", "ControllerName")',
       data: { CategoryId: $(this).val() },
       success: function (result) {
           $('.field').empty();
           $.each(result, function (i, item) {
               // replace 'item.Value' and 'item.Text' from corresponding list properties into model class
               $('.field').append('<option value="' + item.Value + '"> ' + item.Text + ' </option>');
           });
       },
       error: function (xhr, status, err) {
           // error handling
       }
    });
});

控制器动作

public IActionResult GetFields(int CategoryId)
{
    // populate SelectListItem here
    return new JsonResult(list);
}

另一个级联&lt;select&gt;元素的例子可以在这里找到:

ASP.NET MVC Core Cascading DropDownList

【讨论】:

  • 我添加了一个编辑。你能看看我的代码哪里出错了吗?
【解决方案2】:

您可以从 viewmodel 获取数据到一个 javascript 对象中,然后使用 jquery 循环访问该数据

var modelCategories = @Html.Raw(Json.Encode(Model.Categories));
var modelDocumentFields =@Html.Raw(Json.Encode(Model.DocumentFields)); 
$("#datatable-search-input-container-rowone-coltwo").on("click", "#add-row", function (e) {
    var htmlElements = "<div class='col-sm-10 row'>";
    htmlElements = htmlElements + "<div class='col-sm-3 search-spacing'>";
    htmlElements = htmlElements + "<label>Document Categories</label>";
    htmlElements = htmlElements + "<select class='form-control' name='CategoryId[]'>;
    htmlElements += "<option>Select Category</option>";
    $.each(modelCategories, function(i,v){
       htmlElements += `<option value="${v.CategoryId}">${v.CategoryName}</option>`
    });

    htmlElements = htmlElements + "</select>";
    htmlElements = htmlElements + "<label>Document Fields</label>";
    htmlElements = htmlElements + "<select class='form-control' name='FieldId[]'>;
    htmlElements += "<option>Select Document Fields</option>";
    $.each(modelCategories, function(i,v){
       htmlElements += `<option value="${v.FieldId}">${v.FieldNameName}</option>`
    });
    htmlElements = htmlElements + "</select>";
    htmlElements = htmlElements + "</div>";
    htmlElements = htmlElements + "</div>";
    $(htmlElements).appendTo("#datatable-search-input-container-rowone-colone-sub");
    return false;
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-16
    • 2012-11-08
    相关资源
    最近更新 更多