{"id":2393,"date":"2014-08-06T12:00:13","date_gmt":"2014-08-06T08:00:13","guid":{"rendered":"http:\/\/www.dhtmlx.com\/blog\/?p=2393"},"modified":"2023-05-05T13:59:16","modified_gmt":"2023-05-05T10:59:16","slug":"dhtmlxgantt-with-nodejs","status":"publish","type":"post","link":"https:\/\/dhtmlx.com\/blog\/dhtmlxgantt-with-nodejs\/","title":{"rendered":"Using dhtmlxGantt together with Node.js"},"content":{"rendered":"<p>If you follow our tutorials, you have already known how to use <a href=\"https:\/\/dhtmlx.com\/blog\/using-dhtmlxscheduler-with-node-js\/\">dhtmlxScheduler<\/a> and <a href=\"https:\/\/dhtmlx.com\/blog\/using-dhtmlxgrid-with-node-js\/#more-2016\">dhtmlxGrid<\/a> with Node.js, a flexible JavaScript platform.<\/p>\n<p>This time we will deal with dhtmlxGantt with Node.js.<\/p>\n<p><\/br><br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen2.png\" alt=\"dhtmlxGantt with Node.js\" width=\"600\" height=\"176\" class=\"aligncenter size-full wp-image-2417\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen2.png 600w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen2-300x88.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><br \/>\n<\/br><\/p>\n<p>You can download the full archive with the final solution <a href=\"https:\/\/github.com\/DHTMLX\/gantt-howto-node\">from github<\/a>. <\/p>\n<p><strong>Step 1 &#8211; Creating a simple Node.js site<\/strong><\/p>\n<p>Fortunately, Node.js has a set of ready to use solutions. And we don\u2019t have to write everything from scratch, we will use the ready modules. <a href=\"https:\/\/expressjs.com\/\">Express<\/a> as a web-framework and <a href=\"https:\/\/github.com\/mysqljs\/mysql\">node-mysql<\/a> &#8211; to work with MySQL. Also, as we are working with dates we need a lib to convert dates to string and back. For this purpose we will need <a href=\"https:\/\/github.com\/litejs\/date-format-lite\">date-format-lite<\/a> <\/p>\n<p>First of all, let\u2019s create a directory &#8211; \u201cgantt-node\u201d, for example, &#8211; 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 gantt-node<br \/>\ncd gantt-node<br \/>\nnpm install express<br \/>\nnpm install mongoskin<br \/>\nnpm install date-format-lite<\/div><\/div>\n<p>Then we proceed with preparing database &#8211; we need to create tables as described here &#8211;<a href=\"https:\/\/docs.dhtmlx.com\/gantt\/desktop__howtostart_nodejs.html#step3preparingadatabase\">https:\/\/docs.dhtmlx.com\/gantt\/desktop__howtostart_nodejs.html#step3preparingadatabase<\/a><\/p>\n<p><!--more--><\/p>\n<p>The next step is a creation of the base of our app &#8211; \u201capp.js\u201d file in the \u201cscheduler-node\u201d 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<br \/>\n<span class=\"co1\">\/\/connect to the MySQL<\/span><br \/>\n<span class=\"kw1\">var<\/span> mysql &nbsp; &nbsp; &nbsp;<span class=\"sy0\">=<\/span> require<span class=\"br0\">&#40;<\/span><span class=\"st0\">'mysql'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">var<\/span> db <span class=\"sy0\">=<\/span> mysql.<span class=\"me1\">createConnection<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; host &nbsp; &nbsp; <span class=\"sy0\">:<\/span> <span class=\"st0\">'localhost'<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; user &nbsp; &nbsp; <span class=\"sy0\">:<\/span> <span class=\"st0\">'sampleDB'<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; password <span class=\"sy0\">:<\/span> <span class=\"st0\">'sampleDB'<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; database <span class=\"sy0\">:<\/span> <span class=\"st0\">'sampleDB'<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"co1\">\/\/enable date conversion helpers<\/span><br \/>\nrequire<span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;date-format-lite&quot;<\/span><span class=\"br0\">&#41;<\/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>express.<span class=\"me1\">bodyParser<\/span><span class=\"br0\">&#40;<\/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>Don\u2019t forget to change the DB parameters to those you need.<\/p>\n<p>Due to Express, the whole app fit into a couple of lines. It doesn\u2019t execute anything extraordinary and just serves static files from the \u201cpublic\u201d directory.<\/p>\n<p>Create \u201cpublic\u201d directory and unpack the folder \u201ccodebase\u201d from the Gantt\u2019s package into it. The whole files\u2019 structure should look as follows:<\/p>\n<p><\/br><br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen4.png\" alt=\"unpack_gantt\" width=\"600\" height=\"343\" class=\"aligncenter size-full wp-image-2419\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen4.png 600w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen4-300x171.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><br \/>\n<\/br><\/p>\n<p>In the \u201cpublic\u201d directory let\u2019s create \u201cindex.html\u201d file &#8211; the main page where we\u2019ll place a calendar.<\/p>\n<div class=\"codecolorer-container html4strict default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"html4strict codecolorer\"><span class=\"sc0\">&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\">http-equiv<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;Content-type&quot;<\/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<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">head<\/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\/dhtmlxgantt.js&quot;<\/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;&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\/dhtmlxgantt.css&quot;<\/span> <span class=\"kw3\">type<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;text\/css&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; <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>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; html, body{ height:100%; padding:0px; margin:0px; overflow: hidden;}<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=\"kw2\">body<\/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;gantt_here&quot;<\/span> <span class=\"kw3\">style<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">'width:100%; height:100%;'<\/span>&gt;&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; &nbsp; <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>&gt;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; gantt.config.xml_date = &quot;%Y-%m-%d %H:%i:%s&quot;;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; gantt.init(&quot;gantt_here&quot;);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; gantt.load(&quot;\/data&quot;);<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; var dp = new dataProcessor(&quot;\/data&quot;);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; dp.init(gantt);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; dp.setTransactionMode(&quot;POST&quot;, false);<br \/>\n&nbsp; &nbsp; <span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">script<\/span>&gt;<\/span><br \/>\n<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">body<\/span>&gt;<\/span><\/div><\/div>\n<p>So, there is no need in more HTML code for the Gantt. There are two includes for js and css files of Gantt. After it code to init gantt comes. Code contains instructions for data loading and data saving, for which we still don&#8217;t have a server side code, we will add it later.<\/p>\n<p>To see whether the app works right, we may start the node.js server and open https:\/\/localhost:3000 address in a browser. If everything is done correctly, we will see an empty gantt. To start nodejs server, run &#8220;nodejs app.js&#8221; command.<\/p>\n<p><\/br><br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen3.png\" alt=\"dhtmlxgantt-empty\" width=\"600\" height=\"130\" class=\"aligncenter size-full wp-image-2418\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen3.png 600w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen3-300x65.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><br \/>\n<\/br><br \/>\n<strong>Step 2 &#8211; Loading events<\/strong><\/p>\n<p>We\u2019ll start with loading some random data in the database:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">INSERT INTO `gantt_tasks` VALUES <span class=\"br0\">&#40;<\/span><span class=\"st0\">'1'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'Project #1'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2013-04-01 00:00:00'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'5'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'0.8'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'20'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'0'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nINSERT INTO `gantt_tasks` VALUES <span class=\"br0\">&#40;<\/span><span class=\"st0\">'2'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'Task #1'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2013-04-06 00:00:00'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'4'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'0.5'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'10'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'1'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nINSERT INTO `gantt_tasks` VALUES <span class=\"br0\">&#40;<\/span><span class=\"st0\">'3'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'Task #2'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2013-04-05 00:00:00'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'6'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'0.7'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'20'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'1'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nINSERT INTO `gantt_tasks` VALUES <span class=\"br0\">&#40;<\/span><span class=\"st0\">'4'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'Task #3'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2013-04-07 00:00:00'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'0'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'30'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'1'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nINSERT INTO `gantt_tasks` VALUES <span class=\"br0\">&#40;<\/span><span class=\"st0\">'5'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'Task #1.1'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2013-04-05 00:00:00'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'5'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'0.34'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'10'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nINSERT INTO `gantt_tasks` VALUES <span class=\"br0\">&#40;<\/span><span class=\"st0\">'6'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'Task #1.2'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2013-04-11 13:22:17'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'4'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'0.491477'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'20'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nINSERT INTO `gantt_tasks` VALUES <span class=\"br0\">&#40;<\/span><span class=\"st0\">'7'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'Task #2.1'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2013-04-07 00:00:00'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'5'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'0.2'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'10'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'3'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nINSERT INTO `gantt_tasks` VALUES <span class=\"br0\">&#40;<\/span><span class=\"st0\">'8'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'Task #2.2'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'2013-04-06 00:00:00'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'4'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'0.9'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'20'<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">'3'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>after that we can add a handler for data loading in app.js<\/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\">'\/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\">query<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;SELECT * FROM gantt_tasks&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span>err<span class=\"sy0\">,<\/span> rows<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> console.<span class=\"me1\">log<\/span><span class=\"br0\">&#40;<\/span>err<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; db.<span class=\"me1\">query<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;SELECT * FROM gantt_links&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span>err<span class=\"sy0\">,<\/span> links<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>err<span class=\"br0\">&#41;<\/span> console.<span class=\"me1\">log<\/span><span class=\"br0\">&#40;<\/span>err<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &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> rows.<span class=\"me1\">length<\/span><span class=\"sy0\">;<\/span> i<span class=\"sy0\">++<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rows<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span>.<span class=\"me1\">start_date<\/span> <span class=\"sy0\">=<\/span> rows<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span>.<span class=\"me1\">start_date<\/span>.<span class=\"me1\">format<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;YYYY-MM-DD&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rows<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span>.<span class=\"me1\">open<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw2\">true<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res.<span class=\"me1\">send<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span> data<span class=\"sy0\">:<\/span>rows<span class=\"sy0\">,<\/span> collections<span class=\"sy0\">:<\/span> <span class=\"br0\">&#123;<\/span> links <span class=\"sy0\">:<\/span> links <span class=\"br0\">&#125;<\/span> <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/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>\u201c\/data&#8221; handler will be used to load data into the gantt. Here we select all records from tasks and links table, and send them to the client-side as json structure.<\/p>\n<p>NOTE: before sending the records we convert start_date parameter to the string in Year-month-day format. Also, we have set &#8220;open&#8221; property for each item. It will force gantt to have all branches opened after data loading. <\/p>\n<p>After restarting the server and opening in browser http:\/\/localhost:3000 &#8211; there will be our gantt with tasks inside. <\/p>\n<p><\/br><br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen1.png\" alt=\"dhtmlxGantt-with-data\" width=\"600\" height=\"176\" class=\"aligncenter size-full wp-image-2416\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen1.png 600w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2014\/08\/screen1-300x88.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><br \/>\n<\/br><br \/>\n<strong>Step 3 &#8211; Adding \/ deleting \/ editing <\/strong><\/p>\n<p>Let\u2019s go to the server code and add one more handler to app.js:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;height:600px;\"><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&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=\"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<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><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span class=\"me1\">log<\/span><span class=\"br0\">&#40;<\/span>err<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/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=\"br0\">&#125;<\/span><br \/>\n<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> result.<span class=\"me1\">insertId<\/span><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;text\/xml&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=\"st0\">&quot;&lt;data&gt;&lt;action type='&quot;<\/span><span class=\"sy0\">+<\/span>mode<span class=\"sy0\">+<\/span><span class=\"st0\">&quot;' sid='&quot;<\/span><span class=\"sy0\">+<\/span>sid<span class=\"sy0\">+<\/span><span class=\"st0\">&quot;' tid='&quot;<\/span><span class=\"sy0\">+<\/span>tid<span class=\"sy0\">+<\/span><span class=\"st0\">&quot;'\/&gt;&lt;\/data&gt;&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>req.<span class=\"me1\">query<\/span>.<span class=\"me1\">gantt_mode<\/span> <span class=\"sy0\">==<\/span> <span class=\"st0\">&quot;links&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/save links<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <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; &nbsp; &nbsp; db.<span class=\"me1\">query<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;DELETE FROM gantt_links WHERE id = ?&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">&#91;<\/span>sid<span class=\"br0\">&#93;<\/span><span class=\"sy0\">,<\/span> update_response<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">else<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> source &nbsp;<span class=\"sy0\">=<\/span> data.<span class=\"me1\">source<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> target &nbsp;<span class=\"sy0\">=<\/span> data.<span class=\"me1\">target<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> type &nbsp; &nbsp;<span class=\"sy0\">=<\/span> data.<span class=\"me1\">type<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <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; &nbsp; &nbsp; db.<span class=\"me1\">query<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;INSERT INTO gantt_links(source, target, type) VALUES (?,?,?)&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#91;<\/span>source<span class=\"sy0\">,<\/span> target<span class=\"sy0\">,<\/span> type<span class=\"br0\">&#93;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; update_response<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">else<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &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&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n<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; <span class=\"co1\">\/\/save data<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <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; &nbsp; &nbsp; db.<span class=\"me1\">query<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;DELETE FROM gantt_tasks WHERE id = ?&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">&#91;<\/span>sid<span class=\"br0\">&#93;<\/span><span class=\"sy0\">,<\/span> update_response<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">else<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> text &nbsp; &nbsp; &nbsp; &nbsp;<span class=\"sy0\">=<\/span> data.<span class=\"me1\">text<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> start_date &nbsp;<span class=\"sy0\">=<\/span> data.<span class=\"me1\">start_date<\/span>.<span class=\"me1\">date<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;YYYY-MM-DD&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> duration &nbsp; &nbsp;<span class=\"sy0\">=<\/span> data.<span class=\"me1\">duration<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> progress &nbsp; &nbsp;<span class=\"sy0\">=<\/span> data.<span class=\"me1\">progress<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">var<\/span> parent &nbsp; &nbsp; &nbsp;<span class=\"sy0\">=<\/span> data.<span class=\"me1\">parent<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &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; &nbsp; &nbsp; &nbsp; &nbsp; db.<span class=\"me1\">query<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;UPDATE gantt_tasks SET text = ?, start_date = ?, duration = ?, progress = ?, parent = ? WHERE id = ?&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#91;<\/span>text<span class=\"sy0\">,<\/span> start_date<span class=\"sy0\">,<\/span> duration<span class=\"sy0\">,<\/span> progress<span class=\"sy0\">,<\/span> parent<span class=\"sy0\">,<\/span> sid<span class=\"br0\">&#93;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; update_response<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &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; &nbsp; &nbsp; db.<span class=\"me1\">query<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;INSERT INTO gantt_tasks(text, start_date, duration, progress, parent) VALUES (?,?,?,?,?)&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#91;<\/span>text<span class=\"sy0\">,<\/span> start_date<span class=\"sy0\">,<\/span> duration<span class=\"sy0\">,<\/span> progress<span class=\"sy0\">,<\/span> parent<span class=\"br0\">&#93;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; update_response<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">else<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &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&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Here we use &#8220;app.post&#8221;, as all saving operations use POST queries. The first part of the code shows 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>Then, according to the operation type, we carry out the necessary sql query. We have two major blocks &#8211; data operations for tasks and data operations for links. In each block we have separate sql code for each type of operation (adding\/saving\/deleting). As the operations with database are asynchronous, we pass the specified earlier callback function &#8220;update_response&#8221; as the last parameter. The client side expects to get the confirmation of saving operation or an error message &#8211; this is what the \u201cupdate_response\u201d function is responsible for. It generates an XML response in the necessary format and sends it to the client side. (Details of the format you may learn from the documentation ). If we add a new record, this function also includes ID, generated by MySQL for the new record, into the response to update the element&#8217;s id on the client&#8217;s side, too.<\/p>\n<p>If we restart the server and open http:\/\/localhost:3000 in browser again, we&#8217;ll get a gantt with tasks. Clicking on &#8220;Add &#8221; button will add new task to the gantt. Double-clicking or dragging the task will allow modifying the task properties or deleting the task. The cool feature is the availability of all the changes even after reloading the page as they\u2019re automatically saved in database.<\/p>\n<p><strong>What is the result?<\/strong><\/p>\n<p>The server solution is quite simple and can be easily customized. It won&#8217;t be difficult to add validation or some kind of data formatting before loading. As Node.js allows using JavaScript on server side, we use the same concepts on both client side and server side, which definitely makes result code more compact and stable. But it also stands to mention that dhtmlxGantt is flexible enough, and integration with any other server side platform will not require much of coding.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you follow our tutorials, you have already known how to use dhtmlxScheduler and dhtmlxGrid with Node.js, a flexible JavaScript platform. This time we will deal with dhtmlxGantt with &#8230;<\/p>\n","protected":false},"author":2,"featured_media":3800,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[71,1],"tags":[33,20,14,39],"class_list":["post-2393","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","category-uncategorized","tag-all-posts","tag-gantt","tag-tips","tag-nodejs"],"_links":{"self":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/2393","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=2393"}],"version-history":[{"count":1,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/2393\/revisions"}],"predecessor-version":[{"id":8775,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/2393\/revisions\/8775"}],"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=2393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/categories?post=2393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/tags?post=2393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}