jquery-datatable:显示错误的“显示<total>条目的<range>”消息

时间:2016-08-30 18:03:24

标签: javascript jquery asp.net twitter-bootstrap datatables

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

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条记录,但计数显示为100的1到1.它应该是1到8的100。

enter image description here

观察:

如果您调整页面大小,计数似乎正确显示。我不想在每次抽奖后触发窗口调整大小事件。有没有api可以处理这个问题?

期望:

我该如何解决这个问题?任何建议都表示赞赏。

1 个答案:

答案 0 :(得分:1)

随着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',但希望至少可以提供一些有关您应该在下一步看到的内容或临时解决方法的信息。

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