{"id":12912,"date":"2024-09-03T15:24:26","date_gmt":"2024-09-03T12:24:26","guid":{"rendered":"https:\/\/dhtmlx.com\/blog\/?p=12912"},"modified":"2024-09-03T18:17:48","modified_gmt":"2024-09-03T15:17:48","slug":"implementing-dynamic-theme-switching-dhtmlx-scheduler","status":"publish","type":"post","link":"https:\/\/dhtmlx.com\/blog\/implementing-dynamic-theme-switching-dhtmlx-scheduler\/","title":{"rendered":"Implementing Dynamic Theme Switching in DHTMLX Scheduler"},"content":{"rendered":"<p>Creating a responsive and intuitive UI involves adapting to the user&#8217;s preferences across various aspects of your application. One of the popular features that significantly enhances user experience is the ability to switch between light and dark themes. It can be especially useful in comprehensive components like scheduling calendars. <\/p>\n<p>This article will guide you through implementing dynamic theme switching in the DHTMLX Scheduler, making it adapt to the preferred system theme set by the user.<\/p>\n<h5>Introducing Theme Switching in DHTMLX Scheduler<\/h5>\n<p>DHTMLX Scheduler is a powerful JavaScript scheduling widget that comes with built-in support for different themes. In this guide, we&#8217;ll focus on toggling between the &#8220;dark&#8221; and the default &#8220;light&#8221; (terrace) themes. Switching the theme in DHTMLX Scheduler can be done programmatically with the <strong>setSkin()<\/strong> method:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"co1\">\/\/ Switch to the default light theme<\/span><br \/>\nscheduler.<span class=\"me1\">setSkin<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;terrace&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"co1\">\/\/ Switch to the dark theme<\/span><br \/>\nscheduler.<span class=\"me1\">setSkin<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;dark&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>These commands allow for the dynamic updating of the Scheduler&#8217;s appearance, providing a seamless user experience.<\/p>\n<h5>Identifying the Browser&#8217;s Preferred Theme<\/h5>\n<p>Modern browsers offer the possibility to detect a user&#8217;s preferred theme through the <strong>prefers-color-scheme CSS media<\/strong> feature. You can leverage this to adjust our Scheduler&#8217;s theme accordingly:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> prefersDarkMode <span class=\"sy0\">=<\/span> window.<span class=\"me1\">matchMedia<\/span> <span class=\"sy0\">&amp;&amp;<\/span> window.<span class=\"me1\">matchMedia<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'(prefers-color-scheme: dark)'<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">matches<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>This code checks if a user set his preference to dark mode, returning a boolean value.<\/p>\n<h5>Putting Everything Together<\/h5>\n<p>Let&#8217;s combine the theme detection with the component\u2019s initialization to ensure that the Scheduler meets the user&#8217;s system theme preference upon loading. Additionally, you&#8217;ll ensure that the Scheduler dynamically adapts to changes in these preferences:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">window.<span class=\"me1\">addEventListener<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;DOMContentLoaded&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; <span class=\"co1\">\/\/ Initialize Scheduler plugins and configurations<\/span><br \/>\n&nbsp; scheduler.<span class=\"me1\">plugins<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; quick_info<span class=\"sy0\">:<\/span> <span class=\"kw2\">true<\/span><br \/>\n&nbsp; <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; scheduler.<span class=\"me1\">config<\/span>.<span class=\"me1\">cascade_event_display<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw2\">true<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"co1\">\/\/ Function to dynamically update the Scheduler's theme<\/span><br \/>\n&nbsp; <span class=\"kw1\">function<\/span> updateSchedulerTheme<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> prefersDarkMode <span class=\"sy0\">=<\/span> window.<span class=\"me1\">matchMedia<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'(prefers-color-scheme: dark)'<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">matches<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>prefersDarkMode<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">setSkin<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;dark&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> <span class=\"kw1\">else<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">setSkin<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;terrace&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"co1\">\/\/ Set the initial theme based on the user's preference<\/span><br \/>\n&nbsp; updateSchedulerTheme<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"co1\">\/\/ Listen for changes in the preferred color scheme and update the theme<\/span><br \/>\n&nbsp; window.<span class=\"me1\">matchMedia<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'(prefers-color-scheme: dark)'<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">addEventListener<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'change'<\/span><span class=\"sy0\">,<\/span> updateSchedulerTheme<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"co1\">\/\/ Initialize the DHTMLX Scheduler<\/span><br \/>\n&nbsp; scheduler.<span class=\"me1\">init<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'scheduler_here'<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">2024<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">3<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">20<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;week&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>By embedding the theme update logic within the <strong>DOMContentLoaded<\/strong> event listener, you make sure that the Scheduler not only initializes with its configuration and plugins but also immediately adopts the user&#8217;s preferred theme. This integration provides a seamless transition between themes, enhancing the overall user experience. As a result, the application becomes more personalized and accessible.<\/p>\n<h5>Adding a UI Control for Switching Themes<\/h5>\n<p>Don&#8217;t forget to enable end-users to switch themes manually. You&#8217;ll need to make a few adjustments to your code to do this. You have to add a simple control that allows end-users to select a theme from three options: Browser Default, Light, and Dark.<\/p>\n<p>You need to modify the <strong>updateSchedulerTheme<\/strong> function. Add an argument for the user-selected theme. If the end-user chooses either the Light or Dark theme, you&#8217;ll apply that directly. If the default theme is selected in the browser, use the preferred theme from the browser settings.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> updateSchedulerTheme<span class=\"br0\">&#40;<\/span>selectedTheme<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/ We use &quot;default&quot; for the Browser Default option<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span><span class=\"sy0\">!<\/span>selectedTheme <span class=\"sy0\">||<\/span> selectedTheme <span class=\"sy0\">===<\/span> <span class=\"st0\">'default'<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">const<\/span> prefersDarkMode <span class=\"sy0\">=<\/span> window.<span class=\"me1\">matchMedia<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'(prefers-color-scheme: dark)'<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">matches<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>prefersDarkMode<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">setSkin<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;dark&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> <span class=\"kw1\">else<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">setSkin<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;terrace&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> <span class=\"kw1\">else<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">setSkin<\/span><span class=\"br0\">&#40;<\/span>selectedTheme<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>The markup for the switcher control can look like this:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> updateSchedulerTheme<span class=\"br0\">&#40;<\/span>selectedTheme<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/ We use &quot;default&quot; for the Browser Default option<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span><span class=\"sy0\">!<\/span>selectedTheme <span class=\"sy0\">||<\/span> selectedTheme <span class=\"sy0\">===<\/span> <span class=\"st0\">'default'<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">const<\/span> prefersDarkMode <span class=\"sy0\">=<\/span> window.<span class=\"me1\">matchMedia<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'(prefers-color-scheme: dark)'<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">matches<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>prefersDarkMode<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">setSkin<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;dark&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> <span class=\"kw1\">else<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">setSkin<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;terrace&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> <span class=\"kw1\">else<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">setSkin<\/span><span class=\"br0\">&#40;<\/span>selectedTheme<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>The final step is to connect the control to the <strong>updateSchedulerTheme<\/strong> function. It can be done with the following code:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> themeSwitcher <span class=\"sy0\">=<\/span> document.<span class=\"me1\">querySelectorAll<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'input[name=&quot;theme&quot;]'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nthemeSwitcher.<span class=\"me1\">forEach<\/span><span class=\"br0\">&#40;<\/span>radio <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; radio.<span class=\"me1\">addEventListener<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'change'<\/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; &nbsp; &nbsp; updateSchedulerTheme<span class=\"br0\">&#40;<\/span><span class=\"kw1\">this<\/span>.<span class=\"me1\">value<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>In this <a href=\"https:\/\/snippet.dhtmlx.com\/5cbeip44?mode=wide\">sample<\/a>, you can see how everything comes together.<\/p>\n<h5>Conclusion<\/h5>\n<p>Integrating responsive theme switching in web applications, as demonstrated with the DHTMLX Scheduler, elevates the user experience by making applications adaptable to users&#8217; preferences. By embracing such user-centric features, you underscore the adaptability and modernity of your web application, making it more engaging and accessible to all users.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Creating a responsive and intuitive UI involves adapting to the user&#8217;s preferences across various aspects of your application. One of the popular features that significantly enhances user experience is &#8230;<\/p>\n","protected":false},"author":101014,"featured_media":12915,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[71],"tags":[33,15],"class_list":["post-12912","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\/12912","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\/101014"}],"replies":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/comments?post=12912"}],"version-history":[{"count":2,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/12912\/revisions"}],"predecessor-version":[{"id":12914,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/12912\/revisions\/12914"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media\/12915"}],"wp:attachment":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media?parent=12912"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/categories?post=12912"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/tags?post=12912"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}