45

I'm trying to display a friendly message (like "No records found, try again later") within the grid content, when there are no records in the database.

From what I've seen in the docs, there is currently no way of doing this for the grid content. It's only doable for the footer. You can see the example in this fiddle: http://jsfiddle.net/lav911/uNWXJ/

I've purposely misspelled the data route, in order to have an empty grid. To see it with content, simply comment / uncomment these lines:

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

Is there a clean way of achieving this ?

Zubzob
  • 2,653
  • 4
  • 29
  • 44

12 Answers12

73

Good news- this option is available now:

https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/configuration/norecords#noRecords

you can set message via kendo template:

noRecords: {
    template: "No data available on current page. Current page is: #=this.dataSource.page()#"
}

or via message option:

noRecords: true,
messages: {
    noRecords: "There is no data on current page"
}

default text is "No records available." when set noRecords: true only

xinthose
  • 3,213
  • 3
  • 40
  • 59
MarkosyanArtur
  • 1,359
  • 13
  • 10
22

You may use CSS: DEMO

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

with litlle style :

tbody:empty:before {
    content:'NO DATA';
    display:table-cell;
    padding:0.5em;
}
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • 1
    It's an interesting suggestion, but I'm not so sure how viable would a CSS solution be. Maybe I'll want to internationalize the app. – Zubzob May 06 '14 at 08:50
  • 1
    Internationalizing would still be possible with css.. just add a class to the page such as "EN" for english and then prefix your classes with the country class (.EN tbody:empty:before) – KingOfHypocrites Aug 06 '14 at 13:44
  • Very clever solution +vote, I like it and would use it, unfortunately won't support my situation where I need to support html / buttons etc – Josh Mc Feb 13 '15 at 01:27
  • You actually could use HTML data attributes to decouple the content message from the actual CSS. –  Dec 18 '15 at 20:05
  • 1
    This is handy because it will also support Kendo MVC, which apparently still lacks an equivalent to KendoUI's noRecords. – Tim Grant Sep 22 '16 at 02:47
  • I am not sure if this really works on heavy data loads or heavy calculations. Css should be triggered after records validation. This is just my thought. – Kurkula Nov 01 '18 at 17:28
16

I use the following when defining the grid:

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


The javascript function 'DisplayNoResultsFound' is defines as follows:

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>');
        }
    }
}

A running demo can be found here

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Stef Heyenrath
  • 9,335
  • 12
  • 66
  • 121
  • Exactly what I need. Beautifully explained with a nice demo. Thanks! – Zubzob May 09 '14 at 19:31
  • I'm uncertain if it is a difference in kendo versions, but with my grids I had to remove the ".k-grid-header" and .k-grid-content" from the selectors for the targeting to work. – Brandon Barkley Feb 17 '16 at 16:04
  • A few things... 1) a 'norecords' option is now available on the grid 2) no need to pass a jQuery selector $('#grid'), just pass `this` and it's a reference to the grid 3) then you just have to do `if (!this.dataSource.total()) { // append "no records" cell } – dmathisen Jun 07 '16 at 21:39
  • My answer is probably only valid for the version which is used in my demo. This is the last opensource version I believe. – Stef Heyenrath Jun 08 '16 at 16:08
7

Supported out-of-the-box in the 2015.2.805 release. http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#configuration-noRecords.template

pcl
  • 67
  • 1
  • 4
5

Firstly, you cannot fake an empty datasource just by giving an incorrect read url. This will just cause a read error and will never trigger any update on your grid's datasource, (ie. dataBound event will never happen). On the other hand, an empty datasource is still a valid datasource and will trigger the dataBound event.


Anyways, here is my solution. Firstly, to emulate an empty datasource, I have set the datasource like so:

    dataSource: []

Now, the proper way to check whether your grid is truly empty is to read the datasource itself. The others do it... in a more hacky way by reading html DOM. Please do NOT do this as you may have multiple pages, filters, etc... where the item is in the dataSource but not the DOM. Here is how you should do it:

if($("#grid").data("kendoGrid").dataSource.data().length===0){
    //do your stuff!
}

Now, when you read your datasource, the dataBound event is triggered every time. Thus, you should put the above code in the dataBound event. Check if grid dataSource is empty, and then fire a message to the user. Here is my full code for 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();
        }

    }
}

What is this crazy mess above? You'll notice that I am doing a lot of stuff with the variable mBox. This is simply an empty <div> I added on the html page with id msgBox, and I am using it to instantiate a kendoWindow to create the popup saying that there is no data.

You can find out more about kendoWindow here. So instead of using ugly alert boxes, I am just taking advantage of another part of kendo UI's widget library, which is customizable and controllable.

The if and else logic with the mBox simply handles subsequent calls to show the message. The first time, the kendoWindow has not been instantiated so it goes through the if clause. Subsequent calls with just reopen the window.

Give it a try :). You can click the next page buttons to verify that it will show the popup again. Here is a jsFiddle Demo.

gitsitgo
  • 6,589
  • 3
  • 33
  • 45
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>');
            }
        };
Mohammad Atiour Islam
  • 5,380
  • 3
  • 43
  • 48
3

On Grid Data Bound..

Add the following script to show Message.

 //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>');

        }
radu florescu
  • 4,315
  • 10
  • 60
  • 92
Shazhad Ilyas
  • 1,183
  • 8
  • 14
3

I know I'm late to the party but here's how I just did it. It's mostly copied from the TreeList's no data feature (I was annoyed that you didn't have the same thing with the standard grid). I made it into a prototype extension so it's automatically added to every grid. An option could also be added to make the message configurable.

// 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
};
Pluc
  • 2,909
  • 1
  • 22
  • 36
2

Can't you do something like this -

if(this.tbody.rows.length === 0) {
     alert('no records');
     return;
}

Or you are looking for something even cleaner something inbuilt in Kendo? I think, this is an issue still there in Kendo UI which hasn't been fixed yet See this - http://www.telerik.com/forums/empty-grid-norecords-template

Cute_Ninja
  • 4,742
  • 4
  • 39
  • 63
2

If your grid has detail grids (nested grids) then the above examples wont work on the nested grids. To ensure you apply this to all of your kendo grids you can do the following:

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();
            };
        });
    });
}

Then call this function after all of your content has been loaded, there is no need to add it to each grid individually.

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

if you wanted to change the message then add emptyMsg to your dataSource i.e.

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
}
Darren
  • 21
  • 3
2

Kendo grid No Data found 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">Sorry, no data :(</td></tr>');
}

};

1

Not sure what was the exact version this question was asked, but in my case none of the above solutions worked.

I used the following one:

config : {
     noRecords: {
          message: "No records found."
     },
}
radu florescu
  • 4,315
  • 10
  • 60
  • 92