{"id":1975,"date":"2013-09-06T16:42:27","date_gmt":"2013-09-06T12:42:27","guid":{"rendered":"http:\/\/www.dhtmlx.com\/blog\/?p=1975"},"modified":"2025-09-02T14:59:50","modified_gmt":"2025-09-02T11:59:50","slug":"using-dhtmlxscheduler-with-node-js","status":"publish","type":"post","link":"https:\/\/dhtmlx.com\/blog\/using-dhtmlxscheduler-with-node-js\/","title":{"rendered":"Creating Online Event Calendar with Node.js and dhtmlxScheduler"},"content":{"rendered":"<p>The combination of <a href=\"https:\/\/nodejs.org\/en\/\">Node.js<\/a> and <a href=\"https:\/\/www.mongodb.com\/\">MongoDB<\/a> is a useful tool for quick development of dynamic sites. In this tutorial, we will explain how <a href=\"https:\/\/dhtmlx.com\/docs\/products\/dhtmlxScheduler\/\">dhtmlxScheduler<\/a>, an embeddable JavaScript calendar, can be used to create an online event calendar with Node.js backend.<\/p>\n<p><a href=\"\/\/dhtmlx.com\/docs\/products\/dhtmlxScheduler\/download.shtml\" onclick=\"ga('send', 'event', 'link', 'click', 'download-scheduler-nodejs-blog')\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/11\/download-scheduler-banner.png\" alt=\"download scheduler\" width=\"900\" height=\"300\" class=\"aligncenter size-full wp-image-3704\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/11\/download-scheduler-banner.png 900w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/11\/download-scheduler-banner-300x100.png 300w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/11\/download-scheduler-banner-768x256.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p>You can download the full archive with the final solution <a href=\"https:\/\/github.com\/DHTMLX\/node-scheduler-demo\">from GitHub<\/a>.<\/p>\n<h3>Creating a Simple Node.js Site<\/h3>\n<p>&nbsp;<br \/>\nOne of the advantages of Node.js is a rich library of ready to use solutions. That&#8217;s why we won&#8217;t write everything from scratch but will use ready modules: <a href=\"https:\/\/expressjs.com\/\">Express<\/a>, as a web-framework, and <a href=\"https:\/\/github.com\/kissjs\/node-mongoskin\">MongoSkin<\/a>, to work with MongoDB.<\/p>\n<p><a href=\"https:\/\/github.com\/DHTMLX\/node-scheduler-demo\" target=\"_blank\">You can find a complete demo of using dhtmlxScheduler and Node.js on GitHub right now.<\/a><\/p>\n<p><!--more-->To start, let&#8217;s create a new directory, for example, <strong>&#8216;scheduler-node&#8217;<\/strong>, and install the necessary libraries into it by running the next command:<\/p>\n<div class=\"codecolorer-container html4strict default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"html4strict codecolorer\">mkdir scheduler-node<br \/>\ncd scheduler-node<br \/>\nnpm install express --save<br \/>\nnpm install mongodb@&quot;^2.0.0&quot; --save<br \/>\nnpm install mongoskin --save<\/div><\/div>\n<p>Then we create the base of our application &#8211; <strong>app.js<\/strong> file in the <strong>&#8216;scheduler-node&#8217;<\/strong> directory &#8211; with the following content:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">var<\/span> express <span class=\"sy0\">=<\/span> require<span class=\"br0\">&#40;<\/span><span class=\"st0\">'express'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">var<\/span> path <span class=\"sy0\">=<\/span> require<span class=\"br0\">&#40;<\/span><span class=\"st0\">'path'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">var<\/span> bodyParser <span class=\"sy0\">=<\/span> require<span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;body-parser&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"co1\">\/\/connect to the mongoDB<\/span><br \/>\n<span class=\"kw1\">var<\/span> db <span class=\"sy0\">=<\/span> require<span class=\"br0\">&#40;<\/span><span class=\"st0\">'mongoskin'<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">db<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;mongodb:\/\/localhost\/testdb&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">&#123;<\/span> w<span class=\"sy0\">:<\/span> <span class=\"nu0\">0<\/span><span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; db.<span class=\"me1\">bind<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'event'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"co1\">\/\/create express app, use public folder for static files<\/span><br \/>\n<span class=\"kw1\">var<\/span> app <span class=\"sy0\">=<\/span> express<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\napp.<span class=\"me1\">use<\/span><span class=\"br0\">&#40;<\/span>express.<span class=\"kw1\">static<\/span><span class=\"br0\">&#40;<\/span>path.<span class=\"me1\">join<\/span><span class=\"br0\">&#40;<\/span>__dirname<span class=\"sy0\">,<\/span> <span class=\"st0\">'public'<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"co1\">\/\/is necessary for parsing POST request<\/span><br \/>\napp.<span class=\"me1\">use<\/span><span class=\"br0\">&#40;<\/span>bodyParser.<span class=\"me1\">json<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\napp.<span class=\"me1\">use<\/span><span class=\"br0\">&#40;<\/span>bodyParser.<span class=\"me1\">urlencoded<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span> extended<span class=\"sy0\">:<\/span> <span class=\"kw2\">true<\/span> <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\napp.<span class=\"me1\">listen<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">3000<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Due to the use of the Express framework, the whole app fitted into several lines. It doesn&#8217;t execute anything extraordinary and just serves static files from the <strong>&#8216;public&#8217;<\/strong> directory.<\/p>\n<p>Let&#8217;s create <strong>&#8216;public&#8217;<\/strong> directory and unpack the folder <strong>&#8216;codebase&#8217;<\/strong> from the dhtmlxScheduler package into it (<a href=\"https:\/\/dhtmlx.com\/x\/download\/regular\/dhtmlxScheduler.zip\">download dhtmlxScheduler Standard Edition<\/a>). After that, the whole file structure will look like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/09\/files-scheduler.png\" alt=\"dhtmlxScheduler with Node.js - File structure\" title=\"dhtmlxScheduler with Node.js - File structure\" width=\"608\" height=\"203\" class=\"aligncenter size-full wp-image-1983\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/09\/files-scheduler.png 608w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/09\/files-scheduler-300x100.png 300w\" sizes=\"auto, (max-width: 608px) 100vw, 608px\" \/><\/p>\n<p>Now, we create <strong>index.html<\/strong> file in the <strong>&#8216;public&#8217;<\/strong> directory. It will be the main page where we will place our calendar. Here is the content of this file:<\/p>\n<div class=\"codecolorer-container html4strict default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"html4strict codecolorer\"><span class=\"sc2\">&lt;!doctype html&gt;<\/span><br \/>\n<span class=\"sc2\">&lt;<span class=\"kw2\">head<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">meta<\/span> <span class=\"kw3\">content<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;text\/html; charset=utf-8&quot;<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">script<\/span> <span class=\"kw3\">src<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;codebase\/dhtmlxscheduler.js&quot;<\/span> &gt;&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">script<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">link<\/span> <span class=\"kw3\">rel<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;stylesheet&quot;<\/span> <span class=\"kw3\">href<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;codebase\/dhtmlxscheduler.css&quot;<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">style<\/span> <span class=\"kw3\">type<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;text\/css&quot;<\/span> <span class=\"kw3\">media<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;screen&quot;<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; html, body{<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; margin:0px;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; padding:0px;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; height:100%;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; overflow:hidden;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">style<\/span>&gt;<\/span><br \/>\n<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">head<\/span>&gt;<\/span><br \/>\n<br \/>\n<br \/>\n<span class=\"sc2\">&lt;<span class=\"kw2\">script<\/span> <span class=\"kw3\">type<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;text\/javascript&quot;<\/span> <span class=\"kw3\">charset<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;utf-8&quot;<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; function init() {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; scheduler.init('scheduler_here',new Date(2018,8,4),&quot;month&quot;);<br \/>\n&nbsp; &nbsp; }<br \/>\n<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">script<\/span>&gt;<\/span><br \/>\n<br \/>\n<span class=\"sc2\">&lt;<span class=\"kw2\">body<\/span> <span class=\"kw3\">onload<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;init();&quot;<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">id<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;scheduler_here&quot;<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_container&quot;<\/span> <span class=\"kw3\">style<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">'width:100%; height:100%;'<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_navline&quot;<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_prev_button&quot;<\/span>&gt;<\/span><span class=\"sc1\">&amp;nbsp;<\/span><span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_next_button&quot;<\/span>&gt;<\/span><span class=\"sc1\">&amp;nbsp;<\/span><span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_today_button&quot;<\/span>&gt;&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_date&quot;<\/span>&gt;&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_tab&quot;<\/span> <span class=\"kw3\">name<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;day_tab&quot;<\/span>&gt;&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_tab&quot;<\/span> <span class=\"kw3\">name<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;week_tab&quot;<\/span>&gt;&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_tab&quot;<\/span> <span class=\"kw3\">name<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;month_tab&quot;<\/span>&gt;&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_header&quot;<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;dhx_cal_data&quot;<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">body<\/span>&gt;<\/span><\/div><\/div>\n<p>This is the basic HTML code needed for working with dhtmlxScheduler.<\/p>\n<p>To check how the app works, we may start the Node.js server and open http:\/\/localhost:3000 address in a browser. If everything is done correctly, we will see a calendar without events (to start Node.js server, run &#8220;nodejs app.js&#8221; command).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/09\/scheduler-nodejs.png\" alt=\"scheduler nodejs\" width=\"900\" height=\"479\" class=\"aligncenter size-full wp-image-4527\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/09\/scheduler-nodejs.png 900w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/09\/scheduler-nodejs-300x160.png 300w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2013\/09\/scheduler-nodejs-768x409.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/p>\n<h3>Loading Events<\/h3>\n<p>&nbsp;<br \/>\nFirst, we add two new handlers into <strong>app.js<\/strong>:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">app.<span class=\"kw1\">get<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'\/init'<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span>req<span class=\"sy0\">,<\/span> res<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; db.<span class=\"me1\">event<\/span>.<span class=\"me1\">insert<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; text<span class=\"sy0\">:<\/span><span class=\"st0\">&quot;My test event A&quot;<\/span><span class=\"sy0\">,<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; start_date<span class=\"sy0\">:<\/span> <span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">2018<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">8<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; end_date<span class=\"sy0\">:<\/span> &nbsp; <span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">2018<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">8<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">5<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; db.<span class=\"me1\">event<\/span>.<span class=\"me1\">insert<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; text<span class=\"sy0\">:<\/span><span class=\"st0\">&quot;One more test event&quot;<\/span><span class=\"sy0\">,<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; start_date<span class=\"sy0\">:<\/span> <span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">2018<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">8<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">3<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; end_date<span class=\"sy0\">:<\/span> &nbsp; <span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">2018<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">8<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">8<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; color<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;#DD8616&quot;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"coMULTI\">\/*... skipping similar code for other test events...*\/<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; res.<span class=\"me1\">send<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;Test events were added to the database&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<br \/>\napp.<span class=\"kw1\">get<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'\/data'<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span>req<span class=\"sy0\">,<\/span> res<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; db.<span class=\"me1\">event<\/span>.<span class=\"me1\">find<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">toArray<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span>err<span class=\"sy0\">,<\/span> data<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/set id property for all records<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">for<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw1\">var<\/span> i <span class=\"sy0\">=<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span> i <span class=\"sy0\">&lt;<\/span> data.<span class=\"me1\">length<\/span><span class=\"sy0\">;<\/span> i<span class=\"sy0\">++<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span>.<span class=\"me1\">id<\/span> <span class=\"sy0\">=<\/span> data<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span>._id<span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/output response<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; res.<span class=\"me1\">send<\/span><span class=\"br0\">&#40;<\/span>data<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>The first &#8220;\/init&#8221; is necessary to generate test data. It just adds a few records into the database.<\/p>\n<p>The second handler &#8211; &#8220;\/data&#8221; &#8211; will be used to load data into the calendar. Here we choose all the records from the database and send them to the client side as JSON structure.<\/p>\n<p>NOTE: Before sending the records, we define the id property for each object. It&#8217;s needed because dhtmlxScheduler expects that record id is stored in <strong>obj.id<\/strong> but MongoDB keeps this value in <strong>obj._id<\/strong>.<\/p>\n<p>We also need to add some changes in <strong>index.html<\/strong>:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">&nbsp; &nbsp; &nbsp; &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\">2018<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">8<\/span><span class=\"sy0\">,<\/span><span class=\"nu0\">4<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><span class=\"st0\">&quot;month&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">templates<\/span>.<span class=\"me1\">xml_date<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span>value<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span> <span class=\"kw1\">return<\/span> <span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span>value<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span> <span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">load<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;\/data&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;json&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>We have added two lines. The first one defines how to parse dates from the incoming data. Most often, while loading data from the server, dates are stored like strings in a special format. In our case, dates are stored as timestamps and we can convert them into date objects through Date constructor. The second line initiates data loading, using the URL described above.<\/p>\n<p>If we restart the server and open in browser firstly http:\/\/localhost:3000\/init &#8211; to generate test data, and then http:\/\/localhost:3000, we will see our calendar with the events inside.<\/p>\n<h3>Adding, Editing, and Deleting Events<\/h3>\n<p>&nbsp;<br \/>\nTo add the ability to add, edit, and delete events in the calendar, we need to add the code that initializes dataprocessor to the <strong>index.html<\/strong> file:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">&nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">config<\/span>.<span class=\"me1\">xml_date<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;%Y-%m-%d %H:%i&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> dp <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> dataProcessor<span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;\/data&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; dp.<span class=\"me1\">init<\/span><span class=\"br0\">&#40;<\/span>scheduler<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; dp.<span class=\"me1\">setTransactionMode<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;POST&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"kw2\">false<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>The first line defines the format the dates will take while going back to the server. We are using default year-month-day order that can be parsed by MongoDB. The following block initializes dataprocessor and switches it to the mode of simple POST sending. From now on, each time when the data in the scheduler changes, dataprocessor will call &#8220;\/data&#8221; url and will pass all the properties of the changed event.<\/p>\n<p>Let&#8217;s now go over to the server code and add one more handler to <strong>app.js<\/strong>:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">app.<span class=\"me1\">post<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'\/data'<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span>req<span class=\"sy0\">,<\/span> res<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">var<\/span> data <span class=\"sy0\">=<\/span> req.<span class=\"me1\">body<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/get operation type<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">var<\/span> mode <span class=\"sy0\">=<\/span> data<span class=\"br0\">&#91;<\/span><span class=\"st0\">&quot;!nativeeditor_status&quot;<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/get id of record<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">var<\/span> sid <span class=\"sy0\">=<\/span> data.<span class=\"me1\">id<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">var<\/span> tid <span class=\"sy0\">=<\/span> sid<span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/remove properties which we do not want to save in DB<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">delete<\/span> data.<span class=\"me1\">id<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">delete<\/span> data<span class=\"br0\">&#91;<\/span><span class=\"st0\">&quot;!nativeeditor_status&quot;<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/output confirmation response<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">function<\/span> update_response<span class=\"br0\">&#40;<\/span>err<span class=\"sy0\">,<\/span> result<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>err<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mode <span class=\"sy0\">=<\/span> <span class=\"st0\">&quot;error&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">else<\/span> <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>mode <span class=\"sy0\">==<\/span> <span class=\"st0\">&quot;inserted&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tid <span class=\"sy0\">=<\/span> data._id<span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; res.<span class=\"me1\">setHeader<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;Content-Type&quot;<\/span><span class=\"sy0\">,<\/span><span class=\"st0\">&quot;application\/json&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; res.<span class=\"me1\">send<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span>action<span class=\"sy0\">:<\/span> mode<span class=\"sy0\">,<\/span> sid<span class=\"sy0\">:<\/span> sid<span class=\"sy0\">,<\/span> tid<span class=\"sy0\">:<\/span> tid<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/run db operation<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>mode <span class=\"sy0\">==<\/span> <span class=\"st0\">&quot;updated&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; db.<span class=\"me1\">event<\/span>.<span class=\"me1\">updateById<\/span><span class=\"br0\">&#40;<\/span> sid<span class=\"sy0\">,<\/span> data<span class=\"sy0\">,<\/span> update_response<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">else<\/span> <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>mode <span class=\"sy0\">==<\/span> <span class=\"st0\">&quot;inserted&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; db.<span class=\"me1\">event<\/span>.<span class=\"me1\">insert<\/span><span class=\"br0\">&#40;<\/span>data<span class=\"sy0\">,<\/span> update_response<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">else<\/span> <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>mode <span class=\"sy0\">==<\/span> <span class=\"st0\">&quot;deleted&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; db.<span class=\"me1\">event<\/span>.<span class=\"me1\">removeById<\/span><span class=\"br0\">&#40;<\/span> sid<span class=\"sy0\">,<\/span> update_response<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">else<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; res.<span class=\"me1\">send<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;Not supported operation&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>Here we use <strong>app.post<\/strong>, as all saving operations use POST queries. The first part of the code defines the type of operation and removes all the technical parameters from an incoming query to get an object that can be saved in the database.<\/p>\n<p>Next, depending on the type of operation, we call the related method of <strong>db.event<\/strong> for adding\/saving\/deleting data. As the operations with database are asynchronous, we pass the specified earlier callback function <strong>update_response<\/strong> as the last parameter. <\/p>\n<p>The client side expects to get the confirmation of saving operation or an error message &#8211; this is what the <strong>update_response<\/strong> function is responsible for. It generates a JSON response in the necessary format and sends it to the client side. (Details of the format can be found <a href=\"https:\/\/docs.dhtmlx.com\/dataprocessor__configuration.html#sending_modes\">in the documentation<\/a>). In case of adding a new record, this function also includes ID generated by MongoDB for the new record, in response to update of the element id on the client side.<\/p>\n<p>If we restart the server and open http:\/\/localhost:3000 in browser again, we\u2019ll get a calendar with events that we can create, edit and delete. What is more, all the changes are automatically saved in the database and will be available after reloading the page.<\/p>\n<p>Again, the final demo is available on <a href=\"https:\/\/github.com\/DHTMLX\/node-scheduler-demo\">GitHub<\/a> so you can download it and view the details.<\/p>\n<p><strong><a href=\"\/\/dhtmlx.com\/docs\/products\/dhtmlxScheduler\/download.shtml\" onclick=\"ga('send', 'event', 'link', 'click', 'download-shed-nodejs-link')\">Download dhtmlxScheduler to add a powerful scheduling calendar to your app<\/a><\/strong><\/p>\n<h3>Final Thoughts<\/h3>\n<p>&nbsp;<br \/>\nThe server solution we&#8217;ve got is multipurpose. We can add any number of extra fields into the calendar, and we don&#8217;t need to change anything in the server code, as it will save and load new fields automatically. The code of data loading and data saving is quite simple. It won&#8217;t be difficult to add validation or to format data before loading, if needed.<\/p>\n<p>By slightly expanding this code, we may get a Node.js event calendar that allows several users to edit the calendar simultaneously (update the data on the client side without reloading pages). However, it is a topic for a separate article.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The combination of Node.js and MongoDB is a useful tool for quick development of dynamic sites. In this tutorial, we will explain how dhtmlxScheduler, an embeddable JavaScript calendar, can &#8230;<\/p>\n","protected":false},"author":2,"featured_media":3800,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,71,1,38],"tags":[33,14,39,15],"class_list":["post-1975","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-posts-for-codeproject-com","category-tutorials","category-uncategorized","category-visible","tag-all-posts","tag-tips","tag-nodejs","tag-dhtmlxscheduler"],"_links":{"self":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/1975","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\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/comments?post=1975"}],"version-history":[{"count":3,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/1975\/revisions"}],"predecessor-version":[{"id":14381,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/1975\/revisions\/14381"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media\/3800"}],"wp:attachment":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media?parent=1975"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/categories?post=1975"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/tags?post=1975"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}