Holiday and Resources time shift

Greeting,

I wonder if you can direct me how to accomplish the following things.

1. I have defined non-working days in database (as a list of dates)
  - I would like to retrieve non-working days and mark them on the calendar for the same View and Period ( eg. give me all non- working days for week 7 in 2020, or for February 24 )

2. Also, I plan to add configuration per employee for working hours in the same way (eg Monday, February 24, 7-13; Tuesday, February 25, 15-20)
- with the retrieval of event data from back-end, it should trigger fetching hours of work time for an individual employee (resource) and mark it on the calendar - aka shift

EDIT:

is there any way to have 2 different event editor templates based on context menu items ( eg. regular customized event template and block template)

Thanks in advance!

KR,
Ivan

17 Replies

BS Balasubramanian Sattanathan Syncfusion Team February 21, 2020 11:36 AM UTC

Hi Ivan, 

Greetings from Syncfusion Support. 

Q1, Q2 : 
We can set the different working days/hours for the resources by making use of workDays, starthour and endHour properties of Scheduler like below code snippet. Kindly refer the below UG links for more details. 
dataSource: [ 
  { text: 'Will Smith', id: 1, color: '#ea7a57', workDays: [1, 2, 4, 5], startHour: '08:00', endHour: '15:00' }, 
  { text: 'Alice', id: 2, color: 'rgb(53, 124, 210)', workDays: [1, 3, 5], startHour: '08:00', endHour: '17:00' }, 
  { text: 'Robson', id: 3, color: '#7fa900', startHour: '08:00', endHour: '16:00' } 
], 


Q3 : is there any way to have 2 different event editor templates based on context menu items ( eg. regular customized event template and block template) 

We suspect that your requirement is need to use two editor template in Schedule. According to the current architecture, we can’t use two different editor windows. We can differentiate the editor window using editorTemplate property. For your reference, we prepared samples for context menu and editorTemplate. 

 

Kindly try the above links and let us know if you have concerns 

Regards, 
Balasubramanian S 



IV Ivan February 21, 2020 12:00 PM UTC

Hello, 

Thanks for the answers.

Q1 & Q2 update:

     - what if some resource has working time at Monday in morning and on Tuesday afternoon eg. 7-15 and 15-20. Or, for example, if it is shift work, one week in the                   morning and another in the afternoon
       This is clear if selected view is day, but how to configure this for week
   
     - resources data need to be fetched based on scheduler period. eg. if is selected week 8 of 2020. dates are - 17.02.- 23.02 and non-working hours need to be from this               period. 


As I change period on Schedule, only data request is triggered, not resources.

Q3:
     Yes, I would like to have event-template-appointment and event-template-block. So in appointment selectable customer, multiple services, resource, time... and in block only resource and time. I can manage that with example of recurring and normal event template with context menu. 






BS Balasubramanian Sattanathan Syncfusion Team February 24, 2020 09:20 AM UTC

Hi Ivan, 
 
Thanks for the update. 
 
Q1, Q2 : 
We have analyzed your reported scenario and prepared a sample based on your requirements. Please refer the below sample. 
 
 
Q3 : 
We can customize the normal and block events using eventTemplate property like below code snippets. 
<e-view option="Week"> 
  <ng-template #eventTemplate let-data> 
    <div class='template-wrap' [style.background]="data.SecondaryColor"> 
      <div class="subject" [style.background]="data.PrimaryColor">{{data.Subject}}</div> 
      <div class="time" [style.background]="data.PrimaryColor">Time: {{getTimeString(data.StartTime)}} 
        - {{getTimeString(data.EndTime)}}</div> 
      <div class="description">{{data.Description}}</div> 
      <div class="footer" [style.background]="data.PrimaryColor"></div> 
    </div> 
  </ng-template> 
</e-view> 
<e-view option="TimelineWeek"> 
  <ng-template #eventTemplate let-data> 
    <div class='template-wrap' [style.background]="data.PrimaryColor"> 
      <div class="subject" [style.background]="data.SecondaryColor" 
        [style.border-color]="data.PrimaryColor">{{data.Subject}}</div> 
    </div> 
  </ng-template> 
</e-view> 
 
 
Kindly try the above sample and let us know if you have any concerns. 
 
Regards, 
Balasubramanian S


IV Ivan February 24, 2020 09:35 PM UTC

wow,

the answers to q1 and q2 are now crystal clear! I need to apply the above to pure JS but that won't be a problem.


EDIT:
Is there any way to modify cells on DataBind?
I have returned from server with data request, list of non working days. but render cells triggers before databind.

