The date picker on date field in Web UI is made using javascript on client side. Follow the following steps for factory/holiday calendar :
1. Make a custom handler class and implement IF_CRM_WEB_CALLBACK interface.
2. IF_CRM_WEB_CALLBACK interface has only one method named HANDLE_REQUEST. This method is used to handle callback requests. For e.g. ajax requests.
Write the below code in HANDLE_REQUEST method.
DATA: ls_holidays
TYPE iscal_day
,
lt_holidays
TYPE TABLE OF iscal_day
,
lv_date_from
TYPE sy
-datum
,
lv_date_to
TYPE sy
-datum
,
lv_days
TYPE t009b
-butag
,
lv_holidays_str
TYPE string
.
lv_date_from
= ir_server
->request
->get_form_field
( 'date_from' ).
lv_date_to
= ir_server
->request
->get_form_field
( 'date_to' ).
CALL FUNCTION '/SDF/RBE_GET_DAYS_PER_MONTH'
EXPORTING
par_month
= lv_date_to+4
(2)
par_year
= lv_date_to
(4)
IMPORTING
par_days
= lv_days
.
CONCATENATE lv_date_to
(4) lv_date_to+4
(2) lv_days
INTO lv_date_to
.
CALL FUNCTION 'HOLIDAY_GET'
EXPORTING
holiday_calendar = 'IN' "" write your Holiday calendar ID, See tcode scal for reference
* FACTORY_CALENDAR = ' ' "" write your factory calendar id if you want to reflect factory calendar in Web UI
date_from
= lv_date_from
date_to
= lv_date_to
TABLES
holidays
= lt_holidays
EXCEPTIONS
factory_calendar_not_found
= 1
holiday_calendar_not_found
= 2
date_has_invalid_format
= 3
date_inconsistency
= 4
OTHERS = 5.
IF sy
-subrc
= 0.
LOOP AT lt_holidays
INTO ls_holidays
WHERE holiday
= 'X'.
CONCATENATE lv_holidays_str
',''' ls_holidays
-date '''' INTO lv_holidays_str
.
ENDLOOP.
CONCATENATE '[' lv_holidays_str
']' INTO lv_holidays_str
.
ENDIF.
ir_server
->response
->set_cdata
( lv_holidays_str
).
ir_server
->response
->set_header_field
( name
= 'content-type'
value = 'text/xml' ).
The above code is used to get holidays between a certain period and send response in a string.
3. Write the below code on .htm page of your view or follow step 5.
<script>
function convertDate(lv_yr,lv_month,lv_day)
{
var lv_date =
""+lv_day;
if(lv_date.length == 1)
lv_date =
'0'+lv_date;
var lv_month =
""+lv_month;
if(lv_month.length == 1)
lv_month =
'0'+lv_month;
var con =
""+lv_yr+lv_month+ lv_date;
return con;
}
function getHolidays(pm,py,nm,ny)
{
var lv_date_from = convertDate(py,pm,
'01');
var lv_date_to = convertDate(ny,nm,
'31');
var newSessionURL = new thtmlbCSessionURL();
var sicfPath =
"/webcuif/uif_callback";
var handler = 'ZCL_WEB_REQUEST'; /* write your custom handler class name */
var url = newSessionURL.URL + sicfPath +
"?crm_handler=" + handler +
"&date_from=" + lv_date_from +
"&date_to="
+ lv_date_to + thtmlbBuildRequestTicketQuery();
var form = document.getElementById(
"myFormId");
var str = bindHtmlbEvent(form);
var urlArray = url.split(
'?');
ajaxObj = new AjaxRequest(urlArray[0] , {
method:
'post',
asynchronous: false,
parameters: urlArray[1],
bindingMode:
'xml',
onComplete: deltaRenderingCallback,
submittedFormId: form.id,
});
ajaxObj.executeRequest();
var holiday_list = ajaxObj.request.responseText;
return holiday_list;
}
thtmlbCalendar.makeDatePicker = function(sId,iYear,iMonth,iDay,iFirstDayOfWeek) {
var oInput = thtmlbGetElement(sId);
var arrTmp = thtmlb_txt[thtmlb_language];
var date_content =
'';
var displayedDate = thtmlbGetElement(sId).value;
if (displayedDate) {
displayedDate = this.parseDate(displayedDate);
}
if (typeof(aMonthNames) ==
"undefined"){
var aMonthNames = new Array ( arrTmp[
"THTMLB_JANUARY"],arrTmp[
"THTMLB_FEBRUARY"],arrTmp[
"THTMLB_MARCH"],
arrTmp[
"THTMLB_APRIL"],arrTmp[
"THTMLB_MAY"],arrTmp[
"THTMLB_JUNE"],
arrTmp[
"THTMLB_JULY"],arrTmp[
"THTMLB_AUGUST"],arrTmp[
"THTMLB_SEPTEMBER"],
arrTmp[
"THTMLB_OCTOBER"],arrTmp[
"THTMLB_NOVEMBER"],arrTmp[
"THTMLB_DECEMBER"]
);
}
if (typeof(aDayNameAbbrevs) ==
"undefined"){
var aDayNameAbbrevs = new Array ( arrTmp[
"THTMLB_SUNDAY_ABBREV"],arrTmp[
"THTMLB_MONDAY_ABBREV"],arrTmp[
"THTMLB_TUESDAY_ABBREV"],
arrTmp[
"THTMLB_WEDNESDAY_ABBREV"],arrTmp[
"THTMLB_THURSDAY_ABBREV"],arrTmp[
"THTMLB_FRIDAY_ABBREV"],
arrTmp[
"THTMLB_SATURDAY_ABBREV"]
);
}
if (typeof(aDayCount) ==
"undefined"){
var aDayCount = this.dayCounts; }
if (iYear ==
"" && displayedDate) { iYear = displayedDate.getFullYear(); }
if (Number(iYear) < 1000) { iYear = String(Number(iYear)+2000); }
if (typeof(iFirstDayOfWeek)==
"undefined") { iFirstDayOfWeek = thtmlb_system.firstdayofweek; }
iLastDayOfWeek = iFirstDayOfWeek-1;
if (iLastDayOfWeek==-1){ iLastDayOfWeek=6; }
var iMinimalDaysInFirstWeek=thtmlb_system.minimalDaysInFirstWeek;
if (!iMinimalDaysInFirstWeek) { iMinimalDaysInFirstWeek=4; }
var firstOfMonth = new Date(iYear,iMonth,1);
iYear = firstOfMonth.getFullYear();
iMonth = firstOfMonth.getMonth();
this.updateFebruary(iMonth,iYear);
var sCalHtml =
'<table onclick="thtmlbCalendar.pick(event);" class="th-cal-pic-whl" cellpaddding="0" cellspacing="0" border="0"><tr>';
var o = thtmlbGetElement(sId);
var bRO = o.readOnly;
var pm = iMonth-1; /* Previous Month */
var nm = iMonth+1; /* Next Month */
var dy = iDay;
var py = iYear; /* Year associated to the Previous Month */
var ny = iYear; /* Year associated to the Next Month */
var pyd = 0; /* Year Delta associated to the Previous Month */
var nyd = 0; /* Year Delta associated to the Next Month */
if (pm==-1) {
/* Previous Month (is December) falls in the previous year. */
pm = 11;
py--;
pyd = -1;
}
if (nm==12){
/* Next Month (is January) falls in the next year. */
nm = 0;
ny++;
nyd = 1;
}
if (dy>28){
dy=25;
}
var holidayList = getHolidays((pm+1),py,(nm+1),ny);
sCalHtml +=
"<td class=\"th-cal-arr-prev\
" onclick=\"var cr =
" + py + ";
";
sCalHtml += "thtmlbCalendar.showDataPicker(
'"+sId+"', cr ,
"+pm+",
"+dy+",
"+iFirstDayOfWeek+", false);\
"";
sCalHtml +=
" title=\'" + oInput.getAttribute(
'PrevMonth') +
"\'> </td>";
sCalHtml +=
'<td colspan="6" class="th-cal-hdr" nowrap="nowrap" align="center">'+ aMonthNames[iMonth];
sCalHtml +=
' <input type="text" class="th-if" name="currentDate"';
sCalHtml +=
' id="currentDate" value="' + iYear +
'" size="4" maxlength="4"';
sCalHtml +=
" onkeydown=\"if(event.keyCode==13){blur(this);focus(this);}\
""; /* To evaluate the onchange. */
sCalHtml +=
" onchange=\"thtmlbCalendar.showDataPicker(
'"+sId+"',document.getElementById(
'currentDate').value,
"+iMonth+",
"+iDay+",
"+iFirstDayOfWeek+", false);\
"";
sCalHtml +=
"/></td>";
sCalHtml +=
"<td";
if(iYear<9999){
sCalHtml +=
" class=\"th-cal-arr-next\
" onclick=\"var cr =
" + ny + ";
";
sCalHtml += " thtmlbCalendar.showDataPicker(
'" + sId + "',cr,
" + nm+",
"+dy+",
"+iFirstDayOfWeek+", false);\
"";
sCalHtml +=
" title=\'" + oInput.getAttribute(
'NextMonth') +
"\'>";
} else{
sCalHtml +=
' class="th-cal-arr-next-dsbl">';
}
sCalHtml +=
" ";
sCalHtml +=
"</td>";
sCalHtml +=
"</tr>";
sCalHtml +=
"<tr>";
if (thtmlb_system.direction==
"rtl") {
sCalHtml +=
'<td class="th-cal-name" style="border-left:0px none"> </td>';
} else {
sCalHtml +=
'<td class="th-cal-name" style="border-right:0px none"> </td>';
}
for (var i=iFirstDayOfWeek;i<aDayNameAbbrevs.length;i++) {
if (aDayNameAbbrevs.length>3) {
aDayNameAbbrevs[i]=aDayNameAbbrevs[i].substring(0,3);
}
sCalHtml +=
'<td class="th-cal-name">' + aDayNameAbbrevs[i] +
'</td>';
}
for (var i=0;i<iFirstDayOfWeek;i++) {
if (i==iLastDayOfWeek) {
if (thtmlb_system.direction==
"rtl") {
sCalHtml +=
'<td class="th-cal-name" style="border-left:0px none">' + aDayNameAbbrevs[i] +
'</td>';
} else {
sCalHtml +=
'<td class="th-cal-name" style="border-right:0px none">' + aDayNameAbbrevs[i] +
'</td>';
}
} else {
sCalHtml +=
'<td class="th-cal-name">' + aDayNameAbbrevs[i] +
'</td>';
}
}
var numberOfDaysBeforeFirstOfMonth = firstOfMonth.getDay() - iFirstDayOfWeek;
if (numberOfDaysBeforeFirstOfMonth <= 0) numberOfDaysBeforeFirstOfMonth += 7;
var firstCalendarDay = new Date(firstOfMonth.getTime()-(numberOfDaysBeforeFirstOfMonth*24*60*60*1000));
firstCalendarDay = new Date(firstCalendarDay.getTime()+(1000*60*60*12));
var previousYearData = this.getYearData(iYear-1, iLastDayOfWeek, iMinimalDaysInFirstWeek);
var currentYearData = this.getYearData(iYear, iLastDayOfWeek, iMinimalDaysInFirstWeek);
var weeksInPreviousYear = previousYearData.maxWeekNum;
var weeksInCurrentYear = currentYearData.maxWeekNum;
if (iMonth == 0) {
if (firstCalendarDay.getDate() == currentYearData.firstDayOfFirstWeek.getDate()) {
weekNum = 1;
} else {
weekNum = weeksInPreviousYear;
}
} else {
weekNum = Math.floor(((firstCalendarDay.getTime() - currentYearData.firstDayOfFirstWeek.getTime())
/ (7*24*60*60*1000)) + 1.5);
}
for (var i=0;i<6;i++) {
if (iMonth==0
&& weekNum>weeksInPreviousYear) {
weekNum = 1;
} else if (iMonth==11
&& weekNum>weeksInCurrentYear) {
weekNum = 1;
}
sCalHtml +=
'<tr class="th-cal-row"';
if (!bRO){
sCalHtml +=
' style="cursor:pointer;"';
}
sCalHtml +=
'><th class="th-cal-name" style="border-style:none' + ((i<5)?
" none solid none":
"")+
' !important;">' +
((weekNum>0)?weekNum:
" ")+
'</th>';
/* Looping through the days: */
for (var n=0;n<7;n++) {
var sClass=
"";
sId=firstCalendarDay.getFullYear()+
"-"+(firstCalendarDay.getMonth()+1)+
"-"+firstCalendarDay.getDate();
if (firstCalendarDay.getMonth()!=iMonth) {
sClass=
"th-cal-ina";
} else {
sClass=
"";
}
if (displayedDate.getDate) {
if (( firstCalendarDay.getFullYear() == displayedDate.getFullYear() )
&&
( firstCalendarDay.getMonth() == displayedDate.getMonth() )
&&
( firstCalendarDay.getDate() == displayedDate.getDate() )) {
sClass += (sClass) ?
" th-cal-selected" :
"th-cal-selected";
}
}
sCalHtml+=
"<td";
if (n==0) {
if (thtmlb_system.direction==
"rtl"){
sCalHtml+=
' style="border-right-style:solid"';
} else {
sCalHtml+=
' style="border-left-style:solid"';
}
}
date_content = firstCalendarDay.getDate();
var holidclass =
'';
var con_date = convertDate(firstCalendarDay.getFullYear(),(firstCalendarDay.getMonth()+1),firstCalendarDay.getDate());
if(holidayList.indexOf(con_date)!=-1)
{ holidclass =
"th-cal-holid";}
if (((firstCalendarDay.getYear()==new Date().getYear())
&& (firstCalendarDay.getMonth()==new Date().getMonth())
&& (firstCalendarDay.getDate()==new Date().getDate())) || holidclass !=
'' ){
date_content =
'<div class="th-cal-tod ' + holidclass +
'">' + date_content +
'</div>';
}
if (sClass!=
"") {
sCalHtml+=
' id="' + sId +
'" class="th-cal-row-td ' + sClass +
'">' + date_content +
'</td>';
} else {
sCalHtml+=
' id="' + sId +
'" class="th-cal-row-td">' + date_content +
'</td>';
}
var firstCalendarDayfirstHour = firstCalendarDay;
var firstCalendarDayAtNoon;
if (firstCalendarDayfirstHour.getHours()<=1) {
firstCalendarDayAtNoon = new Date(firstCalendarDayfirstHour.getTime()+(1000*60*60*12));
}
else {
firstCalendarDayAtNoon = firstCalendarDayfirstHour;
}
firstCalendarDay = new Date(firstCalendarDayAtNoon.getTime()+(1000*60*60*24));
}
/* Next week! */
weekNum++;
if ((firstCalendarDay.getDay()==iFirstDayOfWeek)
&&(firstCalendarDay.getMonth()>iMonth)) {}
sCalHtml +=
'</tr>';
}
sCalHtml +=
'</table>';
return sCalHtml;
}
</script>
The above code is used to send an ajax request to the custom handler class to get holiday list and then prepare design for the calendar.
getHolidays() function is used to send an ajax request and get response, thtmlbCalendar.makeDatePicker() function is used for the design of calendar.
Step 4 . Write below style element on htm page for holiday date ui.
<style>
.th-cal-holid
{
background-color: LightSalmon;
}
</style>
Step 5. If you want to avoid writing code of step 3 on .htm page, then
a. create a js file
b. copy step 3 code into that js file
c. upload that file into your component through tcode se80->MIME repository.
In Mime repository follow SAP->BC->BSP->
ZAUTO->Import Mime Objects. (ZAUTO is the component name in which your date field is present)
d. Write the below line on .htm page of your view to include the js file you just uploaded.
<script type=
"text/javascript" src=
"/sap/bc/bsp/sap/zauto/myCalendar.js"></script>
zauto is the component name and myCalendar.js is the js file name.
You just need to change the holiday calendar id in step 2 and custom handler class name in step 3.
Now you will be able to see all holidays marked as red in web ui.
Thanks and Regards,
Ritu