Technical Articles
SAPUI5: Drag item from a list and drop it on a Calendar row
INTRODUCTION
The planning calendar allows users to manage multiple appointments in the same view and to create or to delete those appointments. That gives the user excellent advantage to compare elements of the calendar to each other. But what if someone would like to drag items from an external SAPUI5 control and drop them on the calendar row?
In this tutorial, I’m going to explain how to drag and drop an item from a list and drop it on a planning calendar row,
This tutorial will rely on internal implementation of the Planning Calendar class which is, of course, bad practice .
“SAP might add, remove, or change the internal implementation of the parent class at any time. Especially, you should not rely on the following functionality “
But relying on a small portion of an internal implementation of the Planning Calendar will do the job
So far, this method is valid with the version 1.76.1 but don’t worry, I will explain how to use the foolproof method in a further tutorial
LET’S GET TO BUSINESS
Ok, let’s start by configuring a split app architecture really quick :
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="com.Innovation.ui5Project.controller.View1" xmlns:unified="sap.ui.unified" xmlns:dnd="sap.ui.core.dnd" displayBlock="true">
<Shell id="shell">
<SplitApp id="app" initialDetail="detail" initialMaster="master">
<detailPages>
<Page id="detail" title="Planning Calendar" backgroundDesign="Solid" class="sapUiStdPage">
</Page>
</detailPages>
<masterPages>
<Page id="master" title="List" backgroundDesign="List" icon="sap-icon://action" class="sapUiStdPage">
</Page>
</masterPages>
</SplitApp>
</Shell>
</mvc:View>
Now, I’m going to add the planning calendar control in the detail page and the list control in the main page :
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="com.Innovation.ui5Project.controller.View1" xmlns:unified="sap.ui.unified" xmlns:dnd="sap.ui.core.dnd" displayBlock="true">
<Shell id="shell">
<SplitApp id="app" initialDetail="detail" initialMaster="master">
<detailPages>
<Page id="detail" title="Planning Calendar" backgroundDesign="Solid" class="sapUiStdPage">
<PlanningCalendar id="PC1" startDate="{path: 'calendarModel>/startDate'}" rows="{path: 'calendarModel>/people'}" appointmentsVisualization="Filled">
<rows>
<PlanningCalendarRow title="{calendarModel>name}" text="{calendarModel>role}" enableAppointmentsDragAndDrop="true" enableAppointmentsResize="true" enableAppointmentsCreate="true" appointmentDrop="handleAppointmentDrop" appointmentDragEnter="handleAppointmentDragEnter" appointmentResize="handleAppointmentResize" appointmentCreate="handleAppointmentCreate" appointments="{calendarModel>appointments}">
<appointments>
<unified:CalendarAppointment startDate="{calendarModel>start}" endDate="{calendarModel>end}" icon="{calendarModel>pic}" title="{calendarModel>title}" text="{calendarModel>info}" type="{calendarModel>type}" tentative="{tentative}"></unified:CalendarAppointment>
</appointments>
</PlanningCalendarRow>
</rows>
</PlanningCalendar>
</Page>
</detailPages>
<masterPages>
<Page id="master" title="List" backgroundDesign="List" icon="sap-icon://action" class="sapUiStdPage">
<List id="idList" items="{listModel>/}" growing="true" growingThreshold="50" includeItemInSelection="false">
<infoToolbar>
<OverflowToolbar visible="false" id="idInfoToolbar">
<Label id="idFilterLabel"/>
</OverflowToolbar>
</infoToolbar>
<StandardListItem id="listItem" title="{listModel>ProductName}" description="{listModel>ShipperName}" icon="{listModel>ProductPicUrl}" iconDensityAware="false" iconInset="false"/>
</List>
</Page>
</masterPages>
</SplitApp>
</Shell>
</mvc:View>
I’m going to run my app on my localhost :
so far so good….notice we cannot drag anything from the list to the calendar but we can only drag and drop inside the calendar itself.
The Issue Explained
The fun part about the sap.m.PlanningCalendar’s drag and drop functionality is that we do not have to set up a DragDropInfo. As we all know, SAPUI5 developers are working hard day and night to make our life easier ?, the calendar provides built in functions to enable the events
When we define the :
enableAppointmentsDragAndDrop="true"
That property will enable dragging appointments within the same calendar row but also between different rows but not within the sap.m.list nor any external controllers ..
Of course, looking for other people to have encountered this problem, there are very few posts that feature this issue. Unfortunately, they are also unsolved.
So let’s start by implementing the drag and drop config for the list itself.
<dragDropConfig>
<dnd:DragDropInfo sourceAggregation="items" targetElement="PC1-Table" targetAggregation="items" dragEnter="onListPlanningCalendardragEnter" dragStart="onListPlanningCalendardragStart" drop="onListPlanningCalendarDrop"/>
</dragDropConfig>
Notice the target element:
targetElement="PC1-Table"
I’m concatenating my assigned Stable ID of my PC1
PlanningCalendar with the internal table’s ID. …………Yup we’re relying on internal inheritance — “I’ve warned you”
Let’s run again the code and I’m going to put a breakpoints on the event listener :
onListPlanningCalendarDrop: function(oEvent) {
var oDroppedControl = oEvent.getParameter("droppedControl");
var oDragSession = oEvent.getParameter("dragSession");
var cliId = oDroppedControl.getId();
var rowId = cliId.replace("-CLI", "");
var pcRow = sap.ui.getCore().byId(rowId);
var oBindingContext = pcRow.getBindingContext("calendarModel");
var resourceObj = oBindingContext.getObject();
var oDraggedRowContext = oDragSession.getComplexData("onListDragContext");
},
onListPlanningCalendardragStart: function(oEvent) {
var oDragSession = oEvent.getParameter("dragSession");
var oDraggedRow = oEvent.getParameter("target");
var oContextBinding = oDraggedRow.getBindingContext("listModel").getObject();
oDragSession.setComplexData("onListDragContext", oDraggedRow);
}
Eurêka!
Now we can get the item being dragged from the list and the row where I’m trying to dropped it
CONCLUSION
We know have a better understanding of the sap.m.PlanningCalendar internal drag and drop functionalities, those built in features provide event handlers for dragging and dropping appointments between rows and on the same row.
However to be able to drag and drop items from external controllers such as sap.m.List we must use the Stable ID of the Planning Calendar with the internal table’s ID and add it as a reference in the targetElement of the list controller. Using the internal table ID is not the best practice, because SAP could change that any day, any moment, any second without warnings and they’re absolutely right about that, because refactoring and restructuring is a crucial step for improving the SAPUI5 library. However, a more sophisticated approach is possible by configuring the drag and drop config inside the planning calendar. I will explain it in a further blog 🙂
You can clone my Sapui5ListCalendarDragDropapp or export it in the SAP Web IDE
Source code URL : https://github.com/Basselbi/Sapui5ListCalendarDragDrop.git
P.S: I’m using VSCode and the amazing UI5 tooling in my examples, but it’s also compatible with the web IDE
Mr Bass, great blog 🙂
Hi Bassel,
Really useful blog, thanks! Did you ever get round to this part? 😉
However, a more sophisticated approach is possible by configuring the drag and drop config inside the planning calendar. I will explain it in a further blog 🙂
I'd be interested in hearing how this is possible!
Regards
Gareth
How to get the appointment time where we dropped the list item.