renderCell: function (args) {
if (_renderCells) {
let _element = args.element;

if (_element.classList.contains('e-work-hours') || _element.classList.contains('e-work-cells')) {
let dateText = moment(args.date).format('YYYY-MM-DD');
if (_nonWorkingDays.includes(dateText)) {
_element.classList.add('non-working-cell');
}
}

_renderCells = false;
}
}
dataBinding: function (e) {
_nonWorkingDays = e.actual.nonWorkingDays; // ["2020-02-21"]
_renderCells = true; // or modify all day cells
}
EDIT2 ( additional ): 

I have some problem with selected code on mobile version of schedule:
_scheduler.setWorkHours([currentViewDates[i]], calendarSettings.startTime, calendarSettings.endTime, index);
only if I send index 0 is working, 



for q3 some more explanation.

I would like to be able to have two different forms for creating a event on the context menu.

one is for a normal event with all data, the other is for block time where employees are not available to perform the service. It is clear to me about event templates, and I am already using this in a way that I present different events differently. What is important to me is the create form, not preview side.

KR,
Ivan






BS Balasubramanian Sattanathan Syncfusion Team February 25, 2020 02:12 PM UTC

Hi Ivan, 
 
Thanks for the update. 
 
Q1 : 
EDIT: 
Is there any way to modify cells on DataBind?
I have returned from server with data request, list of non working days. but render cells triggers before databind.
 
 
We have validated your reported scenario at our end. We can achieve this scenario using dataBound event of the Scheduler like below code snippet. 
dataBound: function () { 
  var currentViewDates = document.querySelector('.e-schedule .e-date-header-container .e-header-row').children; 
  for (var i = 0; i < currentViewDates.length; i++) { 
    var day = new Date(parseInt(currentViewDates[i].getAttribute('data-date'))).getDay(); 
    if (day == 0 || day == 6) { 
      currentViewDates[i].classList.add('non-working-cell') 
    } 
  } 
} 
 
 
Q2 : 
EDIT2 ( additional ):  
I have some problem with selected code on mobile version of schedule: 
 
We have analyzed your reported problem. Since, the index parameter is an optional one, which is used for specifying the groupIndex of the resources. We suggest you to refer the below UG link to know more details about setWorkHours public method. 
 
 
Q3: 
I would like to be able to have two different forms for creating a event on the context menu. 
one is for a normal event with all data, the other is for block time where employees are not available to perform the service. It is clear to me about event templates, and I am already using this in a way that I present different events differently. What is important to me is the create form, not preview side. 
 
 
We have validated your requirements. We regret to let you know that there is no possibility to achieve more number of editor window using Scheduler code. So we can’t able to achieve a separate event window for normal and block events. Since the block events don’t support mouse actions by default. If you want to add your custom window for block event, kindly add within the highlighted code like below. 
eventRendered: function (args) { 
  var obj = args.data instanceof Array ? args.data[0] : args.data; 
  if (obj.IsBlock) { 
    args.element.addEventListener("click", clickBlock); 
  } 
} 
 
function clickBlock() { 
  // You can provide custom editor window 
  alert("Block event is clicked"); 
} 
 
 
Kindly try the above sample and let us know if you have any concerns. 
 
Regards, 
Balasubramanian S 



IV Ivan February 25, 2020 05:28 PM UTC

Hello, 

thanks for the answer. 

Q1 and Q3 are ok to me. I have some solution for block editor. 

EDIT2 ( additional ):  
I have some problem with selected code on mobile version of schedule: 

I don't see a problem, This configuration with resources works fine on "desktop" version of Schedule. 

Eg. I have 3 employees, so resources indexes are 0,1 and 2. If I run above snippet with indexes 0,1, and 2, working hours are correctly set. But if I run this snippet on device, I have an error. If I remove groupIndex, workingHours are only set on first selected resources. 

I see now, that, setting workhours for mobile version, works without groupIndex, and sets workhours for selected employee ( resource ), how can I set for all available resources?


It seems like a bug with mobile version of schedule. 

Tnx in advance!

KR,
Ivan


BS Balasubramanian Sattanathan Syncfusion Team February 26, 2020 08:37 AM UTC

Hi Ivan, 
 
Thanks for the update. 
 
We have validated your reported scenario with our end. We could reproduce the reported issue in the mobile mode. So we suggest you to use enableCompactView property to overcome the problem. We modified the sample with below code snippet. Please refer the below UG and API for more details about enableCompactView 
 
public group: GroupModel = { 
  resources: ['Doctors'], enableCompactView: false 
}; 
 
 
Kindly try the above links and let us know if you have any concerns. 
 
Regards, 
Balasubramanian S


IV Ivan February 26, 2020 10:29 AM UTC

Hello, 

thanks for awesome support!

Now I don't have that problem with setting workHours. This is not what I was looking for, but at this stage it solves my problem. 

