当Kendo表格为空时,在其中显示一条消息

45

我正在尝试在网格内容中显示友好的消息(例如 "未找到记录,请稍后重试"),当数据库中没有记录时。

根据我在文档中所看到的,目前无法对网格内容执行此操作。 只有页脚可以实现。 您可以在此fiddle中查看示例:http://jsfiddle.net/lav911/uNWXJ/

我故意拼错了数据路由,以便使网格为空。 要查看带有内容的网格,请注释/取消注释这些行:

transport: {
            // read: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Customers"
            read: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Customerss"
        },

有没有一种清晰的方法来实现这个?

12个回答

73

22

您可以使用 CSS:DEMO

tbody:empty:before {
    content:'NO DATA';
}

简单样式

tbody:empty:before {
    content:'NO DATA';
    display:table-cell;
    padding:0.5em;
}

1
这是一个有趣的建议,但我不确定采用CSS解决方案的可行性有多高。也许我想要国际化应用程序。 - Zubzob
1
国际化仍然可以通过 CSS 实现。只需在页面上添加一个类别,如“EN”代表英文,然后将您的类别前缀设置为该国家类别(例如,.EN tbody:empty:before)。 - KingOfHypocrites
非常聪明的解决方案 +1,我喜欢它并会使用它,但不幸的是它无法支持我需要支持 HTML / 按钮等的情况。 - Josh Mc
实际上,您可以使用HTML数据属性来将内容消息与实际的CSS分离。 - user677526
1
这很方便,因为它还支持Kendo MVC,显然仍缺少与KendoUI的noRecords相当的功能。 - Tim Grant
我不确定这是否适用于大量数据负载或大量计算。CSS 应在记录验证后触发。这只是我的想法。 - Kurkula

16

在定义网格时,我使用以下内容:

$('#grid').kendoGrid({
    dataSource: employeeDataSource,
    dataBound: function () {
        DisplayNoResultsFound($('#grid'));
},


JavaScript函数'DisplayNoResultsFound'定义如下:

function DisplayNoResultsFound(grid) {
    // Get the number of Columns in the grid
    var dataSource = grid.data("kendoGrid").dataSource;
    var colCount = grid.find('.k-grid-header colgroup > col').length;

    // If there are no results place an indicator row
    if (dataSource._view.length == 0) {
        grid.find('.k-grid-content tbody')
            .append('<tr class="kendo-data-row"><td colspan="' + colCount + '" style="text-align:center"><b>No Results Found!</b></td></tr>');
    }

    // Get visible row count
    var rowCount = grid.find('.k-grid-content tbody tr').length;

    // If the row count is less that the page size add in the number of missing rows
    if (rowCount < dataSource._take) {
        var addRows = dataSource._take - rowCount;
        for (var i = 0; i < addRows; i++) {
            grid.find('.k-grid-content tbody').append('<tr class="kendo-data-row"><td>&nbsp;</td></tr>');
        }
    }
}

可以在这里找到一个运行演示。


正是我所需要的。讲解得非常清晰,演示也很好。谢谢! - Zubzob
我不确定是kendo版本的差异,但是对于我的网格,我必须从选择器中删除“.k-grid-header”和“.k-grid-content”,以使目标起作用。 - Brandon Barkley
几件事情......1)现在网格上有一个“norecords”选项 2)不需要传递jQuery选择器$("#grid"),只需传递this,它是对网格的引用 3)然后您只需要执行if(! this.dataSource.total()){//添加“无记录”单元格} - dmathisen
我的答案可能只适用于我演示中使用的版本。我相信这是最后一个开源版本。 - Stef Heyenrath

7

5

enter image description here

 // Kendo Grid
         dataSource: dataSource,
         dataBound:gridDataBound,



//No data in the grid show message
        function gridDataBound(e) {
            var grid = e.sender;
            if (grid.dataSource.total() == 0) {
                var colCount = grid.columns.length;
                $(e.sender.wrapper)
                    .find('tbody')
                    .append('<tr class="kendo-data-row"><td colspan="' + colCount + '" class="no-data">There is no data to show in the grid.</td></tr>');
            }
        };

grid.dataSource.total() == 0 应该改为 grid.dataSource._data.length === 0 - Thomas.Benz

5
首先,您无法通过提供错误的读取URL来伪造空数据源。这只会导致读取错误,并且永远不会触发网格数据源的任何更新(即,dataBound事件永远不会发生)。另一方面,空数据源仍然是有效的数据源,将会触发dataBound事件。

无论如何,这是我的解决方案。首先,为了模拟一个空数据源,我已经设置了数据源,如下所示:

    dataSource: []

现在,检查网格是否真正为空的正确方法是读取数据源本身。其他人会通过读取HTML DOM的方式进行更加hacky的操作。请不要这样做,因为您可能有多个页面、过滤器等等,在数据源中存在但不在DOM中的项目。以下是正确的做法:
if($("#grid").data("kendoGrid").dataSource.data().length===0){
    //do your stuff!
}

现在,每次读取数据源时都会触发dataBound事件。因此,您应该将上述代码放在dataBound事件中。检查网格数据源是否为空,然后向用户发送一条消息。这是我的完整dataBound代码。
dataBound: function (e) {
    var grid = $("#grid").data("kendoGrid");
    var mBox = $("#msgBox");
    if (grid.dataSource.data().length === 0) {
        if (!mBox.data("kendoWindow")) {
            mBox.kendoWindow({
                actions: ["Close"],
                animation: {
                    open: {
                        effects: "fade:in",
                        duration: 500
                    },
                    close: {
                        effects: "fade:out",
                        duration: 500
                    }
                },
                modal: true,
                resizable: false,
                title: "No items",
                width: 400
            }).data("kendoWindow").content("<p>No contacts available. Please try again later.</p>").center().open();
        } else {
            mBox.data("kendoWindow").content("<p>No contacts available. Please try again later.</p>").open();
        }

    }
}

上面这一堆是什么鬼?你会注意到我在使用变量 mBox 做很多事情。这只是一个空的 <div>,我在html页面上添加了id为msgBox,我正在使用它来实例化一个 kendoWindow 来创建弹出窗口,告诉用户没有数据。
你可以在这里了解更多关于kendoWindow。所以,我不再使用丑陋的警报框,而是利用 kendo UI 的另一个部分 - 可自定义和可控制的小部件库。 ifelse 逻辑与 mBox 简单处理后续调用以显示消息。第一次,kendoWindow 尚未被实例化,因此它通过 if 子句。随后的调用将只重新打开窗口。

试一试 :). 您可以点击下一页按钮以验证它会再次显示弹出窗口。这里是一个 jsFiddle演示


