Setting Telerik’s HTML5 Kendo UI Grid’s Height to 100% when Binding to Remote Data

Update 06/24/2013 – Telerik, Kendo UI Team (Dimo Dimov) has reached out to me (see block quote below), and has taken the time to provide the best practice on how to handle the 100% height for the Kendo UI Web Grid http://jsfiddle.net/dimodi/SDFsz/, please use this approach vs. the approach in the blog post, thanks for visiting…!

I am Dimo Dimov from the Telerik / Kendo UI team. A client recently provided this page as an example of a 100% high Kendo UI Grid. I reviewed the code and the comments and it seems that a lot of people would benefit from some clarifications how percentage heights work.

First of all, please take a look at the following jsFiddle demo, which is similar to the jsFiddle demo above, but is better and simpler in a couple of ways:

http://jsfiddle.net/dimodi/SDFsz/

The example discussed in this blog post is also similar, but has one drawback – it uses hard-coded “magic numbers” in order to workaround the presumably disobeyed web standard requirement regarding percentage heights. Let me explain this requirement in more detail using the new jsFiddle demo as a starting point.

We have the following DOM tree:

First of all, the rule of thumb is that an element with a percentage height should have a parent with explicit height. The rule applies recursively until an element with a pixel height is reached, or until the HTML element is reached, which should have a height as well. This is because percentage heights are always calculated with regard to the set height of the parent element.

Now let’s get back to our example. The Grid should be 100% high and we set such a style. This implies that the parent element () should have an explicit pixel or percentage height. It has none of those, so we apply a 100% height to it. Now we go up and reach the element. It should also have an explicit height, otherwise the and Grid percentage heights will be ignored. So we apply a 100% height to the element as well. Now we have three nested elements that are 100% high and these heights start working. Since 100% high elements should not have vertical borders, margins or paddings, we remove those, as shown in the jsFiddle demo.

With more complex DOM trees the logic is the same – you start with the given element that needs to expand and go up the tree and apply 100% height styles (or any other values) until an element with a pixel height is reached, or until the element is reached. If you have a sequence of nested 100% high elements, removing just one of those heights will cause all the others to stop working. The most common reason for 100% heights to not work is that there is an element with no height, which breaks the sequence of 100% high nested elements.

One thing more to keep in mind is that 100% high elements cannot have siblings, otherwise they will overflow their parent.

This blog post uses the opposite approach compared to the one I describe – the height is calculated from “the outside to the inside”. The only case, in which such an approach makes sense is when the Grid or some of its parent elements have siblings, so 100% heights cannot be applied that easily. Also, this approach can work with parent elements with missing heights, because it relies on the height of the browser window, but I would not recommend this appoach.

Thank you.

I’ve been somewhat wresting with how to set the KendoUI Grid’s height to 100% so that it could fill a user’s screen as much as possible so that it would only show it’s vertical scrollbar only when absolutely needed e.g. when a user’s actual browser real estate is shorter in height than the grid’s content (rows). Those of us that have wired up the Grid binding to remote data e.g. OAuth, JSON, etc.. have been required to explicitly set the Grid’s height.

I’ve visited the Telerik’s forums and googled, unfortunately no working real solution, hence this blog post.

http://www.kendoui.com/forums/ui/grid/dynamic-grid-height.aspx
http://jsfiddle.net/dimodi/4eNu4/33/

If we don’t set the height, the Grid will render as follows:

Note: No height was set for the Grid configuration and it appears as if the Grid has no records when indeed our service is returning records it’s just the Grid’s content div’s height is 0px because we did not explicity set the height, and if we try to set it to a percent 100%, the Grid does not render at all.


    $(document).ready(function () {
        $("#grid").kendoGrid({
            dataSource: {
                type: "json",
                serverPaging: true,
                pageSize: 5,
                transport: { read: { url: "Products/GetAll", dataType: "json"} },
                schema: { data: "Products", total: "TotalCount" }
            },
            pageable: true,
            columns: [
                    { field: "ProductId", title: "ProductId" },
                    { field: "ProductType", title: "ProductType" },
                    { field: "Name", title: "Name" },
                    { field: "Created", title: "Created" }
                ],
            detailTemplate: kendo.template($("#template").html()), detailInit: detailInit,
            dataBound: function () {
                this.expandRow(this.tbody.find("tr.k-master-row").first());
            }
        });
    });