But with this a new problem has arisen - when swipe actions are used to navigate the peroid, the shift to the past works ok, but the shift to the future does not work and does not mark well the period - video in attachment.

KR,
Ivan



Attachment: swipeactions_c3353a12.zip


BS Balasubramanian Sattanathan Syncfusion Team February 27, 2020 01:44 PM UTC

Hi Ivan, 

Thanks for the update. 

We have checked your reported problem. We could able to reproduce at our end. So we logged the below bug report. The fix for this bug will be provided in our weekly release on March 10, 2020. We would appreciate your valuable patience until then. 


Regards, 
Balasubramanian S


IV Ivan March 13, 2020 10:07 AM UTC

Hello, 

one more question about setWorkHours

My configuration for timescale is:
timeScale: {
enable: true,
interval:
30
slotCount: 2
},
if workhours % 30 != 0, presentation on view is wrong - screenshot in atachment!

eg: 8:25, 8:20

KR,
Ivan






Attachment: workHours_b0f2254b.zip


BS Balasubramanian Sattanathan Syncfusion Team March 16, 2020 10:41 AM UTC

Hi Ivan, 
 
Thanks for the update. 
 
We have validated your reported scenario at our end and let you know that, you are setting timescale slot count as 2 and interval as 30. So all the cells would display 30 minutes interval only. So If we set the workhour start at 8:25 AM, it won’t change. In this case, we need to change the timescale like the below code. 
 
public timeScale: TimeScaleModel = { enable: true, interval: 30, slotCount: 6 }; 
   
 
Regards, 
Balasubramanian S 



IV Ivan March 16, 2020 10:51 AM UTC

Hello,

I'm aware of that option, but in this case, calendar becomes unusable - it shows only 1.5h of day. If employees shift is 8 hour long, he has to scroll every little to see own schedule for selected day.

I currently have several timescale templates predefined. 1h - 1 slot, 30min - 1 slot, 30min - 2 slots.

6 slots are not an option to set

KR,
Ivan


VM Vengatesh Maniraj Syncfusion Team March 17, 2020 06:34 AM UTC

Hi Ivan, 

Thanks for the update. 

We have tried to understand your requirement but we couldn’t get your exact scenario. So could you please share us more details to serve you better? 

Regards, 
Vengatesh 



IV Ivan March 17, 2020 08:23 AM UTC

Greeting,

Nevermind. Ignore the question, I'll get to it by putting a slider above the component that will have the zoom function.

Where it will be possible to change timescale based on zoom and then the user can change between 5, 10, 15, 30 and 60 min intervals.

how can I add this slider to toolbar items ( with only above values )?


KR,
Ivan


VM Vengatesh Maniraj Syncfusion Team March 18, 2020 12:13 PM UTC

Hi Ivan, 
 
Thanks for the update. 
 
We could able to change the timescale based on the Slider change by making use of Slider’s change event.  
 var slider = new ej.inputs.Slider({ 
        //custom ticks 
        customValues: [5, 10, 15, 30, 60], 
        //default selection 
        value: 0, 
        //display ticks 
        ticks: { placement: "Before", largeStep: 10, showSmallTicks: true }, 
        attrs: { name: "Slider" }, 
        tooltip: { 
          placement: "Before", 
          isVisible: true, 
          cssClass: "e-tooltip-cutomization" 
        }, 
        //Change event to change the Schedule's timescale property 
        change: function(args) { 
          var schObj = document.querySelector(".e-schedule").ej2_instances[0]; 
          if (args.value === 0) { 
            schObj.setProperties({ timeScale: { slotCount: 12 } }); 
          } else if (args.value === 1) { 
            schObj.setProperties({ timeScale: { slotCount: 6 } }); 
          } else if (args.value === 2) { 
            schObj.setProperties({ timeScale: { slotCount: 4 } }); 
          } else if (args.value === 3) { 
            schObj.setProperties({ timeScale: { slotCount: 2 } }); 
          } else if (args.value === 4) { 
            schObj.setProperties({ timeScale: { slotCount: 1 } }); 
          } 
        } 
      }); 
 
 
how can I add this slider to toolbar items ( with only above values )? 
 
We could render the slider control in the Scheduler toolbar by making use of actionBegin and actionComplete events. In the actionBegin event, add the HTML element to the toolbar to render the slider control and in the actionComplete event, append the slider control to that element which is rendered in the actionBegin event. For more reference please refer the below code snippet. 
 
actionBegin event: 
actionBegin: function(args) { 
    if (args.requestType === "toolbarItemRendering") { 
      var exportItem = { 
        align: "Center", 
        showTextOn: "Both", 
        prefixIcon: "e-icon-schedule-excel-export", 
        text: "Excel Export", 
        cssClass: "e-excel-export", 
        template: '<div id="Slider"></div>' 
      }; 
      args.items.push(exportItem); 
    } 
  }, 
 
