javascript - jquery-数据表 : incorrect "Showing <range> of <total> entries" message is displayed

标签 javascript jquery asp.net twitter-bootstrap datatables

我正在开发一个 ASP.NET 网页,其中数据将显示在 jquery 数据表中。我能够显示数据,但是我面临的问题是,信息“显示条目”显示的值不正确。

fiddler : https://jsfiddle.net/8f63kmeo/9/

HTML:

    <table id="CustomFilterOnTop" class="display nowrap" width="100%"></table>  

JS

var Report4Component = (function () {
    function Report4Component() {
        //contorls
        this.customFilterOnTopControl = "CustomFilterOnTop"; //table id
        //data table object
        this.customFilterOnTopGrid = null;
        //variables
        this.result = null;
    }
    Report4Component.prototype.ShowGrid = function () {
        var instance = this;
        //add footer
        $('#' + instance.customFilterOnTopControl)
            .append('<tfoot><tr><th colspan="2" class="total-text">Total</th><th class="total-value"></th></tr></tfoot>');
        //create the datatable object
        instance.customFilterOnTopGrid = $('#' + instance.customFilterOnTopControl).DataTable({
            columns: [
                { data: "Description", title: "Desc" },
                { data: "Status", title: "Status" },
                { data: "Count", title: "Count" }
            ],
            "paging": true,
            scrollCollapse: true,
            "scrollX": true,
            scrollY: "300px",
            deferRender: true,
            scroller: true,
            dom: '<"top"Bf<"clear">>rt <"bottom"<"Notes">i<"clear">>',
            buttons: [
                {
                    text: 'Load All',
                    action: function (e, dt, node, config) {
                        instance.ShowData(10000);
                    }
                }
            ],
            initComplete: function (settings) {
                var api = this.api(settings);
                //now, add a second row in header which will hold controls for filtering. 
                $(api.table().header()).append('<tr role="row" id="FilterRow">' +
                    '<th>Desc</th>' +
                    '<th>Status</th>' +
                    '<th>Count</th>' +
                    '</tr>');
                //add input controls for filtering
                $('#FilterRow th', api.table().header()).each(function () {
                    var title = $('#' + instance.customFilterOnTopControl + ' thead th').eq($(this).index()).text();
                    $(this).html('<input type="text" onclick="return false" placeholder="Search ' + title + '" class="form-control" />');
                });
                //todo: refactor this code. this is for displaying the scrollbar below the tfoot instead of tbody
                //when multiple tables are present, use tablename.find to get the specific class object
                //this code is not tested with other options
                $('.dataTables_scrollBody').css({
                    'overflow-x': 'hidden',
                    'border': '0'
                });
                $('.dataTables_scrollFoot').css('overflow', 'auto');
                $('.dataTables_scrollFoot').on('scroll', function () {
                    $('.dataTables_scrollBody').scrollLeft($(this).scrollLeft());
                });
            },
            footerCallback: function (tfoot, data, start, end, display) {
                var api = this.api();
                if (instance.result == null || instance.result.Total == undefined) {
                    return;
                }
                $(api.column(2).footer()).html(instance.result.Total);
            }
        });
        $("div.Notes").html('<div class="alert alert-warning">This is a notes section part of the table dom.</div>');
    };
    Report4Component.prototype.BindEvents = function () {
        var instance = this;
        $("#FilterRow th input").on('keyup change', function () {
            instance.customFilterOnTopGrid
                .column($(this).parent().index() + ':visible')
                .search("^" + $(this).val(), true, false, true) //uses regular expression and checks only for starts with
                .draw();
        });
    };
    Report4Component.prototype.ShowData = function (limit) {
        if (limit === void 0) { limit = 100; }
        var instance = this;
        instance.customFilterOnTopGrid.clear(); //latest api function
        instance.result = instance.GetData(limit);
        instance.customFilterOnTopGrid.rows.add(instance.result.RecordList);
        instance.customFilterOnTopGrid.draw();
    };
    Report4Component.prototype.GetData = function (limit) {
        //structure of the response from controller method
        var resultObj = {};
        resultObj.Total = 0;
        resultObj.RecordList = [];
        for (var i = 1; i <= limit; i++) {
            resultObj.Total += i;
            var record = {};
            record.Description = "This is a test description of record " + i;
            record.Status = ["A", "B", "C", "D"][Math.floor(Math.random() * 4)] + 'name text ' + i;
            record.Count = i;
            resultObj.RecordList.push(record);
        }
        return resultObj;
    };
    return Report4Component;
}());
$(function () {
    var report4Component = new Report4Component();
    report4Component.ShowGrid();
    report4Component.BindEvents();
    report4Component.ShowData();
});
function StopPropagation(evt) {
    if (evt.stopPropagation !== undefined) {
        evt.stopPropagation();
    }
    else {
        evt.cancelBubble = true;
    }
}

