简体   繁体   中英

Returning ViewComponent inside Bootstrap modal .NET Core 3.1 C#

I am bulding an ASP.NET Core MVC Application. (.NET Core 3.1)

On one of the views - Results.chtml (with huge amount of DB rows shown), I decided to display more details of each row on the Bootstrap modal popup.

So - each row in this view has a button that displays a modal with the appropriate data binded by button property. I am loading the ViewComponent to this modal body by use of 'on('show.bs.modal') and $.get() - I call the action in my controller and the action returns the ViewComponent .

A proper ViewComponent loads up, with all the data correctly fetched.The problem is:

Everything related to a jQuery DataTables plugin dissapeared from the modal. (When I was displaying it in the separate page - it worked perfectly)


What I tried to change

At first, I had the jQuery DataTables script loaded in this ViewComponent's .cshtml file, but it was behaving totally unexpectable. Once sorting and filtering options showed up, once not. I decided to change it and I moved jQuery DataTables scripts to the main view - Results.cshtml . Now: it doesn't work, but...the error saying that "dataTable() isn't recognized method" is not present in the JS console! It means that it loaded the DataTables' scripts successfully...

Where should I load DataTables scripts? They are now laoded in the Layout.cshtml file. Is it possible that the order of this loadings makes it impossible to use DataTables inside of the modal? Is it even the source of my problems

Crutial code parts

  1. Layout.cshtml 在此处输入图片说明

  2. Script section inside the Results.cshtml (with a moved fragment at the end - dataTables(...))

     $(function () { $(document).ajaxStart(function() { $("#loading").show(); }); $(document).ajaxStop(function() { $("#loading").hide(); }); $('#exampleModal').on('show.bs.modal', function (event) { var container = $("#receiptDetailsView"); var clickedRow = $(event.relatedTarget); var accountId = clickedRow.data('accountidvalue'); $.get("/Receipts/" + accountId, function (data) { container.html(data); }); }); $("#exampleModal").on("hidden.bs.modal", function () { $("#receiptDetailsView").html(""); }); $('#sortableReceiptsTable').dataTable({ "filter": true, "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]] }); });

  3. Modal markup in Results.cshtml 在此处输入图片说明

  4. Action called by AJAX get:

     [HttpGet("receipts/{accountId}")] public IActionResult ShowReceipts([FromRoute]string accountId) { // invokes the InvokeAsync method of ReceiptsViewComponent return ViewComponent("Receipts", accountId); }
  5. InvokeAsync Method inside of ViewComponent class:

     public async Task<IViewComponentResult> InvokeAsync(string accountId) { var allReceipts = await _cosmosDbService.GetReceiptsByAccountIdAsync(accountId); List<ReceiptViewModel> recVMs = allReceipts.Select(u => u.ToReceiptViewModel()).ToList(); return View("Receipts", recVMs); }

Thank You!

Here is a working demo , you could refer to:

Model:

public class Link
{
    public int Id { get; set; }
    public string Title { get; set; }

    public string Url { get; set; }
    public string Description { get; set; }

    public int CategoryId { get; set; }
    public Category Category { get; set; }
}
public class Category
{
    public int Id { get; set; }
    public string Title { get; set; }
    public int Order { get; set; }

    public ICollection<Link> Links { get; set; }
}

JS inMain view

@section Scripts
{
<script>
        $(function () {

            $(document).ajaxStart(function() {
              $("#loading").show();
            });

            $(document).ajaxStop(function() {
              $("#loading").hide();
            });

            $('#exampleModal').on('show.bs.modal', function (event) {
                var container = $("#receiptDetailsView");
                var clickedRow = $(event.relatedTarget);
                var accountId = clickedRow.data('accountidvalue');
                $.get("/Receipts/" + accountId, function (data){container.html(data);});

            });  

            $("#exampleModal").on("hidden.bs.modal", function () {
                $("#receiptDetailsView").html("");
            });
        });
</script>
}

View Component class

    public async Task<IViewComponentResult> InvokeAsync(string accountId)
    {
        var categoryId = Convert.ToInt32(accountId);
        var model = _context.Link.Where(l => l.CategoryId == categoryId).ToList();
        return View(model);
    }

Default view of view component

@model List<MVCDemo3_1.Models.Links.Link>

<div class="container">
<br />
<div style="width:90%; margin:0 auto;">
    <table id="sortableReceiptsTable" class="table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0">
        <thead>
            <tr>
                <th>Title</th>
                <th>Description</th>
                <th>action</th>
            </tr>
        </thead>
    </table>
</div>
</div>

<script type="text/javascript">
    $(document).ready(function () {
        $('#sortableReceiptsTable').DataTable({
            data: @Html.Raw(Json.Serialize(Model)),
            columns: [
                { 'data': 'title' },
                { 'data': 'description' },
                {
                    'data': 'id',
                    'render': function (data) {
                        {
                            return '<a  href="#" title="ویرایش" style="margin-left:10px" class="btn btn-success button"  onclick="openModal(' + data + ');"><i class="fa fa-edit"></i></a><a  href="#" title="حذف" style="margin-right:10px"  class="btn btn-danger button"  onclick="deleteUser(' + data + ')"><i class="fa fa-trash"></i></a>'
                        }
                    },
                }
            ]
        });
    });
</script>

Result: 在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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