看起来就是我需要的,我今天会测试一下。 - Zubzob

3
我知道我来晚了,但这是我刚刚做的方法。它大多数是从TreeList的无数据功能复制的(我很生气你在标准网格中没有相同的东西)。我将其转化为原型扩展,因此自动添加到每个网格中。还可以添加选项以使消息可配置。
// Replace the grid content with a status message (Can be reused for data errors if you want to show "Request failed [Reload]" or something like that.
kendo.ui.Grid.prototype._showStatus = function (message) {
    var status = this.content.find(".k-status");

    if (!status.length) {
        status = $("<div class='k-status' />").appendTo(this.content.closest(".k-grid-content"));
    }

    status.html(message);
};

// Put back the grid content instead of the status message
kendo.ui.Grid.prototype._hideStatus = function () {
    this.content.find(".k-status").remove();
};

// Keep the original render function so we can call it int our override
kendo.ui.Grid.prototype.__renderContent = kendo.ui.Grid.prototype._renderContent;

// Override the render function
kendo.ui.Grid.prototype._renderContent = function (data, colspan, groups) {
    this.__renderContent(data, colspan, groups);
    if (data.length)
        this._hideStatus();
    else
        this._showStatus("No data."); // Could also add an option for that text so you can choose the message in a grid config
};

3
在网格数据绑定时... 添加以下脚本以显示消息。
 //ondatabound on user assginment grid grid
    function onUserAssignGridDataBound(e) {

        //Get the number of Columns in the grid
        var colCount = $("#UserAssignGrid").find('.k-grid-header colgroup > col').length;

        //If There are no results place an indicator row
        if ($("#UserAssignGrid").data("kendoGrid").dataSource._view.length == 0) {
            $("#UserAssignGrid").find('.k-grid-content tbody')
                .append('<tr class="kendo-data-row"><td colspan="' +
                    colCount +
                    '" style="text-align:center; padding-top:10px;background-color:#AFE4FA"><b>No Results Found!</b></td></tr>');

        }

2

如果您的网格具有详细网格(嵌套网格),则上述示例将无法在嵌套网格上工作。为确保将此应用于您所有的kendo网格,您可以执行以下操作:

function kendoEmptyGridFix() {
    $("[data-role='grid']").each(function() {
        $(this).data("kendoGrid").bind('detailInit', function(e) {
            kendoEmptyGridFix();
        });
        $(this).data("kendoGrid").bind('dataBound', function(e) {
            var colCount = this.table.find("tHead tr th").length;
            if ($(this)[0].dataSource._view.length == 0) {
                var msg = ($(this)[0].dataSource.options.emptyMsg == undefined ? "No Results Found!" : $(this)[0].dataSource.options.emptyMsg);
                this.table.find('tbody').html('<tr class="kendo-data-row"><td colspan="' + colCount + '" style="text-align:center; padding-top:20px; padding-bottom:20px;"><div class="k-empty-grid-row">' + msg + '</div></td></tr>');

                // optional to hide pager section
                this.table.parent().find('.k-grid-pager').hide();
            };
        });
    });
}

当您的所有内容加载完成后,请调用此函数,无需将其添加到每个网格中。

$(document).ready(function () {
    kendoEmptyGridFix();
});

如果你想改变消息,那么请将emptyMsg添加到你的数据源中,例如:

dataSource: {
    transport: {
        read: {
            url: "/getItems/" + e.data.id,
            dataType: "xml"
        }
    },
    emptyMsg: 'There are currently no items available', 
    schema: {
        type: "xml",
        data: "/a/b",
        model: {
            fields: {
                "id": "id/text()",
                "status": "status/text()"
            }
        }
    },
    pageSize: 20
}

2
你能不能做这样的事情——
if(this.tbody.rows.length === 0) {
     alert('no records');
     return;
}

或者您正在寻找更加简洁的东西,即Kendo内置的内容?我认为,在Kendo UI中仍存在这个问题,尚未得到解决。请参见此处 -http://www.telerik.com/forums/empty-grid-norecords-template


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接