Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member670464
Participant
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:


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.
8 Comments
maciola
Explorer
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.
<SinglePlanningCalendar
class="sapUiSmallMarginTop"
viewChange="handleViewChange"
headerDateSelect="handleHeaderDateSelect"
moreLinkPress="handleMoreLinkPress"
startDate="{path: 'ConfState>/date'}"
enableAppointmentsDragAndDrop="false"
enableAppointmentsResize="false"
enableAppointmentsCreate="false"
appointments="{path: '/xFFLExTimCnFSet'}">
<views>
<SinglePlanningCalendarDayView key="DayView" title="{i18n>filter.time.day}"/>
<SinglePlanningCalendarWeekView key="WeekView" title="{i18n>filter.time.week}"/>
<SinglePlanningCalendarMonthView key="MonthView" title="{i18n>filter.time.month}"/>
</views>
<appointments>
<unified:CalendarAppointment
title="{Description}"
text="{Description}"
type="{TimSta}"
icon="{icon}"
startDate="{StartDate}"
endDate="{EndDate}">
</unified:CalendarAppointment>
</appointments>
</SinglePlanningCalendar>

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!
ManojYadav
Explorer
Hello,

If i want to pass date from Odata, in which format it should be?

Regards,

Manoj
FiratAsan
Active Participant
0 Kudos
Thank you saisreelekhasuraparaju48

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.

 

 

poornamamatha
Participant
0 Kudos
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:

  1. OData Response Data which has 79 Records initially.



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
rgadirov
Participant
0 Kudos
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
maciola
Explorer
0 Kudos

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):

<SinglePlanningCalendar
id="confCalendar"
headerDateSelect="onCalDateHeaderChange"
viewChange="onCalViewChange"
startDateChange="onCalDateChange"
moreLinkPress="onCalMoreLinkPress"
startDate="{path: 'TimeState>/date'}"
enableAppointmentsDragAndDrop="false"
enableAppointmentsResize="false"
enableAppointmentsCreate="false"
appointments="{path: 'time>/xFFLExTimCnFSet', templateShareable: false, parameters: {operationMode: 'Client'}}"
appointmentSelect="onSelectConf"
stickyMode="All">
<views>
<SinglePlanningCalendarDayView key="DayView" title="{i18n>times.filter.time.day}"/>
<SinglePlanningCalendarWeekView key="WeekView" title="{i18n>times.filter.time.week}"/>
<SinglePlanningCalendarMonthView key="MonthView" title="{i18n>times.filter.time.month}"/>
</views>
<actions>
<Button
icon="sap-icon://travel-itinerary"
press=".onCreateConf($event, 'T')"
text="{parts: [{path: 'deviceModel>/isNoPhone'}, {path: 'i18n>times.travel.title'}], formatter: '.timeState.formateButtonTextCalendar'}"
visible="{TimeState>/VISIBLE/CREATE_TRAVEL_CONF_BUTTON}"
/>
<Button text="{parts: [{path: 'deviceModel>/isNoPhone'}, {path: 'i18n>times.work.title'}], formatter: '.timeState.formateButtonTextCalendar'}"
icon="sap-icon://timesheet" press=".onCreateConf($event, 'W')"/>
</actions>
<appointments>
<unified:CalendarAppointment
title="{time>AccDesc}"
text="{=${time>Description}!=='' ? ${time>Description}.slice(0,50) : ${time>Description}.length > 50 ? '...': ''}"
type="{parts: [{path: 'time>TimCat'}], formatter: '.timeState.formatCalenderType'}"
icon="{parts: [{path: 'time>'}], formatter: '.timeState.getTimeItemIcon'}"
startDate="{parts: [{path: 'time>StartDate'}, {path: 'time>StartTime'}], formatter: '.timeState.formatCalenderDate'}"
endDate="{parts: [{path: 'time>EndDate'}, {path: 'time>EndTime'}], formatter: '.timeState.formatCalenderDate'}">
</unified:CalendarAppointment>
</appointments>
</SinglePlanningCalendar>
rgadirov
Participant
0 Kudos
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
rgadirov
Participant
0 Kudos

Hi together,

as it seems, it was a UI5 version issue that is fixed now by SAP.

BR
Rufat

Labels in this area