如何在引导警报警告div而非警报框中显示jQuery Datatable错误

时间:2018-11-21 16:50:29

标签: javascript c# jquery datatables asp.net-core-mvc

我正在ASP.NET Core 2.1网站上工作,并且正在使用Datatables.net来显示从后端API检索到的记录列表。

我要解决的问题是,每当从后端API检索数据时发生错误时,我都希望该错误消息出现在与数据表相同页面的Bootstrap警报错误DIV中。

我看过https://datatables.net/forums/discussion/30033/override-default-ajax-error-behaviorEnable datatable warning alert,但是我对JavaScript的了解并不强,因此在确定如何实现此功能方面遇到一些困难。

当前,我在cshtml页面中设置了数据表,如下所示;

<script>

    jQuery(document).ready(function ($) {

        var table = $("#sitelist").DataTable({
            "processing": true,
            "serverSide": true,
            "filter": true,
            "orderMulti": false,
            "ajax": {
                "url": "/Sites/LoadData",
                "type": "POST",
                "datatype": "json"
            },
            "columnDefs": [
                { "orderable": false, "targets": 6 },
                { "className": "text-center", "targets": [4, 5] },
                {
                    "targets": [4, 5],
                    "createdCell": function(td, cellData, rowData, row, col) {
                        if (cellData) {
                            $(td).html('<i class="far fa-check-circle text-primary""></i>');
                        } else {
                            $(td).html('<i class="far fa-times-circle text-danger""></i>');
                        }
                    }
                }
            ],
            "columns": [
                { "data": "Id", "name": "Id", "autoWidth": true, "defaultContent": "" },
                { "data": "SiteName", "name": "SiteName", "autoWidth": true, "defaultContent": "" },
                { "data": "CompanyId", "name": "CompanyId", "autoWidth": true, "defaultContent": "" },
                { "data": "CompanyName", "name": "CompanyName", "autoWidth": true, "defaultContent": "" },
                { "data": "IsAdminSite", "name": "IsAdminSite", "autoWidth": true, "defaultContent": "" },
                { "data": "IsEnabled", "name": "IsEnabled", "autoWidth": true, "defaultContent": "" },
                {
                    "render": function (data, type, full, meta) { return `<a href="/sites/edit?id=${full.Id}"><i class="far fa-edit text-primary" title="Edit"></a>`; }
                }
            ],
            // From StackOverflow http://stackoverflow.com/a/33377633/1988326 - hides pagination if only 1 page
            "preDrawCallback": function (settings) {
                var api = new $.fn.dataTable.Api(settings);
                var pagination = $(this)
                    .closest('.dataTables_wrapper')
                    .find('.dataTables_paginate');
                pagination.toggle(api.page.info().pages > 1);
            }

        });

    });


</script>

这是我的SitesController类中的loaddata操作;

    public async Task<IActionResult> LoadData()
    {
        try
        {
            await SetCurrentUser();
            ViewData["Role"] = _currentRole;

            var draw = HttpContext.Request.Form["draw"].FirstOrDefault();
            var start = Request.Form["start"].FirstOrDefault();
            var length = Request.Form["length"].FirstOrDefault();
            var sortColumn = Request.Form["columns[" + Request.Form["order[0][column]"].FirstOrDefault() + "][name]"].FirstOrDefault();
            var sortColumnDirection = Request.Form["order[0][dir]"].FirstOrDefault();
            var searchValue = Request.Form["search[value]"].FirstOrDefault();
            var pageSize = length != null ? Convert.ToInt32(length) : 0;
            var skip = start != null ? Convert.ToInt32(start) : 0;
            var request = new SitesGetListRequest
            {
                OrderBy = SetOrderBy(sortColumn, sortColumnDirection),
                Filter = SetFilter(searchValue),
                PageNumber = (skip / pageSize) + 1,
                PageSize = pageSize
            };
            var tokenSource = new CancellationTokenSource();
            var token = tokenSource.Token;

            var endpoint = $"api/companies/{SetCompanyId()}/sites/filtered";
            var siteData = await _client.GetSiteListAsync(request, endpoint, token);
            if (siteData.Sites != null)
            {
                return Json(new
                {
                    draw,
                    recordsFiltered = siteData.Paging.TotalCount,
                    recordsTotal = siteData.Paging.TotalCount,
                    data = siteData.Sites.ToList()
                });
            }
            //TODO: Find a way to pass error to a Bootstrap alert-warning DIV rather than the jQuery (javascript) alert box
            var errorMessage = $"Http Status Code: {siteData.StatusCode} - {siteData.ErrorMessages.FirstOrDefault()}";
            return Json(new
            {
                data = "",
                error = errorMessage
            });

        }
        catch (Exception ex)
        {
            const string message = "An exception has occurred trying to get the list of Site records.";
            _logger.LogError(ex, message);
            throw;
        }
    }