问题:

在下面的快照中,您可以看到网格中显示了 8 条记录,但是计数显示为 1 到 1 of 100。它应该是 1 到 8 of 100。

enter image description here

观察:

如果调整页面大小,计数似乎会正确显示。我不想在每次绘制后触发窗口调整大小事件。有没有可用的API来处理这个问题?

期望:

我应该如何解决这个问题?如有任何建议,我们将不胜感激。

最佳答案

通过对 JSFiddle 的一些摆弄(呵呵),我想我已经发现了这个问题的原因。

问题摘要:

存在一些问题,滚动条不知道添加所有行(使用 rows.add() 而不是使用行初始化表格)增加了表格的物理尺寸,因此认为最初的 0 行表就是当前的大小。这会导致它错误地计算可见行数。 draw() 不会有帮助,因为它不会重新创建表,而只会重新创建数据,这是正确的。为滚动条提供的表格内部尺寸不正确。您决定在不完全销毁并重新创建表的情况下加载数据的方式可能无法修复此问题。

解决方案:

由于您在加载数据之前创建并加载表格/事件,因此滚动条不知道表格的 Y 尺寸已更改(该表格是用 0 行创建的,因此它认为没有空间超过 1)。我不太确定应该做什么来更新滚动条,但我找到了一个解决方案。如果您不喜欢这种解决方法,则必须检查在构建表期间加载数据的可能性。

参见this fiddle我所做的就是通过添加虚拟行来更改 HTML 表格:

<table id="CustomFilterOnTop" class="display nowrap" width="100%">
<tr><td>asdf</td><td>asdf</td><td>asdf</td></tr>
<tr><td>asdf</td><td>asdf</td><td>asdf</td></tr>
<tr><td>asdf</td><td>asdf</td><td>asdf</td></tr>
<tr><td>asdf</td><td>asdf</td><td>asdf</td></tr>
<tr><td>asdf</td><td>asdf</td><td>asdf</td></tr>
<tr><td>asdf</td><td>asdf</td><td>asdf</td></tr>
<tr><td>asdf</td><td>asdf</td><td>asdf</td></tr>
<tr><td>asdf</td><td>asdf</td><td>asdf</td></tr>
<tr><td>asdf</td><td>asdf</td><td>asdf</td></tr>
</table>

这会欺骗滚动条,让其相信还有 9 行的空间,这就是您最初拥有的行数。您基本上是将初始表格填充到您的 300px 定义中。

请注意,虽然表格的操作看起来完全相同,但它现在将显示正确的分页信息。请注意,当您初始化和加载表时,这些行将被销毁,因此它们只是一个填充物,以便滚动器知道需要更多行。

这非常“hack-y”,但希望它至少能提供一些关于您下一步应该关注的地方的见解,或者一个临时的解决方法。

更好的解决方案是在初始化时将数据加载到表中,无论如何,这是执行此操作的标准方法。

关于javascript - jquery-数据表 : incorrect "Showing <range> of <total> entries" message is displayed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39234241/

相关文章:

c# - 为什么在 SQL 查询中使用 MIN 时系统出现错误?

javascript - 单元测试编译的 JavaScript?

javascript - 如何使用 FileReader API javascript,仅 html/jquery 读取非常大的文件 .csv

javascript - Jquery获取选定td下的特定文本区域

c# - 是否可以使用匿名类型进行数据绑定(bind)?

javascript - 从 C# 代码获取 html 按钮/下拉文本

javascript - Node JS 如何检查现有 JSON 文件中是否已存在值

javascript - 简单的 Canvas 矩形与 Javascript 交互

javascript - CSS 显示 :none for responsive web design

javascript - 如何在 <div> 底部添加 "Back to top"链接是浏览器窗口比页面短,使用 jquery?