Search code examples
javascriptjquerycsskendo-uikendo-scheduler

How to correctly set a max-height on Kendo Scheduler?


I am wondering if anyone has an idea on how to achieve the following behavior with the Kendo Scheduler:

I want the height of the scheduler to be the height of its contents UNTIL it reaches the height of the browser (which I already have calculated), then have that as far as it goes and become scrollable.

Right now, I just set the height to the height of the browser, but this causes views like the timeline views and when showing only business hours (which are all much shorter than other views) to have extra unneeded white space underneath it because the scheduler is still the height of the browser window.

I have kind of achieved this by setting the max-height of my that I initialize as the scheduler to the browser height. The only issue with this, is that it makes the whole scheduler scrollable (including the header with the date navigation tools, which I don't want). I only want the content under the header to be scrollable.


Solution

  • Have a look at the DOM. You'll notice that the scheduler's content gets rendered within a <table> separated from the header.

    Technically, you could wrap a <div> around the widget's table and set it's CSS-property height or max-height to the desired height and overflow-y to scroll or auto. This way, you could achieve what you want.

    Have a look at the following code-snippet. It should do the trick:

    $("#scheduler > table.k-scheduler-layout").wrap("<div style='max-height: 200px; overflow-y: auto;'></div>")
    

    However, I haven't tested if manipulating the HTML-structure this way will introduce any unexpected side-effects from kendo's side during regular usage of the widget.

    UPDATE: During the rendering-process when navigating to a different view, kendo removes the old table in order to render the new one - obviously - using the same routine as before. What remains is the empty <div> we created above and the new table, both directly underneath the widgets parent-node $("#scheduler"). This means that the code from above has to be executed after the grid's data has been bound. You can use the dataBound-event for this purpose. Docs: https://docs.telerik.com/kendo-ui/api/javascript/ui/scheduler#events-dataBound)

    The updated code-snippet, showing how the event-method could look like:

      function scheduler_DataBound() {
        $("#scheduler > .scheduler-content-wrapper").remove();//Reset the DOM after changing page
        $("#scheduler > table.k-scheduler-layout").wrap("<div class='scheduler-content-wrapper' style='max-height: 200px; overflow-y: auto;'></div>");
        $("#scheduler .k-scheduler-content").css("overflow-x", "hidden");//Fix horizontal scrollbar
      }
    

    UPDATE 2: I found out that the grid will crash in the case the dataBound-event gets fired after resizing the page or opening the editor-popup. My first thought was that dataBound isn't the right place to resize the grid. After trying to run the code through the navigate-event, which I think should be the right place, I found out that the only way to get it working from there is to surround the code with setTimeout(function(){ /* code... */ }). While this works, the delayed rendering looks terrible in the browser. Finally, I changed the code in order to set a flag whenever the grid should be resized after dataBound. Of course it feels cheesy to spread around that much code just to resize a widget. But from my current point of understanding this is the only acceptable solution if user experience matters.

    <script>
      var resizeScheduler = true;
      function scheduler_DataBound() {
        if (!resizeScheduler) {//Prevent grid crash, when event fired on page resize
          return; 
        }
    
        resizeScheduler = false;
        $("#scheduler > .scheduler-content-wrapper").remove();
        $("#scheduler > table.k-scheduler-layout").wrap("<div class='scheduler-content-wrapper' style='max-height: 200px; overflow-y: auto;'></div>");
        $("#scheduler .k-scheduler-content").css("overflow-x", "hidden");//Fix horizontal scrollbar
      }
      function scheduler_Navigate() {
        resizeScheduler = true;
      }
    </script>
    

    I hope this helps.