目前,如果从API调用返回的对象中存在错误,我会向返回的json中的error属性传递一条消息,并在cshtml页面上显示为javascript警报弹出框,当我单击“确定”,数据表显示“未找到记录”,如下图所示;

Popup Alert on Error

和...

After popup alert is cleared.

我要的是使错误消息显示在cshtml页面顶部的bootstrap alert-danger div中。我不想让警报弹出窗口出现,我仍然希望数据表显示“未找到记录”。

我认为我正在寻找的内容已在Enable datatable warning alert ...

中进行了描述

使用禁用警报弹出窗口

$.fn.dataTable.ext.errMode = 'none';

并使用

将错误消息传递给BootStrap div
 $('#example')
.on( 'error.dt', function ( e, settings, techNote, message ) {
    console.log( 'An error has been reported by DataTables: ', message );
} )
.DataTable();

但不是

console.log( 'An error has been reported by DataTables: ', message );

使用类似

$("#error").html(MY ERROR MESSAGE HERE);

并将id =“ error”分配给引导div。

但是,我在弄清楚如何从SitesController中的loaddata方法触发Ajax调用以及如何正确地将错误事件添加到datatable脚本的开头时遇到麻烦。

在花更多的时间尝试解决这个问题之前,我想我应该把它放在SO上,看看是否有javascrit / jquery经验的人可以提供一些指导。

1 个答案:

答案 0 :(得分:0)

您可以将error属性添加到ajax调用中。最好的办法是使用fnServerData

    jQuery(document).ready(function ($) {

        var table = $("#sitelist").DataTable({
            "processing": true,
            "serverSide": true,
            "filter": true,
            "orderMulti": false,
            "sAjaxSource": "/Sites/LoadData",
            "fnServerData": function (sSource, aoData, fnCallback) {
                $.ajax({
                   "dataType": 'json',
                    "type": "GET",
                    "url": sSource,
                    "data": aoData,
                    "cache": false,
                     "success": function (data) {
                          fnCallback(data);                   
                      },
                     "error": function(error){
                        $("#error").html(error);
                     }
                });
             },
            "columnDefs": [
                { "orderable": false, "targets": 6 },
                { "className": "text-center", "targets": [4, 5] },
                {
                    "targets": [4, 5],
                    "createdCell": function(td, cellData, rowData, row, col) {
                        if (cellData) {
                            $(td).html('<i class="far fa-check-circle text-primary""></i>');
                        } else {
                            $(td).html('<i class="far fa-times-circle text-danger""></i>');
                        }
                    }
                }
            ],
            "columns": [
                { "data": "Id", "name": "Id", "autoWidth": true, "defaultContent": "" },
                { "data": "SiteName", "name": "SiteName", "autoWidth": true, "defaultContent": "" },
                { "data": "CompanyId", "name": "CompanyId", "autoWidth": true, "defaultContent": "" },
                { "data": "CompanyName", "name": "CompanyName", "autoWidth": true, "defaultContent": "" },
                { "data": "IsAdminSite", "name": "IsAdminSite", "autoWidth": true, "defaultContent": "" },
                { "data": "IsEnabled", "name": "IsEnabled", "autoWidth": true, "defaultContent": "" },
                {
                    "render": function (data, type, full, meta) { return `<a href="/sites/edit?id=${full.Id}"><i class="far fa-edit text-primary" title="Edit"></a>`; }
                }
            ],
            // From StackOverflow http://stackoverflow.com/a/33377633/1988326 - hides pagination if only 1 page
            "preDrawCallback": function (settings) {
                var api = new $.fn.dataTable.Api(settings);
                var pagination = $(this)
                    .closest('.dataTables_wrapper')
                    .find('.dataTables_paginate');
                pagination.toggle(api.page.info().pages > 1);
            }

        });

    });


</script>