{"id":14265,"date":"2025-08-07T17:17:57","date_gmt":"2025-08-07T14:17:57","guid":{"rendered":"https:\/\/dhtmlx.com\/blog\/?p=14265"},"modified":"2025-08-07T20:25:57","modified_gmt":"2025-08-07T17:25:57","slug":"creating-task-backlog-drag-drop-support-dhtmlx-scheduler","status":"publish","type":"post","link":"https:\/\/dhtmlx.com\/blog\/creating-task-backlog-drag-drop-support-dhtmlx-scheduler\/","title":{"rendered":"Creating Task Backlog with Drag-and-Drop Support in DHTMLX Scheduler"},"content":{"rendered":"<p>Users\u2019 feedback is a vital source of information for enhancing our JavaScript UI components with highly-demanded features. Responding to requests from DHTMLX customers, we can not only solve issues in specific scenarios but also may result in new stable features for our products. One such story has become the foundation for this tutorial that walks you through the process of complementing a JavaScript calendar with a backlog for scheduling tasks with drag-and-drop. <\/p>\n<h5>Prerequisites<\/h5>\n<p>One of our <a href=\"https:\/\/dhtmlx.com\/docs\/products\/dhtmlxScheduler\/\" rel=\"noopener\" target=\"_blank\">JavaScript Scheduler<\/a> customers inquired about the possibility of assigning tasks to available resources (employees) from the backlog using simple drag and drop operations like in property management systems. This functionality can significantly simplify users\u2019 scheduling experience, enabling them to easily drag tasks to the required slot in the timeline from a separate list (backlog) instead of manually assigning dates and resources.<\/p>\n<p>DHTMLX Scheduler doesn\u2019t have built-in support for this functionality, but this behavior can be implemented manually using the extensive API of our component. To prove this point, our team prepared a demo that demonstrates how the backlog with drag-and-drop support works in a JS calendar built with DHTMLX.<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2025\/08\/backlog.gif\" alt=\"backlog with drag-and-drop support\" width=\"1856\" height=\"796\" class=\"aligncenter size-full wp-image-14278\" \/><a href=\"https:\/\/snippet.dhtmlx.com\/d59udhhx?text=scheduler&#038;mode=wide\" rel=\"noopener\" target=\"_blank\">Check the sample ><\/a><\/p>\n<p>To achieve a similar goal programmatically, you should implement the following:<\/p>\n<ul>\n<li>Render draggable backlog cards.<\/li>\n<li>Highlight time slots when dragging.<\/li>\n<li>Calculate the dragged event position in Scheduler and insert it when the event is dropped.<\/li>\n<\/ul>\n<p>In the following sections, we\u2019ll explain these and other steps that should be taken to make it work like in our demo.  <\/p>\n<h5>Step 1: Scheduler Initialization<\/h5>\n<p>It is not hard to guess that the first step to take is to initialize the Scheduler component. At this point, you configure Scheduler views and enable necessary plugins.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">scheduler.<span class=\"me1\">plugins<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; units<span class=\"sy0\">:<\/span> <span class=\"kw2\">true<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; timeline<span class=\"sy0\">:<\/span> <span class=\"kw2\">true<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; tooltip<span class=\"sy0\">:<\/span> <span class=\"kw2\">true<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; quick_info<span class=\"sy0\">:<\/span> <span class=\"kw2\">true<\/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>You should use <a href=\"https:\/\/docs.dhtmlx.com\/scheduler\/api__scheduler_first_hour_config.html\" rel=\"noopener\" target=\"_blank\">scheduler.config.first_hour<\/a> and <a href=\"https:\/\/docs.dhtmlx.com\/scheduler\/api__scheduler_last_hour_config.html\" rel=\"noopener\" target=\"_blank\">scheduler.config.last_hour<\/a> properties to set the necessary timeframe, including only working hours (06:00 &#8211; 20:00), and show it in Scheduler.<\/p>\n<p>You&#8217;ll also need a shared store object to manage tasks across the application. It allows updating, adding, or removing tasks in one place and ensuring that both the backlog and the scheduler reflect the same data.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;height:600px;\"><div class=\"javascript codecolorer\"><span class=\"kw5\">export<\/span> <span class=\"kw1\">const<\/span> store <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; let tasks <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; let units <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; let priorities <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"kw1\">const<\/span> subs <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> Set<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">const<\/span> notify <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> subs.<span class=\"me1\">forEach<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span>fn<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> fn<span class=\"br0\">&#40;<\/span>getState<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">const<\/span> deepObjClone <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span>obj<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> JSON.<span class=\"me1\">parse<\/span><span class=\"br0\">&#40;<\/span>JSON.<span class=\"me1\">stringify<\/span><span class=\"br0\">&#40;<\/span>obj<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">const<\/span> toUnitsList <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span>units<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span><br \/>\n&nbsp; &nbsp; units.<span class=\"me1\">map<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span>unit<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; key<span class=\"sy0\">:<\/span> unit.<span class=\"me1\">id<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; label<span class=\"sy0\">:<\/span> unit.<span class=\"me1\">name<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"kw1\">const<\/span> getState <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; tasks<span class=\"sy0\">:<\/span> deepObjClone<span class=\"br0\">&#40;<\/span>tasks<span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; units<span class=\"sy0\">:<\/span> deepObjClone<span class=\"br0\">&#40;<\/span>units<span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; priorities<span class=\"sy0\">:<\/span> deepObjClone<span class=\"br0\">&#40;<\/span>priorities<span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"kw1\">return<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; getState<span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; toUnitsList<span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; init<span class=\"br0\">&#40;<\/span>data<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; tasks <span class=\"sy0\">=<\/span> data.<span class=\"me1\">tasks<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; units <span class=\"sy0\">=<\/span> data.<span class=\"me1\">units<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; priorities <span class=\"sy0\">=<\/span> data.<span class=\"me1\">priorities<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; notify<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; upsertTask<span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; <span class=\"kw1\">const<\/span> idx <span class=\"sy0\">=<\/span> tasks.<span class=\"me1\">findIndex<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span>t<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> t.<span class=\"me1\">id<\/span> <span class=\"sy0\">===<\/span> task.<span class=\"me1\">id<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; idx <span class=\"sy0\">===<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span> <span class=\"sy0\">?<\/span> tasks.<span class=\"me1\">push<\/span><span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">:<\/span> tasks.<span class=\"me1\">splice<\/span><span class=\"br0\">&#40;<\/span>idx<span class=\"sy0\">,<\/span> <span class=\"nu0\">1<\/span><span class=\"sy0\">,<\/span> task<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; notify<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; deleteTask<span class=\"br0\">&#40;<\/span>id<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; tasks <span class=\"sy0\">=<\/span> tasks.<span class=\"me1\">filter<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span>t<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> t.<span class=\"me1\">id<\/span> <span class=\"sy0\">!==<\/span> id<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; notify<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; subscribe<span class=\"br0\">&#40;<\/span>fn<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; subs.<span class=\"me1\">add<\/span><span class=\"br0\">&#40;<\/span>fn<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; fn<span class=\"br0\">&#40;<\/span>getState<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> subs.<span class=\"kw1\">delete<\/span><span class=\"br0\">&#40;<\/span>fn<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; getTaskById<span class=\"br0\">&#40;<\/span>id<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> tasks.<span class=\"me1\">find<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> task.<span class=\"me1\">id<\/span> <span class=\"sy0\">===<\/span> id<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; <span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>To display only weekdays, use the built-in <strong><a href=\"https:\/\/docs.dhtmlx.com\/scheduler\/custom_scales.html#:~:text=the%20ignore_%7BviewName%7D%20method\" rel=\"noopener\" target=\"_blank\">ignore_{viewName}<\/a><\/strong> method:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">scheduler.<span class=\"me1\">ignore_unit<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span>date<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">return<\/span> date.<span class=\"me1\">getDay<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">==<\/span> <span class=\"nu0\">6<\/span> <span class=\"sy0\">||<\/span> date.<span class=\"me1\">getDay<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">==<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><br \/>\nscheduler.<span class=\"me1\">ignore_timeline<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span>date<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">return<\/span> date.<span class=\"me1\">getDay<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">==<\/span> <span class=\"nu0\">6<\/span> <span class=\"sy0\">||<\/span> date.<span class=\"me1\">getDay<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">==<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<h5>Step 2: Rendering of Backlog Tasks<\/h5>\n<p>Now, you can move on to displaying the list of unscheduled tasks (backlog). For this purpose, you need to dynamically create HTML elements based on the task data from the store object. Each task card is made draggable so that it can be dragged into the scheduler timeline.<\/p>\n<p>When a user starts dragging a task card, the <strong>dragstart<\/strong> event is triggered. In this handler, you perform several important actions:<\/p>\n<p><strong>1) Add visual feedback<\/strong><br \/>\nYou add the <strong>dragging-task<\/strong> class to the element to visually indicate it&#8217;s being dragged.<\/p>\n<p><strong>2) Attach task data to the drag event<\/strong><br \/>\nYou retrieve the <strong>task<\/strong> object from the <strong>store<\/strong> using its <strong>id<\/strong>, then serialize and attach it to the drag event using the <strong>e.dataTransfer.setData()<\/strong> method. This allows you to extract and use the task data later when it\u2019s dropped onto the timeline.<\/p>\n<p><strong>3) Customize the drag image<\/strong><br \/>\nBy default, browsers display a semi-transparent snapshot of the dragged element, which may appear plain or even invisible. To fix this, you create a copy of the dragged element using <strong>cloneNode<\/strong>, assign it a custom class (<strong>drag-img<\/strong>) for styling, and append it to the document body.<\/p>\n<p>Then, you pass this element to <strong>e.dataTransfer.setDragImage()<\/strong>, so the browser displays a custom image during the drag operation. This improves the user experience and ensures consistent visuals across browsers.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">listItem.<span class=\"me1\">addEventListener<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;dragstart&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">&#40;<\/span>e<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>e.<span class=\"me1\">target<\/span>.<span class=\"me1\">matches<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.uncheduled-task-card&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; e.<span class=\"me1\">target<\/span>.<span class=\"me1\">classList<\/span>.<span class=\"me1\">add<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;dragging-task&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">const<\/span> task <span class=\"sy0\">=<\/span> store.<span class=\"me1\">getState<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">tasks<\/span>.<span class=\"me1\">find<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span>t<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> t.<span class=\"me1\">id<\/span> <span class=\"sy0\">==<\/span> e.<span class=\"me1\">target<\/span>.<span class=\"me1\">dataset<\/span>.<span class=\"me1\">id<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; e.<span class=\"me1\">dataTransfer<\/span>.<span class=\"me1\">clearData<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; e.<span class=\"me1\">dataTransfer<\/span>.<span class=\"me1\">setData<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;application\/json&quot;<\/span><span class=\"sy0\">,<\/span> JSON.<span class=\"me1\">stringify<\/span><span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">const<\/span> dragImage <span class=\"sy0\">=<\/span> e.<span class=\"me1\">target<\/span>.<span class=\"me1\">cloneNode<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw2\">true<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; dragImage.<span class=\"me1\">removeAttribute<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;id&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; dragImage.<span class=\"me1\">removeAttribute<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;data-id&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; dragImage.<span class=\"me1\">classList<\/span>.<span class=\"me1\">add<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;drag-img&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; document.<span class=\"me1\">body<\/span>.<span class=\"me1\">appendChild<\/span><span class=\"br0\">&#40;<\/span>dragImage<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; e.<span class=\"me1\">dataTransfer<\/span>.<span class=\"me1\">setDragImage<\/span><span class=\"br0\">&#40;<\/span>dragImage<span class=\"sy0\">,<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">0<\/span><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><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>When a user stops dragging (regardless of whether the task was dropped successfully), the <strong>dragend<\/strong> event is fired:<\/p>\n<ol>\n<li>You remove the <strong>dragging-task<\/strong> class to reset the task card style.<\/li>\n<li>You remove the temporary <strong>drag-img<\/strong> element from the DOM to keep things clean.<\/li>\n<\/ol>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">listItem.<span class=\"me1\">addEventListener<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;dragend&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">&#40;<\/span>e<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; e.<span class=\"me1\">target<\/span>.<span class=\"me1\">classList<\/span>.<span class=\"me1\">remove<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;dragging-task&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; document.<span class=\"me1\">body<\/span>.<span class=\"me1\">removeChild<\/span><span class=\"br0\">&#40;<\/span>document.<span class=\"me1\">querySelector<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.drag-img&quot;<\/span><span class=\"br0\">&#41;<\/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<h5>Step 3: Highlight Drop Time Slots<\/h5>\n<p>In this step, you can improve the drag-and-drop experience by complementing your JavaScript Scheduler with a visual highlight. It appears when a task is dragged over a valid time slot, thereby helping end-users understand where the task would be scheduled if dropped. This feature is implemented with the help of the <strong><a href=\"https:\/\/docs.dhtmlx.com\/scheduler\/api__scheduler_marktimespan.html\" rel=\"noopener\" target=\"_blank\">markTimespan()<\/a><\/strong> method.<\/p>\n<p>In the <strong>dragover<\/strong> event handler, you check whether the pointer is currently over a valid time slot (<strong>.dhx_scale_time_slot<\/strong> or <strong>.dhx_timeline_data_cell<\/strong>). If not, the event is ignored:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> slot <span class=\"sy0\">=<\/span> e.<span class=\"me1\">target<\/span>.<span class=\"me1\">closest<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.dhx_scale_time_slot&quot;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">||<\/span> e.<span class=\"me1\">target<\/span>.<span class=\"me1\">closest<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.dhx_timeline_data_cell&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span><span class=\"sy0\">!<\/span>slot<span class=\"br0\">&#41;<\/span> <span class=\"kw1\">return<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>After that, you should do the following:<\/p>\n<ul>\n<li>Extract the task\u2019s name and duration from the dragged element<\/li>\n<li>Retrieve the proposed start date and target section for scheduling using <a href=\"https:\/\/docs.dhtmlx.com\/scheduler\/api__scheduler_getactiondata.html\" rel=\"noopener\" target=\"_blank\">scheduler.getActionData(e)<\/a><\/li>\n<li>Calculate the end date by passing the start date and task duration to the <strong>calcEndDate()<\/strong> function<\/li>\n<\/ul>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> taskName <span class=\"sy0\">=<\/span> draggedEl.<span class=\"me1\">querySelector<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.task-name&quot;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">textContent<\/span> <span class=\"sy0\">||<\/span> <span class=\"st0\">&quot;&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">const<\/span> taskDuration <span class=\"sy0\">=<\/span> <span class=\"sy0\">+<\/span>draggedEl.<span class=\"me1\">dataset<\/span>.<span class=\"me1\">taskDuration<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">const<\/span> <span class=\"br0\">&#123;<\/span> date<span class=\"sy0\">:<\/span> start_date<span class=\"sy0\">,<\/span> section <span class=\"br0\">&#125;<\/span> <span class=\"sy0\">=<\/span> scheduler.<span class=\"me1\">getActionData<\/span><span class=\"br0\">&#40;<\/span>e<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">const<\/span> end_date <span class=\"sy0\">=<\/span> calcEndDate<span class=\"br0\">&#40;<\/span>start_date<span class=\"sy0\">,<\/span> taskDuration<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>If there\u2019s a highlighted timeslot, you remove it using the <strong><a href=\"https:\/\/docs.dhtmlx.com\/scheduler\/api__scheduler_unmarktimespan.html\" rel=\"noopener\" target=\"_blank\">unmarkTimespan()<\/a><\/strong> method and reset the tracking variable via <strong>currentMarkTime = null<\/strong>:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>currentMarkTime <span class=\"sy0\">&amp;&amp;<\/span> currentMarkTime.<span class=\"me1\">length<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; scheduler.<span class=\"me1\">unmarkTimespan<\/span><span class=\"br0\">&#40;<\/span>currentMarkTime<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; currentMarkTime <span class=\"sy0\">=<\/span> <span class=\"kw2\">null<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>After that, you highlight a new time range using <strong>scheduler.markTimespan()<\/strong> and stored in <strong>currentMarkTime<\/strong>:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">currentMarkTime <span class=\"sy0\">=<\/span> scheduler.<span class=\"me1\">markTimespan<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; start_date<span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; end_date<span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; css<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;timeslot-highlight-marktime&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; sections<span class=\"sy0\">:<\/span> <span class=\"br0\">&#123;<\/span> unit<span class=\"sy0\">:<\/span> section<span class=\"sy0\">,<\/span> timeline<span class=\"sy0\">:<\/span> <span class=\"br0\">&#91;<\/span>section<span class=\"br0\">&#93;<\/span> <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; html<span class=\"sy0\">:<\/span> `<span class=\"sy0\">&lt;<\/span>div<span class=\"sy0\">&gt;<\/span>$<span class=\"br0\">&#123;<\/span>scheduler.<span class=\"me1\">templates<\/span>.<span class=\"me1\">event_date<\/span><span class=\"br0\">&#40;<\/span>start_date<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#125;<\/span> <span class=\"sy0\">-<\/span> $<span class=\"br0\">&#123;<\/span>scheduler.<span class=\"me1\">templates<\/span>.<span class=\"me1\">event_date<\/span><span class=\"br0\">&#40;<\/span>end_date<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy0\">&lt;\/<\/span>div<span class=\"sy0\">&gt;<\/span><br \/>\n<span class=\"sy0\">&lt;<\/span>div<span class=\"sy0\">&gt;<\/span>$<span class=\"br0\">&#123;<\/span>taskName<span class=\"br0\">&#125;<\/span><span class=\"sy0\">&lt;\/<\/span>div<span class=\"sy0\">&gt;<\/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>You also add an event listener for the <strong>dragleave<\/strong> event. If the pointer moves outside the scheduler area entirely (not just between cells), the highlight is removed by calling <strong>scheduler.unmarkTimespan()<\/strong> to prevent displaying a stale visual indicator.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">dropZone.<span class=\"me1\">addEventListener<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;dragleave&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">&#40;<\/span>e<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> related <span class=\"sy0\">=<\/span> e.<span class=\"me1\">relatedTarget<\/span> <span class=\"sy0\">||<\/span> document.<span class=\"me1\">elementFromPoint<\/span><span class=\"br0\">&#40;<\/span>e.<span class=\"me1\">clientX<\/span><span class=\"sy0\">,<\/span> e.<span class=\"me1\">clientY<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> stillInside <span class=\"sy0\">=<\/span> related<span class=\"sy0\">?<\/span>.<span class=\"me1\">closest<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.dhx_scale_time_slot&quot;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">||<\/span> related<span class=\"sy0\">?<\/span>.<span class=\"me1\">closest<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.dhx_timeline_data_cell&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>stillInside<span class=\"br0\">&#41;<\/span> <span class=\"kw1\">return<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; highlightedTimeSlot <span class=\"sy0\">=<\/span> <span class=\"kw2\">null<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>currentMarkTime<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">unmarkTimespan<\/span><span class=\"br0\">&#40;<\/span>currentMarkTime<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; currentMarkTime <span class=\"sy0\">=<\/span> <span class=\"kw2\">null<\/span><span class=\"sy0\">;<\/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<h5>Step 4: Convert a Dragged Item into a Scheduled Task on Drop<\/h5>\n<p>When an end-user drops the task onto the scheduler, you convert the backlog item into the actual event in the following way:<\/p>\n<ul>\n<li>Clear the highlight by removing the current <strong>markTimespan<\/strong>.<\/li>\n<li>Retrieve the task data from the <strong>dataTransfer<\/strong> object. This was serialized earlier during the <strong>dragstart<\/strong> event.<\/li>\n<li>Determine the drop position using <strong>scheduler.getActionData(e)<\/strong>, which provides the proposed start date and target section (resource).<\/li>\n<li>Calculate the end date using the <strong>calcEndDate<\/strong> function.<\/li>\n<li>Update the store using <strong>upsertTask<\/strong>, saving the task with its new <strong>start_date<\/strong>, <strong>end_date<\/strong>, and <strong>owner_id<\/strong>.<\/li>\n<\/ul>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">dropZone.<span class=\"me1\">addEventListener<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;drop&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">&#40;<\/span>e<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; e.<span class=\"me1\">preventDefault<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> slot <span class=\"sy0\">=<\/span> e.<span class=\"me1\">target<\/span>.<span class=\"me1\">closest<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.dhx_scale_time_slot&quot;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">||<\/span> e.<span class=\"me1\">target<\/span>.<span class=\"me1\">closest<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.dhx_timeline_data_cell&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>slot<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; highlightedTimeSlot <span class=\"sy0\">=<\/span> <span class=\"kw2\">null<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>currentMarkTime <span class=\"sy0\">&amp;&amp;<\/span> currentMarkTime.<span class=\"me1\">length<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; scheduler.<span class=\"me1\">unmarkTimespan<\/span><span class=\"br0\">&#40;<\/span>currentMarkTime<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentMarkTime <span class=\"sy0\">=<\/span> <span class=\"kw2\">null<\/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<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> data <span class=\"sy0\">=<\/span> JSON.<span class=\"me1\">parse<\/span><span class=\"br0\">&#40;<\/span>e.<span class=\"me1\">dataTransfer<\/span>.<span class=\"me1\">getData<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;application\/json&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> <span class=\"br0\">&#123;<\/span> date<span class=\"sy0\">,<\/span> section <span class=\"br0\">&#125;<\/span> <span class=\"sy0\">=<\/span> scheduler.<span class=\"me1\">getActionData<\/span><span class=\"br0\">&#40;<\/span>e<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> start_date <span class=\"sy0\">=<\/span> date<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> end_date <span class=\"sy0\">=<\/span> calcEndDate<span class=\"br0\">&#40;<\/span>start_date<span class=\"sy0\">,<\/span> data.<span class=\"me1\">duration<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; store.<span class=\"me1\">upsertTask<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span> ...<span class=\"me1\">data<\/span><span class=\"sy0\">,<\/span> start_date<span class=\"sy0\">,<\/span> end_date<span class=\"sy0\">,<\/span> owner_id<span class=\"sy0\">:<\/span> section <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<h5>Step 5: Unschedule a Task and Return it to Backlog<\/h5>\n<p>In the last step, you add the ability to &#8220;unschedule&#8221; a task and send it back to the backlog. It can be done by adding a corresponding button inside the scheduler\u2019s lightbox and the quick info extension.<\/p>\n<p>In the lightbox, the button is added to the left side of the control panel:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">scheduler.<span class=\"me1\">config<\/span>.<span class=\"me1\">buttons_left<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><span class=\"st0\">&quot;dhx_save_btn&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;dhx_cancel_btn&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;unschedule_button&quot;<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; scheduler.<span class=\"me1\">locale<\/span>.<span class=\"me1\">labels<\/span><span class=\"br0\">&#91;<\/span><span class=\"st0\">&quot;unschedule_button&quot;<\/span><span class=\"br0\">&#93;<\/span> <span class=\"sy0\">=<\/span> <span class=\"st0\">&quot;Unschedule&quot;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>For quick info, you define a custom icon and handle its click:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">scheduler.<span class=\"me1\">config<\/span>.<span class=\"me1\">icons_select<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><span class=\"st0\">&quot;icon_unschedule&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;icon_details&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;icon_delete&quot;<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; scheduler.<span class=\"me1\">locale<\/span>.<span class=\"me1\">labels<\/span>.<span class=\"me1\">icon_unschedule<\/span> <span class=\"sy0\">=<\/span> <span class=\"st0\">&quot;Unschedule&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; scheduler._click.<span class=\"me1\">buttons<\/span>.<span class=\"me1\">unschedule<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>id<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; uncheduleEvent<span class=\"br0\">&#40;<\/span>id<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>The main logic resides in the <strong>unscheduleEvent<\/strong> function, which asks a user for confirmation and removes the task\u2019s scheduling-related data.<\/p>\n<p>That\u2019s all you need to know to enrich your JavaScript Scheduling calendar with a backlog for handling unscheduled tasks with drag-and-drop like our <a href=\"https:\/\/snippet.dhtmlx.com\/d59udhhx?text=scheduler&#038;mode=wide\" rel=\"noopener\" target=\"_blank\">sample<\/a>.<\/p>\n<h5>Conclusion<\/h5>\n<p>In this tutorial, you\u2019ve learned how to extend a JavaScript scheduling calendar with a task backlog and seamless drag-and-drop support for planning and unplanning tasks. This solution enables end-users to manage their schedules more flexibly and intuitively. It can come in handy when you need to boost productivity in real-world scheduling apps built with DHTMLX. Doubt it? Download a <a href=\"https:\/\/dhtmlx.com\/docs\/products\/dhtmlxScheduler\/download.shtml\" rel=\"noopener\" target=\"_blank\">free 30-day trial version<\/a> of DHTMLX Scheduler and give it a try. <\/p>\n<h5>Related Materials<\/h5>\n<ul>\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\/?sample=%2701_initialization_loading\/01_basic_init.html%27&#038;filter=%27%27\" rel=\"noopener\" target=\"_blank\">DHTMLX Scheduler samples<\/a><\/li>\n<li><a href=\"https:\/\/dhtmlx.com\/blog\/tutorials\/?tag=dhtmlxscheduler\" rel=\"noopener\" target=\"_blank\">DHTMLX Scheduler tutorials<\/a><\/li>\n<li><a href=\"https:\/\/dhtmlx.com\/docs\/products\/dhtmlxScheduler\/download.shtml\" rel=\"noopener\" target=\"_blank\">Free 30-day trial version<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Users\u2019 feedback is a vital source of information for enhancing our JavaScript UI components with highly-demanded features. Responding to requests from DHTMLX customers, we can not only solve issues &#8230;<\/p>\n","protected":false},"author":101014,"featured_media":14271,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[71],"tags":[33,15],"class_list":["post-14265","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\/14265","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=14265"}],"version-history":[{"count":10,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/14265\/revisions"}],"predecessor-version":[{"id":14267,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/14265\/revisions\/14267"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media\/14271"}],"wp:attachment":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media?parent=14265"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/categories?post=14265"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/tags?post=14265"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}