If explicity set the height, the Grid will render as follows:

Note: Line 10, where we are explicitly setting the height, however notice that we have plenty of screen real estate under grid, and if we could get the Grid could take advantage of that empty space we wouldn’t need the scrollbar.


    $(document).ready(function () {
        $("#grid").kendoGrid({
            dataSource: {
                type: "json",
                serverPaging: true,
                pageSize: 5,
                transport: { read: { url: "Products/GetAll", dataType: "json"} },
                schema: { data: "Products", total: "TotalCount" }
            },
            height: 500,
            pageable: true,
            columns: [
                    { field: "ProductId", title: "ProductId" },
                    { field: "ProductType", title: "ProductType" },
                    { field: "Name", title: "Name" },
                    { field: "Created", title: "Created" }
                ],
            detailTemplate: kendo.template($("#template").html()), detailInit: detailInit,
            dataBound: function () {
                this.expandRow(this.tbody.find("tr.k-master-row").first());
            }
        });
    });

So a quick way we can remedy this is to calculate how much vertical space we have and set the maximum height of the Grid ourselves. By taking the Html document height and offsetting it factoring in our layout e.g. header and footer.


    $(document).ready(function () {
        $("#grid").kendoGrid({
            dataSource: {
                type: "json",
                serverPaging: true,
                pageSize: 5,
                transport: { read: { url: "Products/GetAll", dataType: "json"} },
                schema: { data: "Products", total: "TotalCount" }
            },
            height: $(document).height() - 350,
            pageable: true,
            columns: [
                    { field: "ProductId", title: "ProductId" },
                    { field: "ProductType", title: "ProductType" },
                    { field: "Name", title: "Name" },
                    { field: "Created", title: "Created" }
                ],
            detailTemplate: kendo.template($("#template").html()), detailInit: detailInit,
            dataBound: function () {
                this.expandRow(this.tbody.find("tr.k-master-row").first());
            }
        });
    });

Great! Our Grid now renders and takes up the full vertical real estate within the browser on the intial load

Last Problem, now when we resize the browswer, the Grid is NOT automatically resizing itself

No problem, we will add a method for resizing the grid and wire this up to the browser resize event with jQuery.


  $(document).ready(function () {
        $("#grid").kendoGrid({
            dataSource: {
                type: "json",
                serverPaging: true,
                pageSize: 5,
                transport: { read: { url: "Products/GetAll", dataType: "json"} },
                schema: { data: "Products", total: "TotalCount" }
            },
            height: 250,
            pageable: true,
            columns: [
                    { field: "ProductId", title: "ProductId" },
                    { field: "ProductType", title: "ProductType" },
                    { field: "Name", title: "Name" },
                    { field: "Created", title: "Created" }
                ],
            detailTemplate: kendo.template($("#template").html()), detailInit: detailInit,
            dataBound: function () {
                this.expandRow(this.tbody.find("tr.k-master-row").first());
            }
        });
    });
    
    function resizeGrid() {
        var gridElement = $("#grid");
        var dataArea = gridElement.find(".k-grid-content");

        var newGridHeight = $(document).height() - 350;
        var newDataAreaHeight = newGridHeight - 65;

        dataArea.height(newDataAreaHeight);
        gridElement.height(newGridHeight);

        $("#grid").data("kendoGrid").refresh();
    }
    
    $(window).resize(function () {
        resizeGrid();
    });

Now, when grid first loads

Note: Looks great, Grid occupies all the available vertical real estate it can

When user resizes Grid (maximizes browser vertically)

Note: Still Looks great, Grid automatically resizes itself to occupy the new vertical space within the browser after the resize.

Happy Coding…!

Download sample application:

https://skydrive.live.com/redir.aspx?cid=949a1c97c2a17906&resid=949A1C97C2A17906!375&parid=949A1C97C2A17906!361

About these ads

