Technical Articles
Planning Calendar in SAP UI5
Hi All,
In this blog post, I am going to explain a business scenario that I had gone through and how I gave a solution to it.
Business Scenario:
Develop a web application that shows a calendar showing which agent is assigned to jobs on which days at which location.
Solution:
I have designed and developed SAP UI5 Responsive Web Application using sap.m.planningcalendar which displays rows with appointments for different entities (such as persons or teams) for the selected time interval.
About Planning Calendar:
Planning Calendar containing multiple rows with appointments, where each row represents a different person.
We can configure different time-interval views that make us switch between, such as hours or days, and even a whole week/month. The available navigation allows us to select a specific interval using a picker, or move to the previous/next interval using arrows.
The PlanningCalendar uses parts of the sap.ui.unified library.
Logon to the Business Application Studio and follow the below steps.
Step 1:
Create a Sample Application named “Planning Calendar”.
Step 2.1: Open the View1.view.xml file and add the below libraries.
xmlns:core=”sap.ui.core”
xmlns:unified=”sap.ui.unified”
Step2.2: Add the below code.
<PlanningCalendar
id="PC1"
startDate="{path: '/startDate'}"
rows="{path: '/people'}"
appointmentsVisualization="Filled"
appointmentSelect="handleAppointmentSelect"
showEmptyIntervalHeaders="false"
showWeekNumbers="true">
<rows>
<PlanningCalendarRow
title="{name}"
appointments="{path : 'appointments', templateShareable: true}">
<appointments>
<unified:CalendarAppointment
startDate="{start}"
endDate="{end}"
title="{title}"
text="{info}"
type="{type}"
tentative="{tentative}">
</unified:CalendarAppointment>
</appointments>
</PlanningCalendarRow>
</rows>
</PlanningCalendar>
Step3:
Open the View1.controller.js file and add the below code.
onInit: function () {
// create model
var oModel = new JSONModel();
oModel.setData({
startDate: new Date("2020", "11", "01", "8", "0"),
people: [{
name: "Sunil",
appointments: [
{
start: new Date("2020", "11", "1", "08", "30"),
end: new Date("2020", "11", "8", "09", "30"),
title: "Telangana",
info: "Manikonda,Hyderabad",
type: "Type02",
tentative: false
},
{
start: new Date("2020", "11", "11", "10", "0"),
end: new Date("2020", "11", "11", "12", "0"),
title: "Andhra Pradesh",
info: "Balaji Colony,Tirupathi",
type: "Type01",
tentative: false
},
{
start: new Date("2020", "11", "15", "10", "0"),
end: new Date("2020", "11", "15", "12", "0"),
title: "Andhra Pradesh",
info: "MVP Colony,Visakapatnam",
type: "Type01",
tentative: false
}
]
},
{
name: "Anil",
appointments: [
{
start: new Date("2020", "11", "1", "18", "00"),
end: new Date("2020", "11", "2", "19", "10"),
title: "Telangana",
info: "Madhapur,Hyderabad",
type: "Type04",
tentative: false
},
{
start: new Date("2020", "11", "5", "18", "00"),
end: new Date("2020", "11", "8", "19", "10"),
title: "Telangana",
info: "Banjara Hills,Hyderabad",
type: "Type04",
tentative: false
},
{
start: new Date("2020", "11", "11", "18", "00"),
end: new Date("2020", "11", "15", "19", "10"),
title: "Andhra Pradesh",
info: "Rushikonda,Visakapatnam",
type: "Type04",
tentative: false
}
]
},
{
name: "Chaithanya",
appointments: [
{
start: new Date("2020", "11", "15", "08", "30"),
end: new Date("2020", "11", "15", "09", "30"),
title: "Telangana",
info: "Jiblee Hills,Hyderabad",
type: "Type02",
tentative: false
},
{
start: new Date("2020", "11", "1", "11", "0"),
end: new Date("2020", "11", "31", "23", "59"),
title: "Telangana",
info: "Mothi Nagar,Hyderabad",
type: "Type10",
tentative: false
}
]
}
]
});
this.getView().setModel(oModel);
}
Step4:
Run the Application. The Output screen would be like below. By default Hours view will be selected.
We can navigate to different Views by selecting options available in the dropdown like below.
We can see 1 month View in Ipad Mode like below:
Step5:
Sometimes in Month view, we can’t able to see the clear information (Location) of the appointment. For that, we are adding a message box to pops up while clicking on the selected appointment.
Add the below function in js file.
handleAppointmentSelect: function (oEvent) {
var oAppointment = oEvent.getParameter("appointment"),
sSelected;
if (oAppointment) {
sSelected = oAppointment.getSelected() ? "selected" : "deselected";
MessageBox.show("'" + oAppointment.getTitle() + "' " + sSelected +"\n"+ oAppointment.getText());
} else {
var aAppointments = oEvent.getParameter("appointments");
var sValue = aAppointments.length + " Appointments selected";
MessageBox.show(sValue);
}
}
Reload the application and click on any of the appointments to show detailed info.
Conclusion: By the following, we have successfully visualized the Agent details clearly in different Views.
I hope it helps.
Thank you.
Hello Sai,
nice example, this was exactly I was looking for.
I'm trying to map fields of type date from ODataSource into the single Instance unified:CalendarAppointment but can't see any appointments in the calendar controll.
My single data item from ODataSource (the root path is here /xFFLExTimCnFSet) has fields StartDate, StartTime, EndDate, EndTime, Description, ...
Is there anything special I have to care about? Maybe the problem ist that the fields "StartDate" and "EndDate" contains only day, month and year values and time value is zero. How would be the best approach to combine those StartDate+StartTime and EndDate+EndTime repectivelly before the data will is given to the Calendar control?
Thanks!
Hi Maciej Kaczmarek,
I have the exact same issue. How did you solve it? The planning calendar expects a Javascript Date Object via new...but how to pass this via SAP CAP CDS OData behind it? I tested both with datatype Date and DateTime.
BR
Rufat
Hello Rufat,
what do you mean with "expects a Javascript Date Object via new..." ?
My current view works now and is like (TimeState is JsonModel bound to this view):
Hi Maciej Kaczmarek,
thank you, I just had issues with the date format. Can you show a snippet of your data model, please? I am using CAP CDS with data type DateTime, didn´t succeed yet. Otherwise, I got the mentioned errors.
BR
Rufat
Hello,
If i want to pass date from Odata, in which format it should be?
Regards,
Manoj
Thank you Sai Sreelekha Suraparaju,
that's good blog and helpful. But i want to ask how u set your OData Structure? And how we can do entity under entity without association.
For example we have firma information like :
{Company Name:
Company Adress:
Company Budget:
Company Products :{
Product name:
Product size:
Product price: }
}
I want to ask exactly how can we set up OData Structure with only one Entity set for planning calendar.
Hi Firat,
In OData Using one Entity we can achieve this, in UI by filtering the whole response Data from OData Service with Unique Key i.e.., either Person Id or Person Name push into one Array named Appointments or any respective Array Name.
By this after filtering the Data you will get the Data similar to this like below:
Response Data from OData Call
2. After filtering the whole OData Response with unique record then got 12 records.
Filtered Data
3. Now in this Filtered Array each record has Appointments Array as shown below:
With Appointments inner Array
So by this way you can bind the appointments to calendar. But this causes some performance issue when we have huge number of records say like 10k, so in that case better to create a Deep Entity at backend which has header and Item Entities which is better approach for eradicating the performance issue further.
Regards,
Mamatha M