简体   繁体   English

jQuery创建的ASP.NET Core 2.1填充下拉列表

[英]ASP.NET Core 2.1 Populating dropdownlist created by jquery

I have this button that when clicked, creates a new div row that contains several dropdowns. 我有这个按钮,当单击该按钮时,将创建一个包含多个下拉列表的新div行。 How can I populate those dropdowns from the viewmodel that is loaded into my view? 如何从加载到我的视图的viewmodel中填充这些下拉菜单?

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

What I have above just creates an empty dropdown list. 我上面的内容只创建了一个空的下拉列表。 Also, is it possible to do an onchange for Document Categories that will repopulate Document Fields? 另外,是否可以对文档类别进行onchange,以重新填充文档字段?

EDIT: Based on @TetsuyaYamamotos answer here is what I made 编辑:基于@TetsuyaYamamotos的答案,这就是我所做的

PartialView: PartialView:

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

Adding Rows: 添加行:

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

The only issue left is that the only onchange that works is the main one and not the jquery added on changes 剩下的唯一问题是,唯一起作用的onchange是主要变量,而不是更改时添加的jquery

You can get the data from viewmodel into a javascript object and Loop through that data using jquery 您可以将数据从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;
});

The ASP.NET Core MVC tag helper behavior is similar to @Html.DropDownListFor() helper, they're both rendered server-side and should be treated like asp-for server-side attribute. ASP.NET Core MVC标记帮助程序的行为类似于@Html.DropDownListFor()帮助程序,它们@Html.DropDownListFor()现在服务器端,应将其视为asp-for服务器端属性。 You need to use partial view containing elements to append, accompanied by a controller action method to return it like below example: 您需要使用包含要追加的元素的局部视图,并伴随一个控制器操作方法来返回它,如下例所示:

SelectPartialView.cshtml 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>

Controller Action 控制器动作

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

Then use AJAX callback to append partial view elements into target element: 然后使用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);
    });
});

Regarding cascading <select> tag helper, you need to define class selector into both dropdowns and use AJAX to populate option list: 关于级联的<select>标记帮助器,您需要在两个下拉列表中定义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
       }
    });
});

Controller Action 控制器动作

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

Another example of cascading <select> element can be found here: 级联<select>元素的另一个示例可以在这里找到:

ASP.NET MVC Core Cascading DropDownList ASP.NET MVC核心级联DropDownList

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM