{"id":12521,"date":"2024-06-18T15:21:26","date_gmt":"2024-06-18T12:21:26","guid":{"rendered":"https:\/\/dhtmlx.com\/blog\/?p=12521"},"modified":"2024-06-18T15:21:26","modified_gmt":"2024-06-18T12:21:26","slug":"combine-fixed-headers-container-autoresize-dhtmlx-scheduler","status":"publish","type":"post","link":"https:\/\/dhtmlx.com\/blog\/combine-fixed-headers-container-autoresize-dhtmlx-scheduler\/","title":{"rendered":"How to Combine Fixed Headers and Container Autoresize in DHTMLX Scheduler"},"content":{"rendered":"<p>&#8220;Great things are done by a series of small things brought together&#8221; &#8211; these are the words of Vincent Van Gogh, and they perfectly capture the essence of the development process. However, web developers frequently get stuck on some small things and lose their valuable time. To save your efforts with DHTMLX libraries, we want to start sharing tips that shed light on the proper usage of certain API elements.<\/p>\n<p>We start with discussing how to fix the headers at the top of the <a href=\"https:\/\/dhtmlx.com\/docs\/products\/dhtmlxScheduler\/\" rel=\"noopener\" target=\"_blank\">DHTMLX JavaScript Scheduler<\/a> with the enabled <strong>container_autoresize<\/strong> extension.<\/p>\n<h5>What is the Issue<\/h5>\n<p>When using the <strong>container_autoresize <\/strong>extension in DHTMLX Scheduler, the scheduler component resizes itself to fit all the content. This can cause Scheduler to exceed the screen size, resulting in scrollbars appearing on the outer container or the page itself. This behavior ensures that the content is visible without internal scrolling. But here comes a challenge: the navigation and time headers scroll out of view when the page is scrolled down <a href=\"https:\/\/snippet.dhtmlx.com\/9vvjxh6i?mode=wide\" rel=\"noopener\" target=\"_blank\">like in this example<\/a>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2024\/06\/DHTMLX-Scheduler-Not-Fixed-Headers.gif\" alt=\"dhtmlx-scheduler-not-fixed-headers\" width=\"1306\" height=\"792\" class=\"aligncenter size-full wp-image-12525\" \/> <a href=\"https:\/\/snippet.dhtmlx.com\/9vvjxh6i?mode=mobile\" rel=\"noopener\" target=\"_blank\">Check the sample ><\/a><\/p>\n<p>Let&#8217;s go through a few steps that can help with this issue.<\/p>\n<h5>CSS for Sticky Position<\/h5>\n<p>To keep the headers fixed, we&#8217;ll use <strong>position: sticky<\/strong> for the header elements. This ensures that the headers stay in place while the rest of the content scrolls. Here\u2019s the necessary CSS:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"sy0\">&lt;<\/span>style<span class=\"sy0\">&gt;<\/span><br \/>\n<br \/>\n&nbsp; .<span class=\"me1\">dhx_cal_container<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; overflow<span class=\"sy0\">:<\/span> visible<span class=\"sy0\">!<\/span>important<span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; .<span class=\"me1\">dhx_cal_navline<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; .<span class=\"me1\">dhx_cal_header<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; position<span class=\"sy0\">:<\/span> sticky<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; z<span class=\"sy0\">-<\/span>index<span class=\"sy0\">:<\/span> <span class=\"nu0\">10<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; background<span class=\"sy0\">:<\/span><span class=\"kw1\">var<\/span><span class=\"br0\">&#40;<\/span><span class=\"sy0\">--<\/span>dhx<span class=\"sy0\">-<\/span>scheduler<span class=\"sy0\">-<\/span>container<span class=\"sy0\">-<\/span>background<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <br \/>\n&nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; .<span class=\"me1\">dhx_cal_navline<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; z<span class=\"sy0\">-<\/span>index<span class=\"sy0\">:<\/span> <span class=\"nu0\">11<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; top<span class=\"sy0\">:<\/span><span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; .<span class=\"me1\">dhx_cal_header<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; <span class=\"coMULTI\">\/* top coordinate is assigned from JS *\/<\/span><br \/>\n&nbsp; &nbsp; &nbsp; margin<span class=\"sy0\">-<\/span>left<span class=\"sy0\">:<\/span> <span class=\"sy0\">-<\/span>1px<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; box<span class=\"sy0\">-<\/span>shadow<span class=\"sy0\">:<\/span> <span class=\"nu0\">0<\/span> 1px 0px 0px <span class=\"kw1\">var<\/span><span class=\"br0\">&#40;<\/span><span class=\"sy0\">--<\/span>dhx<span class=\"sy0\">-<\/span>scheduler<span class=\"sy0\">-<\/span>base<span class=\"sy0\">-<\/span>colors<span class=\"sy0\">-<\/span>border<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n<span class=\"sy0\">&lt;\/<\/span>style<span class=\"sy0\">&gt;<\/span><\/div><\/div>\n<p>In this CSS, <strong>position: sticky<\/strong> is applied to both the <strong>.dhx_cal_navline<\/strong> and <strong>.dhx_cal_header elements<\/strong>. Pay attention to the usage of theme css variables for the <strong>background<\/strong> and <strong>box-shadow<\/strong> properties. This is essential for maintaining consistent styles with the rest of the Scheduler across all themes. <\/p>\n<p>As for the positioning, let\u2019s set <strong>top: 0<\/strong> for the <strong>.dhx_cal_navline<\/strong> element since it is the topmost element of the scheduler.<\/p>\n<p>The <strong>.dhx_cal_header<\/strong> element, which should be displayed directly below the navigation line, also uses <strong>position: sticky<\/strong>. However, its top position needs to be dynamically set using JavaScript to account for the varying height of the <strong>.dhx_cal_navline<\/strong>.<\/p>\n<h5>JavaScript for Dynamic Positioning<\/h5>\n<p>Now you need to dynamically set the top position of the time header based on the height of the navigation panel. For this purpose, use the <strong>onViewChange<\/strong> API event of DHTMLX Scheduler:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">scheduler.<span class=\"me1\">attachEvent<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;onViewChange&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp;<span class=\"kw1\">const<\/span> navBar <span class=\"sy0\">=<\/span> scheduler.$container.<span class=\"me1\">querySelector<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.dhx_cal_navline&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp;<span class=\"kw1\">const<\/span> header <span class=\"sy0\">=<\/span> scheduler.$container.<span class=\"me1\">querySelector<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.dhx_cal_header&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp;<span class=\"kw1\">if<\/span><span class=\"br0\">&#40;<\/span>navBar <span class=\"sy0\">&amp;&amp;<\/span> header<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;header.<span class=\"me1\">style<\/span>.<span class=\"me1\">top<\/span> <span class=\"sy0\">=<\/span> `$<span class=\"br0\">&#123;<\/span>navBar.<span class=\"me1\">offsetHeight<\/span><span class=\"br0\">&#125;<\/span>px`<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp;<span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>At this stage, you capture the scheduler repaints. Each time a repaint occurs, you take the current height of the navigation bar and set it as the top coordinate for the <strong>.dhx_cal_header<\/strong> element. This dynamic positioning keeps the time header right below the navigation panel, regardless of its height.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2024\/06\/DHTMLX-Scheduler-Fixed-Headers.gif\" alt=\"dhtmlx-scheduler-fixed-headers\" width=\"1306\" height=\"792\" class=\"aligncenter size-full wp-image-12526\" \/><a href=\"https:\/\/snippet.dhtmlx.com\/syo8wm9s?mode=mobile\" rel=\"noopener\" target=\"_blank\">Check the sample ><\/a><\/p>\n<p>These are the main steps that will help keep the headers of your JavaScript scheduling calendar visible when the page is scrolled down. <a href=\"https:\/\/snippet.dhtmlx.com\/syo8wm9s?mode=wide\" rel=\"noopener\" target=\"_blank\">Use this sample<\/a> to see how it works in practice.<\/p>\n<h5>Related Materials<\/h5>\n<ul>\n<li><a href=\"https:\/\/dhtmlx.com\/docs\/products\/dhtmlxScheduler\/download.shtml\" rel=\"noopener\" target=\"_blank\">DHTMLX Scheduler 30-day trial version<\/a><\/li>\n<li><a href=\"https:\/\/docs.dhtmlx.com\/scheduler\/\" rel=\"noopener\" target=\"_blank\">DHTMLX Scheduler documentation<\/a><\/li>\n<li><a href=\"https:\/\/docs.dhtmlx.com\/scheduler\/samples\/\" rel=\"noopener\" target=\"_blank\">DHTMLX Scheduler samples<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;Great things are done by a series of small things brought together&#8221; &#8211; these are the words of Vincent Van Gogh, and they perfectly capture the essence of the &#8230;<\/p>\n","protected":false},"author":101013,"featured_media":12528,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[71],"tags":[33,15],"class_list":["post-12521","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-all-posts","tag-dhtmlxscheduler"],"_links":{"self":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/12521","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/users\/101013"}],"replies":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/comments?post=12521"}],"version-history":[{"count":3,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/12521\/revisions"}],"predecessor-version":[{"id":12529,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/12521\/revisions\/12529"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media\/12528"}],"wp:attachment":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media?parent=12521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/categories?post=12521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/tags?post=12521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}