actionComplete event: 
actionComplete: function(args) { 
    if (args.requestType === "toolBarItemRendered") { 
      var sliderDiv = ej.base.createElement("div", { id: "Slider" }); 
      var slider = new ej.inputs.Slider({ 
        //custom ticks 
        customValues: [5, 10, 15, 30, 60], 
        //default selection 
        value: 0, 
        //display ticks 
        ticks: { placement: "Before", largeStep: 10, showSmallTicks: true }, 
        attrs: { name: "Slider" }, 
        tooltip: { 
          placement: "Before", 
          isVisible: true, 
          cssClass: "e-tooltip-cutomization" 
        }, 
        //Change event to change the Schedule's timescale property 
        change: function(args) { 
          var schObj = document.querySelector(".e-schedule").ej2_instances[0]; 
          if (args.value === 0) { 
            schObj.setProperties({ timeScale: { slotCount: 12 } }); 
          } else if (args.value === 1) { 
            schObj.setProperties({ timeScale: { slotCount: 6 } }); 
          } else if (args.value === 2) { 
            schObj.setProperties({ timeScale: { slotCount: 4 } }); 
          } else if (args.value === 3) { 
            schObj.setProperties({ timeScale: { slotCount: 2 } }); 
          } else if (args.value === 4) { 
            schObj.setProperties({ timeScale: { slotCount: 1 } }); 
          } 
        } 
      }); 
      slider.appendTo("#Slider"); 
    } 
  } 
 
For the sample, we have prepared the sample which is available in below link, 
 

Kindly check the above sample and get back to us if you would require any further assistance. 
 
Regards, 
Vengatesh.  



IV Ivan March 18, 2020 03:37 PM UTC

Hi, 


that works! 

do i need to include something special if i want to use slider on mobile view?

KR,
Ivan


VM Vengatesh Maniraj Syncfusion Team March 19, 2020 09:48 AM UTC

Hi Ivan, 

Thanks for the update. 

We have modified our previously shared sample which is applicable for both desktop and mobile mode. Accordingly, we have removed the actionBegin event and use the actionComplete event to render the Slider control inside the toolbar like below code 

app.component.ts 
actionComplete: function(args) { 
    if (args.requestType === "toolBarItemRendered") { 
      //Create the element to render the Slider 
      var sliderDiv = ej.base.createElement("div", { id: "Slider" }); 
      //Get the target element from Toolbar 
      var toolbar = document.querySelector(".e-toolbar-center"); 
      //Append the sleder element into toolbar target 
      toolbar.appendChild(sliderDiv); 
      //Create the Slider control 
      var slider = new ej.inputs.Slider({ 
        //custom ticks 
        customValues: [5, 10, 15, 30, 60], 
        //default selection 
        value: 0, 
        //display ticks 
        ticks: { placement: "Before", largeStep: 10, showSmallTicks: true }, 
        attrs: { name: "Slider" }, 
        tooltip: { 
          placement: "Before", 
          isVisible: true, 
          cssClass: "e-tooltip-cutomization" 
        }, 
        //Change event to change the Schedule's timescale property 
        change: function(args) { 
          var schObj = document.querySelector(".e-schedule").ej2_instances[0]; 
          if (args.value === 0) { 
            schObj.setProperties({ timeScale: { slotCount: 12 } }); 
          } else if (args.value === 1) { 
            schObj.setProperties({ timeScale: { slotCount: 6 } }); 
          } else if (args.value === 2) { 
            schObj.setProperties({ timeScale: { slotCount: 4 } }); 
          } else if (args.value === 3) { 
            schObj.setProperties({ timeScale: { slotCount: 2 } }); 
          } else if (args.value === 4) { 
            schObj.setProperties({ timeScale: { slotCount: 1 } }); 
          } 
        } 
      }); 
      //Append slider control into slider div element. 
      slider.appendTo("#Slider"); 
    } 
  } 
 
CSS Changes 
<style> 
    body { 
      touch-action: none; 
    } 
 
    .e-slider-container { 
      top: 10px; 
      width: 100px !important; 
      hieght: 30px !important; 
    } 
 
    .e-toolbar .e-toolbar-items .e-toolbar-item:not(.e-separator{ 
      min-width: 0px; 
      padding: 0px; 
    } 
 
    .e-device .e-slider-container { 
      left: 0px; 
      width: 69px !important; 
    } 
 
    .e-device .e-control-wrapper.e-slider-container .e-scale.e-h-scale .e-tick .e-tick-value.e-tick-before { 
      top: -5px; 
    } 
  </style> 
 

Kindly try the above sample and get back to us if you would require any other assistance.  

Regards, 
Vengatesh 


Loader.
Up arrow icon