34 thoughts on “Setting Telerik’s HTML5 Kendo UI Grid’s Height to 100% when Binding to Remote Data

  1. you are truly a just right webmaster. The web site loading velocity is
    incredible. It kind of feels that you’re doing any distinctive trick.
    Also, The contents are masterwork. you’ve performed
    a excellent activity in this topic!

  2. My question is always why can’t this be handled out of the box. Width is very easy to program, but whenever height comes into question it is almost always much much harder to program. In reality it’s a very common scenario to want to have a grid height fill a specified container. So “modern web grid technology” (*cough* *cough* ‘Telerik –> KendoUI Web’*), add functionality out of the box for common scenarios. Much obliged.

    • Joe, I think this (Kendo Widgets built-in responsiveness behavior) maybe addressed with their latest release, they demo’d something along these lines in their latest keynote release webinar earlier this week.

  3. There are many more out there than you think there are. Depending on
    your source, diet cycles with HCG injections or
    sublingual drops can cost upwards of $800 or more. The
    Gluten-Free Diet will teach you how to eat in a way that will protect you from an allergy to gluten.

  4. As an inventor he helped to develop most of what became modern electrical systems.

    It is said that people can get as much energy as they want from the Nikola Tesla generator
    especially when it comes to supporting the household.

    Like something out of a bad movie script, it
    just so happened that a murderer was about to be executed in the first electric chair at New York’s Auburn State Prison.

  5. P.S. It seems that tags are not allowed in comments. The missing DOM tree above should read:

    [html]
    [body]
    [div id="grid"]

    [/div]
    [/body]
    [/html]

  6. Hello,

    I am Dimo Dimov from the Telerik / Kendo UI team. A client recently provided this page as an example of a 100% high Kendo UI Grid. I reviewed the code and the comments and it seems that a lot of people would benefit from some clarifications how percentage heights work.

    First of all, please take a look at the following jsFiddle demo, which is similar to the jsFiddle demo above, but is better and simpler in a couple of ways:

    http://jsfiddle.net/dimodi/SDFsz/

    The example discussed in this blog post is also similar, but has one drawback – it uses hard-coded “magic numbers” in order to workaround the presumably disobeyed web standard requirement regarding percentage heights. Let me explain this requirement in more detail using the new jsFiddle demo as a starting point.

    We have the following DOM tree:

    First of all, the rule of thumb is that an element with a percentage height should have a parent with explicit height. The rule applies recursively until an element with a pixel height is reached, or until the HTML element is reached, which should have a height as well. This is because percentage heights are always calculated with regard to the set height of the parent element.

    Now let’s get back to our example. The Grid should be 100% high and we set such a style. This implies that the parent element () should have an explicit pixel or percentage height. It has none of those, so we apply a 100% height to it. Now we go up and reach the element. It should also have an explicit height, otherwise the and Grid percentage heights will be ignored. So we apply a 100% height to the element as well. Now we have three nested elements that are 100% high and these heights start working. Since 100% high elements should not have vertical borders, margins or paddings, we remove those, as shown in the jsFiddle demo.

    With more complex DOM trees the logic is the same – you start with the given element that needs to expand and go up the tree and apply 100% height styles (or any other values) until an element with a pixel height is reached, or until the element is reached. If you have a sequence of nested 100% high elements, removing just one of those heights will cause all the others to stop working. The most common reason for 100% heights to not work is that there is an element with no height, which breaks the sequence of 100% high nested elements.

    One thing more to keep in mind is that 100% high elements cannot have siblings, otherwise they will overflow their parent.

    This blog post uses the opposite approach compared to the one I describe – the height is calculated from “the outside to the inside”. The only case, in which such an approach makes sense is when the Grid or some of its parent elements have siblings, so 100% heights cannot be applied that easily. Also, this approach can work with parent elements with missing heights, because it relies on the height of the browser window, but I would not recommend this appoach.

    Thank you.

  7. Hi are using WordPress for your blog platform?
    I’m new to the blog world but I’m trying to get started and create my own.

    Do you require any coding knowledge to make your own blog?
    Any help would be greatly appreciated!

    • I’m using WordPress and no, there is no coding knowledge and/or experience required to start blogging, good luck!

  8. Nice post. Was struggling with this issue for a bit one afternoon. Sizing the dataArea of the grid was the missing piece. Thanks

  9. hi frends,

    This is very nice post n very help full.
    I am using $(document). height () -350, to get 100%, height and its working fine , but the problem is when i am changing the arabic version ( changing direction to right to left of grid ) this is not working .

    Many Thanks for any help.

    • Hi Suman,

      Unfortunately, I have never tried to change which side the paging is rendered on. You will most likely end up working with the Kendo UI Grid CSS in order to make this happen.

    • Hi Le,

      Thanks for your reply, in arabic mode kendo ui grid is changing to right to left direction perfectly, but the auto height is not working . its giving extra height more that the window size.

      note : am using this code in kendo ui grid asp.net mvc (in html its working fine )

      Thanks
      Suman

  10. Is there a way to adjust the pageSize so more items are shown to fill the available height of the grid? You hard-code 5, leaving a mostly empty grid, even though the grid itself fills the browser window. So data is still being shown unoptimized for the available screen real estate. Thanks!

    • Hi David,

      I’m not sure I understand you question, you can just change the 5 to an integer that has a higher value to show more items in the Kendo UI Grid.

    • Hi Long, what I want to do is set the pageSize to whatever number is required to entirely fill the grid with items. If the browser window window is maximized, and with your code, the grid is also resized to fill the browser, then there might be enough room in the grid for 58 items, and so I would set pageSize to 58 when the browser window is resized. Thanks!

  11. Really helpful post. One question though. As we can see in the picture http://lelong37.files.wordpress.com/2012/03/2-28-2012-2-13-06-pm.png, the table doesn’t seem to be ending(bottom horizontal line after 5th row is missing.). Could anyone throw some light on how to fix this. Ideally I would like to see the grid with alternate rows colored, filling all the available space of the table body. Here it is only 5 rows filled with alternate colors. Thanks in advance.

  12. Use this for better results.
    function resizeGrid() {
    var gridElement = $(“#grid”);
    var newGridHeight = $(document).height() – 350;
    gridElement.height(newGridHeight);

    gridElement .data(“kendoGrid”)._thead();
    }

  13. Le

    Just been revisiting my code, and it will not work properly on the Kendoui tab strip unless you exclude the refresh statement. Updated code below:

    // event handler for select
    var onSelect = function (e) {
    //refresh the supplier grid to make sure it renders properly.
    var gridElement = $(“#Supplier”);
    var dataArea = gridElement.find(“.k-grid-content”);
    //I’m using a fixed height for the tabstrip size
    var newGridHeight = 320; //$(document).height() – 350;
    //The new grid height below allows the scroll bar to render correctly when
    //using paging and scrolling on the grid.
    var newDataAreaHeight = newGridHeight – 83; //newGridHeight – 65;
    dataArea.height(newDataAreaHeight);
    gridElement.height(newGridHeight);
    //$(“#Supplier”).data(“kendoGrid”).refresh();
    };

    // attach select event handler during initialization
    var tabStrip = $(“#tabStrip”).kendoTabStrip({
    select: onSelect
    });

  14. Le

    Thank you so much. Spent hours trying to sort this out, until I reached your post. Also helped me to solve the rendering issues with multiple grids on tabstrip. Here’s my code to assist people having the same problem which uses the Onselect method of the tabstrip:

    // event handler for select
    var onSelect = function (e) {

    //refresh the supplier grid to make sure it renders properly.
    var gridElement = $(“#Supplier”);
    var dataArea = gridElement.find(“.k-grid-content”);
    //I’m using a fixed height for the tabstrip size
    var newGridHeight = 220; //$(document).height() – 350;
    //The new grid height below allows the scroll bar to render correctly when
    //using paging and scrolling on the grid.
    var newDataAreaHeight = newGridHeight – 83; //newGridHeight – 65;
    dataArea.height(newDataAreaHeight);
    gridElement.height(newGridHeight);
    $(“#Supplier”).data(“kendoGrid”).refresh();

    };

    // attach select event handler during initialization
    var tabStrip = $(“#tabStrip”).kendoTabStrip({
    select: onSelect
    });

  15. Hi Le,

    Thanks for this. I really appreciate you sharing your expertise, and I learned a lot more from your code and style than *just* how to set the height.

    Best wishes

    Mike

Please Leave a Reply or Tweet me @LeLong37...!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s