meteor + react + syncfusion schedule

Hello 


I just wanted to check if there're any samples on how to use meteor + react schedule (Syncfusion). Or any links I can use. 

Thank you in advance for your help. 



19 Replies

VS Velmurugan S Syncfusion Team May 17, 2018 07:05 AM UTC

Hi Mohd,

Thank you for contacting Syncfusion support.

We can add our JS2 Scheduler in Meteor project for which we have prepared the sample that can be downloaded from the following location, 
http://www.syncfusion.com/downloads/support/forum/137540/ze/ScheduleReactInMeteor-1453353298

Refer to the following steps to render the control in Meteor project. 
1.       Kindly follow the instruction from the below link to create simple meteor sample.
https://www.meteor.com/tutorials/blaze/creating-an-app 
2.       Run the following commend to add the Syncfusion packages. 
         meteor npm install --save @syncfusion/ej2-react-schedule  
3.       Create the schedule.js file add the Schedule control rendering code example as mentioned below. 
<Code> 
import React from 'react'; 
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject } from '@syncfusion/ej2-react-schedule'; 
import './main.css'; 
 
var data = [{ 
  Id: 1, 
  Subject: 'Conference', 
  StartTime: new Date(2018, 1, 7, 10, 0), 
  EndTime: new Date(2018, 1, 7, 11, 0), 
  IsAllDay: false 
}, { 
  Id: 2, 
  Subject: 'Meeting - 1', 
  StartTime: new Date(2018, 1, 15, 10, 0), 
  EndTime: new Date(2018, 1, 16, 12, 30), 
  IsAllDay: false 
}, { 
  Id: 3, 
  Subject: 'Paris', 
  StartTime: new Date(2018, 1, 13, 12, 0), 
  EndTime: new Date(2018, 1, 13, 12, 30), 
  IsAllDay: false 
}, { 
  Id: 4, 
  Subject: 'Vacation', 
  StartTime: new Date(2018, 1, 12, 10, 0), 
  EndTime: new Date(2018, 1, 12, 10, 30), 
  IsAllDay: false 
}, { 
  Id: 5, 
  Subject: 'Scrum Meeting', 
  Location: 'Office', 
  StartTime: new Date(2018, 1, 12, 9, 30), 
  EndTime: new Date(2018, 1, 12, 10, 30), 
  RecurrenceRule: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;INTERVAL=1' 
}]; 
 
export default class ScheduleControl extends React.Component 
  render() { 
    return ( 
      <ScheduleComponent height="550px" eventSettings={ { dataSource: data } } selectedDate={new Date(2018, 1, 15)}> 
        <Inject services={[Day, Week, WorkWeek, Month, Agenda]} /> 
      </ScheduleComponent> 
    ); 
  } 
} 
</Code> 
4.     Import and render the Schedule component in main.js file as mentioned below. 
<Code> 
import { Meteor } from 'meteor/meteor'; 
import React from 'react'; 
import { render } from 'react-dom'; 
import ScheduleControl from './schedule.js'; 
Meteor.startup(() => { 
  render(<ScheduleControl />, document.getElementById('Schedule1')); 
}); 
</Code> 
5.       In body section create a Div element and adding the required CSS file reference in the header section as shown below. 
<head> 
<title>sample</title> 
  <!-- Syncfusion Essential JS 2 Styles --> 
   <link rel="stylesheet" rel='nofollow' href="https://cdn.syncfusion.com/ej2/material.css" /> 
</head> 
 
<body> 
<div id="Schedule1"></div> 
</body> 
 
In the above sample we have rendered the default scheduler with appointments. Currently we do not have any documentation related to adding the Scheduler control in Meteor projects. We will consider this requirement and add it to the knowledge base document and publish it soon in our website. 

Regards,
Velmurugan


MO mohd replied to Velmurugan S May 24, 2018 10:36 PM UTC

Hi Mohd,

Thank you for contacting Syncfusion support.

We can add our JS2 Scheduler in Meteor project for which we have prepared the sample that can be downloaded from the following location, 
http://www.syncfusion.com/downloads/support/forum/137540/ze/ScheduleReactInMeteor-1453353298

Refer to the following steps to render the control in Meteor project. 
1.       Kindly follow the instruction from the below link to create simple meteor sample.
https://www.meteor.com/tutorials/blaze/creating-an-app 
2.       Run the following commend to add the Syncfusion packages. 
         meteor npm install --save @syncfusion/ej2-react-schedule  
3.       Create the schedule.js file add the Schedule control rendering code example as mentioned below. 
<Code> 
import React from 'react'; 
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject } from '@syncfusion/ej2-react-schedule'; 
import './main.css'; 
 
var data = [{ 
  Id: 1, 
  Subject: 'Conference', 
  StartTime: new Date(2018, 1, 7, 10, 0), 
  EndTime: new Date(2018, 1, 7, 11, 0), 
  IsAllDay: false 
}, { 
  Id: 2, 
  Subject: 'Meeting - 1', 
  StartTime: new Date(2018, 1, 15, 10, 0), 
  EndTime: new Date(2018, 1, 16, 12, 30), 
  IsAllDay: false 
}, { 
  Id: 3, 
  Subject: 'Paris', 
  StartTime: new Date(2018, 1, 13, 12, 0), 
  EndTime: new Date(2018, 1, 13, 12, 30), 
  IsAllDay: false 
}, { 
  Id: 4, 
  Subject: 'Vacation', 
  StartTime: new Date(2018, 1, 12, 10, 0), 
  EndTime: new Date(2018, 1, 12, 10, 30), 
  IsAllDay: false 
}, { 
  Id: 5, 
  Subject: 'Scrum Meeting', 
  Location: 'Office', 
  StartTime: new Date(2018, 1, 12, 9, 30), 
  EndTime: new Date(2018, 1, 12, 10, 30), 
  RecurrenceRule: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;INTERVAL=1' 
}]; 
 
export default class ScheduleControl extends React.Component 
  render() { 
    return ( 
      <ScheduleComponent height="550px" eventSettings={ { dataSource: data } } selectedDate={new Date(2018, 1, 15)}> 
        <Inject services={[Day, Week, WorkWeek, Month, Agenda]} /> 
      </ScheduleComponent> 
    ); 
  } 
} 
</Code> 
4.     Import and render the Schedule component in main.js file as mentioned below. 
<Code> 
import { Meteor } from 'meteor/meteor'; 
import React from 'react'; 
import { render } from 'react-dom'; 
import ScheduleControl from './schedule.js'; 
Meteor.startup(() => { 
  render(<ScheduleControl />, document.getElementById('Schedule1')); 
}); 
</Code> 
5.       In body section create a Div element and adding the required CSS file reference in the header section as shown below. 
<head> 
<title>sample</title> 
  <!-- Syncfusion Essential JS 2 Styles --> 
   <link rel="stylesheet" rel='nofollow' href="https://cdn.syncfusion.com/ej2/material.css" /> 
</head> 
 
<body> 
<div id="Schedule1"></div> 
</body> 
 
In the above sample we have rendered the default scheduler with appointments. Currently we do not have any documentation related to adding the Scheduler control in Meteor projects. We will consider this requirement and add it to the knowledge base document and publish it soon in our website. 

Regards,
Velmurugan

outstanding work ... thank you a million :) 


VS Velmurugan S Syncfusion Team May 25, 2018 05:28 AM UTC

Hi Mohd 
Most welcome.   
We are glad that our given solution helped you to meet your expectation. Please let us know if you need any further assistance on this.   
Regards,   
Velmurugan   



MO mohd May 26, 2018 12:39 AM UTC

I have the following questions: 

1) are all functionalities available in the react-schedule component? like Categories? Resources? any links on how to use them?

2) How to override the edit/add a new form to custom-made form? I want to make sure more details for my business scenario are supplied before adding an appointment, also I want to post-approve appointment after adding them. 

3)can I  change themes to my own?

thank you for your support. 


VS Velmurugan S Syncfusion Team May 28, 2018 03:54 PM UTC

Hi Mohd,  
Please find the following response for your queries:  
Query #1: Are all functionalities available in the react-schedule component? like Categories? Resources? any links on how to use them?  
In our Volume – 1, 2018 release – Schedule was released in vertical view modes with all the basic functionalities which can be referred from here (https://ej2.syncfusion.com/16.1.37/react/demos/#/material/schedule/default ) and still, we are implementing all other pending features such as timeline views, drag and drop, resize and others one by one which will be available in our next Volume-3 2018 release. 
Apart from this, Multiple resources and Timescale features will be available in our upcoming Volume-2 2018 main release.  
Also, you can achieve the requirement of applying category colors to the appointments by using the “onEventRendered” event with an additional category field added to an appointment object. Please refer to the following code example to meet this requirement.  
<Code> 
 
import React from 'react'; 
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject } from '@syncfusion/ej2-react-schedule'; 
import './main.css'; 
 
var data = [{ 
  Id: 1, 
  Subject: 'Conference', 
  StartTime: new Date(2018, 1, 7, 10, 0), 
  EndTime: new Date(2018, 1, 7, 11, 0), 
  IsAllDay: false, 
  CategoryColor: '#1aaa55' 
}, { 
  Id: 2, 
  Subject: 'Meeting - 1', 
  StartTime: new Date(2018, 1, 15, 10, 0), 
  EndTime: new Date(2018, 1, 16, 12, 30), 
  IsAllDay: false, 
  CategoryColor: '#f57f17' 
}, { 
  Id: 3, 
  Subject: 'Paris', 
  StartTime: new Date(2018, 1, 13, 12, 0), 
  EndTime: new Date(2018, 1, 13, 12, 30), 
  IsAllDay: false, 
  CategoryColor: '#7fa900' 
}, { 
  Id: 4, 
  Subject: 'Vacation', 
  StartTime: new Date(2018, 1, 12, 11, 0), 
 EndTime: new Date(2018, 1, 12, 11, 30), 
  IsAllDay: false, 
  CategoryColor: '#ea7a57' 
}, { 
  Id: 5, 
  Subject: 'Scrum Meeting', 
  Location: 'Office', 
  StartTime: new Date(2018, 1, 12, 9, 30), 
  EndTime: new Date(2018, 1, 12, 10, 30), 
  RecurrenceRule: 'FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;INTERVAL=1', 
  CategoryColor: '#00bdae' 
}]; 
 
function onEventRendered(args) { 
  let categoryColor = args.data.CategoryColor; 
  if (!args.element || !categoryColor) { 
    return; 
  } 
  if (this.currentView === 'Agenda') { 
    (args.element.firstChild).style.borderLeftColor = categoryColor; 
  } else { 
    args.element.style.backgroundColor = categoryColor; 
  } 
} 
 
export default class ScheduleControl extends React.Component 
  render() { 
    return ( 
      <ScheduleComponent height="550px" eventSettings={ { dataSource: data } } selectedDate={new Date(2018, 1, 15)} eventRendered={onEventRendered}> 
        <Inject services={[Day, Week, WorkWeek, Month, Agenda]} /> 
      </ScheduleComponent> 
    ); 
  } 
} 
 
</Code>  
Query #2: How to override the edit/add a new form to custom-made form? I want to make sure more details for my business scenario are supplied before adding an appointment, also I want to post-approve appointment after adding them.   
You can make a custom-form using the JS2 “Additional Fields” or “Editor Template” support. If you wish to use some additional fields with the default fields go with the “Additional Fields” support. Otherwise if you are using the fully customized window, we suggest you to use the “Editor Template” support. Please refer to the following sample link to know about the Additional Fields and EditorTemplate support.  
Kindly share the details about your requirement on this “post-approve appointment after adding them” like whether you are expecting to add/prevent the appointment creation based on the condition. For example, if the appointment owner is admin, allowing him to create the appointment or else preventing it. The information provided will be more helpful for us to analyze your requirement and provide you the prompt solution.  
Query #3: Can I  change themes to my own?  
Our Syncfusion JS2 controls supports the following themes now. 
Available Themes:   
Material, Fabric, Bootstrap, High Contrast   
Please look into our below UG link to change the theme in your react application.  
Also, we have implemented the theme studio support in our JS2 platform which will be available in our upcoming main release Volume 2, 2018.  
Regards, 
Velmurugan


MO mohd June 7, 2018 12:19 AM UTC

Thank you guys for your help. 

Ok, so when does Volume 2 is expected to be released? 

Because Resources, Cells Styles, Colum header styles, Row header styles are mandatory to my project, I need to take a decision whether to use synfusion on this project or not. 


VS Velmurugan S Syncfusion Team June 7, 2018 03:53 PM UTC

Hi Mohd, 
  
You are most welcome. Our Volume 2, 2018 beta release will be available in this week. 
  
Also, we would like to inform you that the cell, header styles can be changed by using our template support and all the below customization is applicable for the resource feature too. Please refer to the following sample links to know about the Schedule customization using templates. 
Note - Currently, timeline view is not available in our JS2 Schedule now, which has been planned for Volume-3 2018 as stated earlier. 
  
Kindly check with the above sample links and let us know if you need any further assistance on this. 
Regards, 
Velmurugan 



MO mohd June 8, 2018 12:57 AM UTC

Thank you for your support. 

I've visited these samples before, but I had a problem with typescript and how to move it to JS ES5/6 to seamlessly work with my meteor/react project. 


VS Velmurugan S Syncfusion Team June 10, 2018 03:42 PM UTC

Hi Mohd, 
You are most welcome. 
We have modified the previously shared meteor sample with the above mentioned customization, which can be downloaded from the following location. 
In the above sample, we have added the required code changes in the “schedule.js, main.css” files. Also, added one more folder is called “public” to store the required images. Please refer to the following images of the customization done in the above sample. 
 
 
Kindly try with the above sample and let us know if you need any further assistance on this. 
Regards, 
Velmurugan


MO mohd replied to Velmurugan S June 11, 2018 08:43 AM UTC

Hi Mohd, 
You are most welcome. 
We have modified the previously shared meteor sample with the above mentioned customization, which can be downloaded from the following location. 
In the above sample, we have added the required code changes in the “schedule.js, main.css” files. Also, added one more folder is called “public” to store the required images. Please refer to the following images of the customization done in the above sample. 
 
 
Kindly try with the above sample and let us know if you need any further assistance on this. 
Regards, 
Velmurugan

Amazing work... thank you guys. 

Can I ask one more question on this? How to (add new appointments) using (customized form) ?? in this form I should be able to decide the category/color of the appointment and maybe (Icon to represent a service/product) ??


VS Velmurugan S Syncfusion Team June 13, 2018 03:42 AM UTC

Hi Mohd,   
  
Thanks for your appreciation.  
    
We have modified the previously shared meteor sample to meet your requirement by adding new appointments with custom field (ex: category) value, which can be downloaded from the following location. 
 
 
In the above sample, we have added the custom field Category and used the DropDownList control for its values display. Please refer to the following code example changes done in the above sample to meet your requirement.    
   
schedule.js page:   
 
import React from 'react'; 
import { createElement, Internationalization } from '@syncfusion/ej2-base'; 
import { DropDownList } from '@syncfusion/ej2-dropdowns'; 
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject } from '@syncfusion/ej2-react-schedule'; 
import './main.css'; 
 
var data = [ 
  { 
    Id: 1, 
    Subject: 'Environment Day', 
    Tags: 'Eco day, Forest conserving, Earth & its resources', 
    Description: 'A day that creates awareness to promote the healthy planet and reduce the air pollution crisis on nature earth.', 
    StartTime: new Date(2018, 1, 12, 9, 0), 
    EndTime: new Date(2018, 1, 12, 14, 0), 
    ImageName: 'environment-day', 
    PrimaryColor: '#1aaa55', 
    SecondaryColor: '#47bb76', 
    Category: 'maintenance' 
  }, { 
    Id: 2, 
    Subject: 'Health Day', 
    Tags: 'Reduce mental stress, Follow good food habits', 
    Description: 'A day that raises awareness on different health issues. It marks the anniversary of the foundation of WHO.', 
    StartTime: new Date(2018, 1, 13, 9, 0), 
    EndTime: new Date(2018, 1, 13, 14, 0), 
    ImageName: 'health-day', 
    PrimaryColor: '#357cd2', 
    SecondaryColor: '#5d96db', 
    Category: 'public-event' 
  }, { 
    Id: 3, 
    Subject: 'Cancer Day', 
    Tags: 'Life threatening cancer effects, Palliative care', 
    Description: 'A day that raises awareness on cancer and its preventive measures. Early detection saves life.', 
    StartTime: new Date(2018, 1, 14, 9, 0), 
    EndTime: new Date(2018, 1, 14, 14, 0), 
    ImageName: 'cancer-day', 
    PrimaryColor: '#7fa900', 
    SecondaryColor: '#a4c932', 
    Category: 'commercial-event' 
  }, { 
    Id: 4, 
    Subject: 'Happiness Day', 
    Tags: 'Stress-free, Smile, Resolve frustration and bring happiness', 
    Description: 'A general idea is to promote happiness and smile around the world.', 
    StartTime: new Date(2018, 1, 15, 9, 0), 
    EndTime: new Date(2018, 1, 15, 14, 0), 
    ImageName: 'happiness-day', 
    PrimaryColor: '#ea7a57', 
    SecondaryColor: '#ee9478' 
  }, { 
   Id: 5, 
    Subject: 'Tourism Day', 
    Tags: 'Diverse cultural heritage, strengthen peace', 
    Description: 'A day that raises awareness on the role of tourism and its effect on social and economic values.', 
    StartTime: new Date(2018, 1, 16, 9, 0), 
    EndTime: new Date(2018, 1, 16, 14, 0), 
    ImageName: 'tourism-day', 
    PrimaryColor: '#00bdae', 
    SecondaryColor: '#32cabe' 
  }]; 
 
function onPopupOpen(args) { 
  if (args.type === 'Editor') { 
    // Create required custom elements in initial time 
    if (!args.element.querySelector('.custom-field-row')) { 
      let row = createElement('div', { className: 'custom-field-row' }); 
      let formElement = args.element.querySelector('.e-schedule-form'); 
      formElement.firstChild.insertBefore(row, args.element.querySelector('.e-title-location-row')); 
      let container = createElement('div', { className: 'custom-field-container' }); 
      let inputEle = createElement('input', { 
        className: 'e-field', attrs: { name: 'Category' } 
      }); 
      container.appendChild(inputEle); 
      row.appendChild(container); 
      let drowDownList= new DropDownList({ 
        dataSource: [ 
          { text: 'Blue Category', value: 'public-event', color:'blue' }, 
          { text: 'Orange Category', value: 'maintenance', color:'orange' }, 
          { text: 'Yellow Category', value: 'commercial-event', color:'yellow' } 
        ], 
        fields: { text: 'text', value: 'value' }, 
        itemTemplate: itemTemplate, // This is used to display the icon along with the text in the dropdownlist item display in popup 
        valueTemplate: valueTemplate, // This is used to display the icon along with the text in the dropdownlist value display 
        value: 'maintenance', 
        floatLabelType: 'Always', placeholder: 'Category' 
      }); 
      drowDownList.appendTo(inputEle); 
      inputEle.setAttribute('name', 'Category'); // This name attribute value should be same as the Field Name (ex: Category in event collection). 
 
    } 
  } 
} 
 
//set the value to item template 
let itemTemplate = '<div><img class="category-image" style="background-color:${color}" src="/${value}.png" alt="category"/>' + 
'<div class="e-category"> ${text} </div></div>'; 
//set the value to value template 
let valueTemplate = '<div class="category-value-container"><img class="category-value-img" style="background-color:${color}" src="/${value}.png" alt="category"/>' 
+ '<div class="category"> ${text} </div></div>'; 
 
export default class ScheduleControl extends React.Component { 
  render() { 
    return ( 
      <ScheduleComponent height="550px" cellTemplate={cellTemplate} dateHeaderTemplate={dateHeaderTemplate} eventSettings={{ dataSource: data, template: eventTemplate }} selectedDate={new Date(2018, 1, 15)} actionBegin={onActionBegin} eventRendered={onEventRendered} navigating={onNavigating} popupOpen={onPopupOpen}> 
        <Inject services={[Day, Week, WorkWeek, Month, Agenda]} /> 
      </ScheduleComponent> 
    ); 
  } 
} 
 
 
main.css page: 
 
.custom-field-row { 
        margin-bottom: 20px; 
    } 
 
    .category-image { 
        padding: 2px; 
    } 
 
    .category-image, 
    .category-value-img { 
        float: left; 
        height: 28px; 
        width: 28px; 
    } 
 
    .category-value-container { 
        width: 100%; 
        height: 100%; 
        padding: 5px 0px 
    } 
 
    .category { 
        padding: 5px 0px 0px 35px; 
    } 
 
 
Please refer to the following screenshot of the custom field selection while creating the appointment. 
 
 
 
We have used our additional field support in the above sample, since the mentioned requirement is related to adding a single custom field (Category). If you wish to use more custom fields, we suggest you to use our Editor Template support. Please refer to the following sample link to know about the Editor Template and Additional Field support.   
   
   
Also, we used the DropDownList control item template and value template features to display the images along with the category options. Please refer to the following sample and UG link to know about the DropDownList template support.   
   
   
Note: We would like to inform you that we have internally processing the form element controls (ex: Input, DropDownList, CheckBox) values based on its name attribute value. Therefore, while defining the custom field with the form controls, add the name attribute value same as in the appointment collection or database table field (ex: Category in both appointment collection and the name of the DropDownList control in the above sample).   
   
Kindly try with the above sample and let us know if you need any further assistance on this.    
  
Regards,   
Velmurugan


MO mohd replied to Velmurugan S June 28, 2018 10:49 AM UTC

Hi Mohd,   
  
Thanks for your appreciation.  
    
We have modified the previously shared meteor sample to meet your requirement by adding new appointments with custom field (ex: category) value, which can be downloaded from the following location. 
 
 
In the above sample, we have added the custom field Category and used the DropDownList control for its values display. Please refer to the following code example changes done in the above sample to meet your requirement.    
   
schedule.js page:   
 
import React from 'react'; 
import { createElement, Internationalization } from '@syncfusion/ej2-base'; 
import { DropDownList } from '@syncfusion/ej2-dropdowns'; 
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject } from '@syncfusion/ej2-react-schedule'; 
import './main.css'; 
 
var data = [ 
  { 
    Id: 1, 
    Subject: 'Environment Day', 
    Tags: 'Eco day, Forest conserving, Earth & its resources', 
    Description: 'A day that creates awareness to promote the healthy planet and reduce the air pollution crisis on nature earth.', 
    StartTime: new Date(2018, 1, 12, 9, 0), 
    EndTime: new Date(2018, 1, 12, 14, 0), 
    ImageName: 'environment-day', 
    PrimaryColor: '#1aaa55', 
    SecondaryColor: '#47bb76', 
    Category: 'maintenance' 
  }, { 
    Id: 2, 
    Subject: 'Health Day', 
    Tags: 'Reduce mental stress, Follow good food habits', 
    Description: 'A day that raises awareness on different health issues. It marks the anniversary of the foundation of WHO.', 
    StartTime: new Date(2018, 1, 13, 9, 0), 
    EndTime: new Date(2018, 1, 13, 14, 0), 
    ImageName: 'health-day', 
    PrimaryColor: '#357cd2', 
    SecondaryColor: '#5d96db', 
    Category: 'public-event' 
  }, { 
    Id: 3, 
    Subject: 'Cancer Day', 
    Tags: 'Life threatening cancer effects, Palliative care', 
    Description: 'A day that raises awareness on cancer and its preventive measures. Early detection saves life.', 
    StartTime: new Date(2018, 1, 14, 9, 0), 
    EndTime: new Date(2018, 1, 14, 14, 0), 
    ImageName: 'cancer-day', 
    PrimaryColor: '#7fa900', 
    SecondaryColor: '#a4c932', 
    Category: 'commercial-event' 
  }, { 
    Id: 4, 
    Subject: 'Happiness Day', 
    Tags: 'Stress-free, Smile, Resolve frustration and bring happiness', 
    Description: 'A general idea is to promote happiness and smile around the world.', 
    StartTime: new Date(2018, 1, 15, 9, 0), 
    EndTime: new Date(2018, 1, 15, 14, 0), 
    ImageName: 'happiness-day', 
    PrimaryColor: '#ea7a57', 
    SecondaryColor: '#ee9478' 
  }, { 
   Id: 5, 
    Subject: 'Tourism Day', 
    Tags: 'Diverse cultural heritage, strengthen peace', 
    Description: 'A day that raises awareness on the role of tourism and its effect on social and economic values.', 
    StartTime: new Date(2018, 1, 16, 9, 0), 
    EndTime: new Date(2018, 1, 16, 14, 0), 
    ImageName: 'tourism-day', 
    PrimaryColor: '#00bdae', 
    SecondaryColor: '#32cabe' 
  }]; 
 
function onPopupOpen(args) { 
  if (args.type === 'Editor') { 
    // Create required custom elements in initial time 
    if (!args.element.querySelector('.custom-field-row')) { 
      let row = createElement('div', { className: 'custom-field-row' }); 
      let formElement = args.element.querySelector('.e-schedule-form'); 
      formElement.firstChild.insertBefore(row, args.element.querySelector('.e-title-location-row')); 
      let container = createElement('div', { className: 'custom-field-container' }); 
      let inputEle = createElement('input', { 
        className: 'e-field', attrs: { name: 'Category' } 
      }); 
      container.appendChild(inputEle); 
      row.appendChild(container); 
      let drowDownList= new DropDownList({ 
        dataSource: [ 
          { text: 'Blue Category', value: 'public-event', color:'blue' }, 
          { text: 'Orange Category', value: 'maintenance', color:'orange' }, 
          { text: 'Yellow Category', value: 'commercial-event', color:'yellow' } 
        ], 
        fields: { text: 'text', value: 'value' }, 
        itemTemplate: itemTemplate, // This is used to display the icon along with the text in the dropdownlist item display in popup 
        valueTemplate: valueTemplate, // This is used to display the icon along with the text in the dropdownlist value display 
        value: 'maintenance', 
        floatLabelType: 'Always', placeholder: 'Category' 
      }); 
      drowDownList.appendTo(inputEle); 
      inputEle.setAttribute('name', 'Category'); // This name attribute value should be same as the Field Name (ex: Category in event collection). 
 
    } 
  } 
} 
 
//set the value to item template 
let itemTemplate = '<div><img class="category-image" style="background-color:${color}" src="/${value}.png" alt="category"/>' + 
'<div class="e-category"> ${text} </div></div>'; 
//set the value to value template 
let valueTemplate = '<div class="category-value-container"><img class="category-value-img" style="background-color:${color}" src="/${value}.png" alt="category"/>' 
+ '<div class="category"> ${text} </div></div>'; 
 
export default class ScheduleControl extends React.Component { 
  render() { 
    return ( 
      <ScheduleComponent height="550px" cellTemplate={cellTemplate} dateHeaderTemplate={dateHeaderTemplate} eventSettings={{ dataSource: data, template: eventTemplate }} selectedDate={new Date(2018, 1, 15)} actionBegin={onActionBegin} eventRendered={onEventRendered} navigating={onNavigating} popupOpen={onPopupOpen}> 
        <Inject services={[Day, Week, WorkWeek, Month, Agenda]} /> 
      </ScheduleComponent> 
    ); 
  } 
} 
 
 
main.css page: 
 
.custom-field-row { 
        margin-bottom: 20px; 
    } 
 
    .category-image { 
        padding: 2px; 
    } 
 
    .category-image, 
    .category-value-img { 
        float: left; 
        height: 28px; 
        width: 28px; 
    } 
 
    .category-value-container { 
        width: 100%; 
        height: 100%; 
        padding: 5px 0px 
    } 
 
    .category { 
        padding: 5px 0px 0px 35px; 
    } 
 
 
Please refer to the following screenshot of the custom field selection while creating the appointment. 
 
 
 
We have used our additional field support in the above sample, since the mentioned requirement is related to adding a single custom field (Category). If you wish to use more custom fields, we suggest you to use our Editor Template support. Please refer to the following sample link to know about the Editor Template and Additional Field support.   
   
   
Also, we used the DropDownList control item template and value template features to display the images along with the category options. Please refer to the following sample and UG link to know about the DropDownList template support.   
   
   
Note: We would like to inform you that we have internally processing the form element controls (ex: Input, DropDownList, CheckBox) values based on its name attribute value. Therefore, while defining the custom field with the form controls, add the name attribute value same as in the appointment collection or database table field (ex: Category in both appointment collection and the name of the DropDownList control in the above sample).   
   
Kindly try with the above sample and let us know if you need any further assistance on this.    
  
Regards,   
Velmurugan

Thank you guys for this amazing work. You rock! It worked like a charm!

To end this: how to add a complete custom form to add new events? with fields like (category), (price as a number), (customerName should be a drop-down list or a search field from another table), (Resources as a drop-down coming from another table). 
I hope this does not look too complicated, but I am sure there's a huge value for such this for many developers using Schedule on their React/Meteor applications. 

Thank you in advance for your support. 


VS Velmurugan S Syncfusion Team June 29, 2018 06:44 PM UTC

Hi Mohd,    
   
You are most welcome and we are glad that our provided solutions helped you to meet your requirements.   
     
We have modified the previously shared meteor sample to meet your requirement complete custom form to add new events by using our EditorTemplate support, which can be downloaded from the following location.  
  
  
In the above sample, we have added the mentioned custom fields Category, Customer Name and Resource Name and used the DropDownList control for its values (used the local data – you can use your table data instead of local data) display and another custom field Price value displayed in the textbox. Please refer to the following code example changes done in the above sample to meet your requirement.     
    
schedule.js page:    
  
import React from 'react'; 
import { Internationalization } from '@syncfusion/ej2-base'; 
import { DropDownList } from '@syncfusion/ej2-dropdowns'; 
import { DateTimePicker } from '@syncfusion/ej2-calendars'; 
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject } from '@syncfusion/ej2-react-schedule'; 
import './main.css'; 
 
var data = [ 
  { 
    Id: 1, 
    Subject: 'Environment Day', 
    Tags: 'Eco day, Forest conserving, Earth & its resources', 
    Description: 'A day that creates awareness to promote the healthy planet and reduce the air pollution crisis on nature earth.', 
    StartTime: new Date(2018, 1, 12, 9, 0), 
    EndTime: new Date(2018, 1, 12, 14, 0), 
    ImageName: 'environment-day', 
    PrimaryColor: '#1aaa55', 
    SecondaryColor: '#47bb76', 
    Category: 'maintenance', 
    ResourceName: 'John', 
    CustomerName: 'James', 
    Price: 100, 
  }, { 
    Id: 2, 
    Subject: 'Health Day', 
    Tags: 'Reduce mental stress, Follow good food habits', 
    Description: 'A day that raises awareness on different health issues. It marks the anniversary of the foundation of WHO.', 
    StartTime: new Date(2018, 1, 13, 9, 0), 
    EndTime: new Date(2018, 1, 13, 14, 0), 
    ImageName: 'health-day', 
    PrimaryColor: '#357cd2', 
    SecondaryColor: '#5d96db', 
    Category: 'public-event', 
    ResourceName: 'Jim', 
    CustomerName: 'Adams', 
    Price: 100, 
  }, { 
    Id: 3, 
    Subject: 'Cancer Day', 
    Tags: 'Life threatening cancer effects, Palliative care', 
    Description: 'A day that raises awareness on cancer and its preventive measures. Early detection saves life.', 
    StartTime: new Date(2018, 1, 14, 9, 0), 
    EndTime: new Date(2018, 1, 14, 14, 0), 
    ImageName: 'cancer-day', 
    PrimaryColor: '#7fa900', 
    SecondaryColor: '#a4c932', 
    Category: 'commercial-event', 
    ResourceName: 'John', 
    CustomerName: 'James', 
    Price: 300, 
  }, { 
    Id: 4, 
    Subject: 'Happiness Day', 
    Tags: 'Stress-free, Smile, Resolve frustration and bring happiness', 
    Description: 'A general idea is to promote happiness and smile around the world.', 
    StartTime: new Date(2018, 1, 15, 9, 0), 
    EndTime: new Date(2018, 1, 15, 14, 0), 
    ImageName: 'happiness-day', 
    PrimaryColor: '#ea7a57', 
    SecondaryColor: '#ee9478', 
    Category: 'public-event', 
    ResourceName: 'Mohd', 
    CustomerName: 'Mathews', 
    Price: 100, 
  }, { 
    Id: 5, 
    Subject: 'Tourism Day', 
    Tags: 'Diverse cultural heritage, strengthen peace', 
    Description: 'A day that raises awareness on the role of tourism and its effect on social and economic values.', 
    StartTime: new Date(2018, 1, 16, 9, 0), 
    EndTime: new Date(2018, 1, 16, 14, 0), 
    ImageName: 'tourism-day', 
    PrimaryColor: '#00bdae', 
    SecondaryColor: '#32cabe', 
    Category: 'public-event', 
    ResourceName: 'Jim', 
    CustomerName: 'Adams', 
    Price: 200, 
  }]; 
 
----------------------- 
----------------------- 
----------------------- 
----------------------- 
 
function onPopupOpen(args) { 
  if (args.type === 'Editor') { // Here checking the detail window type and proceed to render the controls for custom fields 
    var categoryElement = args.element.querySelector('#Category'); 
    if (!categoryElement.classList.contains('e-dropdownlist')) { 
      let categoryDrowDownList= new DropDownList({  
        dataSource: [  
          { text: 'Blue Category', value: 'public-event', color:'blue' },  
          { text: 'Orange Category', value: 'maintenance', color:'orange' },  
          { text: 'Yellow Category', value: 'commercial-event', color:'yellow'}  
        ],  
        fields: { text: 'text', value: 'value' },  
        itemTemplate: itemTemplate, // This is used to display the icon along with the text in the dropdownlist item display in popup  
        valueTemplate: valueTemplate, // This is used to display the icon along with the text in the dropdownlist value display  
        value: 'maintenance',  
        floatLabelType: 'Always', placeholder: 'Category'  
      }); 
      categoryDrowDownList.appendTo(categoryElement); 
      categoryElement.setAttribute('name', 'CustomerName'); 
    } 
    var customerNameElement = args.element.querySelector('#CustomerName'); 
    if (!customerNameElement.classList.contains('e-dropdownlist')) { 
      var customerNameDownListObject = new DropDownList({ 
        placeholder: 'Choose Customer Name', value: customerNameElement.value, 
        dataSource: ['James', 'Adams', 'Mathews'] 
      }); 
      customerNameDownListObject.appendTo(customerNameElement); 
      customerNameElement.setAttribute('name', 'CustomerName'); 
    } 
    var resourceNameElement = args.element.querySelector('#ResourceName'); 
    if (!resourceNameElement.classList.contains('e-dropdownlist')) { 
      var dropDownListObject = new DropDownList({ 
        placeholder: 'Choose Resource Name', value: resourceNameElement.value, 
        dataSource: ['John', 'Jim', 'Mohd'] 
      }); 
      dropDownListObject.appendTo(resourceNameElement); 
      resourceNameElement.setAttribute('name', 'ResourceName'); 
    } 
    var startElement = args.element.querySelector('#StartTime'); 
    if (!startElement.classList.contains('e-datetimepicker')) { 
      new DateTimePicker({ value: new Date(startElement.value) || new Date() }, startElement); 
    } 
    var endElement = args.element.querySelector('#EndTime'); 
    if (!endElement.classList.contains('e-datetimepicker')) { 
      new DateTimePicker({ value: new Date(endElement.value) || new Date() }, endElement); 
    } 
  } 
} 
--------------------------- 
--------------------------- 
--------------------------- 
 
let editorTemplate = '<table class="custom-event-editor" width="100%" cellpadding="5"><tbody>' 
  + '<tr><td class="e-textlabel">Summary</td><td colspan="4"><input id="Subject" class="e-field e-input" type="text" value="" name="Subject" style="width: 100%" /></td></tr>' 
  + '<tr><td class="e-textlabel">Category</td><td colspan="4"><input type="text" id="Category" name="Category" class="e-field" style="width: 100%" /></td></tr>' 
  + '<tr><td class="e-textlabel">Price</td><td colspan="4"><input id="Price" class="e-field e-input" type="text" value="" name="Price" style="width: 100%" /></td></tr>' 
  + '<tr><td class="e-textlabel">Customer Name</td><td colspan="4"><input type="text" id="CustomerName" name="CustomerName" class="e-field" style="width: 100%" /></td></tr>' 
  + '<tr><td class="e-textlabel">Resource Name</td><td colspan="4"><input type="text" id="ResourceName" name="ResourceName" class="e-field" style="width: 100%" /></td></tr>' 
  + '<tr><td class="e-textlabel">From</td><td colspan="4"><input id="StartTime" class="e-field" type="text" name="StartTime" /></td></tr>' 
  + '<tr><td class="e-textlabel">To</td><td colspan="4"><input id="EndTime" class="e-field" type="text" name="EndTime" /></td></tr>' 
  + '<tr><td class="e-textlabel">Reason</td><td colspan="4"><textarea id="Description" class="e-field e-input" name="Description" rows="3" cols="50" style="width: 100%; height: 60px !important; resize: vertical"></textarea></td></tr>' 
  + '</tbody></table>'; 
 
export default class ScheduleControl extends React.Component { 
  render() { 
    return ( 
      <ScheduleComponent height="550px" editorTemplate={editorTemplate} cellTemplate={cellTemplate} dateHeaderTemplate={dateHeaderTemplate} eventSettings={{ dataSource: data, template: eventTemplate }} selectedDate={new Date(2018, 1, 15)} actionBegin={onActionBegin} eventRendered={onEventRendered} navigating={onNavigating} popupOpen={onPopupOpen}> 
        <Inject services={[Day, Week, WorkWeek, Month, Agenda]} /> 
      </ScheduleComponent> 
    ); 
  } 
} 
 
  
main.css page:  
  
    .custom-event-editor .e-textlabel { 
        padding-right: 15px; 
        text-align: right; 
    } 
   
    .custom-event-editor td { 
        padding: 7px; 
        padding-right: 16px; 
    } 
  
  
Please refer to the following screenshot of the custom form with the mentioned fields.  
 
While Saving Appointment: 
 
 
 
While Editing Appointment: 
 
 
 
Kindly try with the above sample and let us know if you need any further assistance on this.     
 
Note: We would like to inform you that we have internally processing the form element controls (ex: Input, DropDownList, CheckBox) values based on its name attribute value. Therefore, while defining the custom field with the form controls, add the name attribute value same as in the appointment collection or database table field (ex: ResourceName in both appointment collection and the name of the DropDownList control in the above sample). 
 
Regards,    
Velmurugan



MO mohd July 12, 2018 10:36 AM UTC

Hello 

Thank you guys for this amazing work. Let's add one more request: 

1) How to show (month) view with each cell (day) have a different background color + a different picture based on (date value). 

Thank you


VS Velmurugan S Syncfusion Team July 13, 2018 05:54 PM UTC

Hi Mohd,    
   
You are most welcome   
     
We have modified the previously shared meteor sample to meet your requirement applying different background color and different picture based on the date value by using our cellTemplate feature and renderCell event, which can be downloaded from the following location.  
  
  
schedule.js page:    
  
import React from 'react'; 
import { Internationalization } from '@syncfusion/ej2-base'; 
import { DropDownList } from '@syncfusion/ej2-dropdowns'; 
import { DateTimePicker } from '@syncfusion/ej2-calendars'; 
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject } from '@syncfusion/ej2-react-schedule'; 
import './main.css'; 
 
---------------------------- 
---------------------------- 
---------------------------- 
 
function onRenderCell(args) { 
  if (args.elementType == "monthCells") { // Here checking the monthcells type and applying the color 
    let colors = ["brown", "blue", "blueviolet", "burlywood", "yellow", 
      "olive", "orangered", "orchid", "gray", "green", 
      "greenyellow", "gold", "goldenrod", "aqua", "chartreuse", 
      "chocolate", "coral", "cadetblue", "cornflowerblue", "crimson", 
      "lime", "darkblue", "darkgreen", "darkkhaki", "darkmagenta", 
      "darkolivegreen", "darkred", "firebrick", "greenyellow", 
      "grey", "salmon"]; 
    args.element.style.backgroundColor = colors[args.date.getDate() - 1]; // Here applying the color to the month cell element 
 
  } 
} 
 
--------------------------------- 
--------------------------------- 
--------------------------------- 
 
/** 
 * Schedule cell template – Applying different picture based on the month and date value 
 */ 
 
window.getCellContent = function (date) { 
  if (date.getMonth() === 1 && date.getDate() === 23) { 
    return '<img height="40px" src="/thanksgiving-day.svg" /><div class="caption">Thanksgiving day</div>'; 
  } else if (date.getMonth() === 1 && date.getDate() === 2) { 
    return '<img height="40px" src="/newyear.svg" /><div class="caption">Party time</div>'; 
  } else if (date.getMonth() === 1 && date.getDate() === 3) { 
    return '<img height="40px" src="/get-together.svg" /><div class="caption">Party time</div>'; 
  } else if (date.getMonth() === 1 && date.getDate() === 4) { 
    return '<img height="40px" src="/birthday.svg" /><div class="caption">Happy birthday</div>'; 
  } else if (date.getMonth() === 1 && date.getDate() === 5) { 
    return '<img height="40px" src="/christmas-eve.svg" /><div class="caption">Christmas Eve</div>'; 
  } else if (date.getMonth() === 1 && date.getDate() === 6) { 
    return '<img height="40px" src="/christmas.svg" /><div class="caption">Christmas Day</div>'; 
  } else if (date.getMonth() === 0 && date.getDate() === 1) { 
    return '<img height="40px" src="/newyear.svg" /><div class="caption">New Year\'s Day</div>'; 
  } else if (date.getMonth() === 0 && date.getDate() === 14) { 
    return '<img height="40px" src="/get-together.svg" /><div class="caption">Get together</div>'; 
  } 
  return ''; 
}; 
-------------------------------- 
-------------------------------- 
-------------------------------- 
 
window.getTimeString = function (value) { 
  return instance.formatDate(value, { skeleton: 'hm' }); 
}; 
 
let cellTemplate = '${if(type === "monthCells")}<div class="templatewrap">${getCellContent(data.date)}</div>${/if}'; 
-------------------------------- 
-------------------------------- 
-------------------------------- 
 
export default class ScheduleControl extends React.Component { 
  render() { 
    return ( 
      <ScheduleComponent height="550px" editorTemplate={editorTemplate} cellTemplate={cellTemplate} dateHeaderTemplate={dateHeaderTemplate} eventSettings={{ dataSource: data, template: eventTemplate }} selectedDate={new Date(2018, 1, 15)} actionBegin={onActionBegin} eventRendered={onEventRendered} navigating={onNavigating} popupOpen={onPopupOpen} renderCell={onRenderCell}> 
        <Inject services={[Day, Week, WorkWeek, Month, Agenda]} /> 
      </ScheduleComponent> 
    ); 
  } 
} 
  
   
Please refer to the following UG and sample link to know about the CellTemplate and RenderCell event.    
    
    
Kindly try with the above sample and let us know if you need any further assistance on this.     
   
Regards,    
Velmurugan 



MO mohd August 15, 2018 12:22 PM UTC

Hello again

can we update this sample with the new (schedule) component and show how to do (resources) example? with the previous additions: like pictures on appointments, resource name foto, resource name on Event Editor??

Thank you guys for your continuous support. 


AA Arulraj A Syncfusion Team August 17, 2018 12:45 PM UTC

Hi Mohd,     
    
Thanks for the update. 
      
We have prepared the new schedule meteor sample to meet your requirement adding resources and resource name in the event editor with previously provided customization solutions, which can be downloaded from the following location.   
   
In the above sample, we have used the MultiSelect control instead of DropDownList for displaying the “Resource Names” as shown below and by using this control you can select multiple resource at a time and create the new appointment for all the selected resources at a time. 
 
 
 
Please refer to the following code example changes used in the above sample to include the resources. 
 
schedule.js page:     
   
import React from 'react'; 
import { Internationalization, isNullOrUndefined } from '@syncfusion/ej2-base'; 
import { DropDownList, MultiSelect } from '@syncfusion/ej2-dropdowns'; 
import { DateTimePicker } from '@syncfusion/ej2-calendars'; 
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject, ResourcesDirective, ResourcesModelDirective } from '@syncfusion/ej2-react-schedule'; 
import './main.css'; 
 
var data = [ 
    { 
        Id: 1, 
        Subject: 'Environment Day', 
        Tags: 'Eco day, Forest conserving, Earth & its resources', 
        Description: 'A day that creates awareness to promote the healthy planet and reduce the air pollution crisis on nature earth.', 
        StartTime: new Date(2018, 1, 12, 9, 0), 
        EndTime: new Date(2018, 1, 12, 14, 0), 
        ImageName: 'environment-day', 
        PrimaryColor: '#1aaa55', 
        SecondaryColor: '#47bb76', 
        Category: 'maintenance', 
        CustomerName: 'James', 
        Price: 100, 
        ResourceId: 2, 
    }, { 
        Id: 2, 
        Subject: 'Health Day', 
        Tags: 'Reduce mental stress, Follow good food habits', 
        Description: 'A day that raises awareness on different health issues. It marks the anniversary of the foundation of WHO.', 
        StartTime: new Date(2018, 1, 13, 9, 0), 
        EndTime: new Date(2018, 1, 13, 14, 0), 
        ImageName: 'health-day', 
        PrimaryColor: '#357cd2', 
        SecondaryColor: '#5d96db', 
        Category: 'public-event', 
        CustomerName: 'Adams', 
        Price: 100, 
        ResourceId: 1, 
    }, { 
        Id: 3, 
        Subject: 'Cancer Day', 
        Tags: 'Life threatening cancer effects, Palliative care', 
        Description: 'A day that raises awareness on cancer and its preventive measures. Early detection saves life.', 
        StartTime: new Date(2018, 1, 14, 9, 0), 
        EndTime: new Date(2018, 1, 14, 14, 0), 
        ImageName: 'cancer-day', 
        PrimaryColor: '#7fa900', 
        SecondaryColor: '#a4c932', 
        Category: 'commercial-event', 
        CustomerName: 'James', 
        Price: 300, 
        ResourceId: 3, 
    }, { 
        Id: 4, 
        Subject: 'Happiness Day', 
        Tags: 'Stress-free, Smile, Resolve frustration and bring happiness', 
        Description: 'A general idea is to promote happiness and smile around the world.', 
        StartTime: new Date(2018, 1, 15, 9, 0), 
        EndTime: new Date(2018, 1, 15, 14, 0), 
        ImageName: 'happiness-day', 
        PrimaryColor: '#ea7a57', 
        SecondaryColor: '#ee9478', 
        Category: 'public-event', 
        CustomerName: 'Mathews', 
        Price: 100, 
        ResourceId: 2, 
    }, { 
        Id: 5, 
        Subject: 'Tourism Day', 
        Tags: 'Diverse cultural heritage, strengthen peace', 
        Description: 'A day that raises awareness on the role of tourism and its effect on social and economic values.', 
        StartTime: new Date(2018, 1, 16, 9, 0), 
        EndTime: new Date(2018, 1, 16, 14, 0), 
        ImageName: 'tourism-day', 
        PrimaryColor: '#00bdae', 
        SecondaryColor: '#32cabe', 
        Category: 'public-event', 
        CustomerName: 'Adams', 
        Price: 200, 
       ResourceId: 1, 
    }]; 
 
var resourceData = [ 
    { ResourceName: 'Jim', ResourceId: 1, ResourceColor: '#EA7A57' }, 
    { ResourceName: 'John', ResourceId: 2, ResourceColor: '#357cd2' }, 
    { ResourceName: 'Mohd', ResourceId: 3, ResourceColor: '#7fa900' } 
]; 
 
------------------- 
------------------- 
------------------- 
 
function onPopupOpen(args) { 
    if (args.type === 'Editor') { // Here checking the detail window type and proceed to render the controls for custom fields 
        -------------------------- 
        -------------------------- 
        -------------------------- 
        var resourceNameElement = args.element.querySelector('#ResourceName'); 
        var resourceValue = args.target.classList.contains("e-work-cells") ? args.data.ResourceId : [args.data.ResourceId]; 
        if (!resourceNameElement.classList.contains('e-multiselect')) { 
            var multiSelectObject = new MultiSelect({ 
                placeholder: 'Choose Resource Name', value: resourceValue, 
                dataSource: resourceData, 
                fields: { text: 'ResourceName', value: 'ResourceId' } 
            }); 
            multiSelectObject.appendTo(resourceNameElement); 
            resourceNameElement.setAttribute('name', 'ResourceId'); 
        } 
        var startElement = args.element.querySelector('#StartTime'); 
        if (!startElement.classList.contains('e-datetimepicker')) { 
            new DateTimePicker({ value: new Date(startElement.value) || new Date() }, startElement); 
        } 
        var endElement = args.element.querySelector('#EndTime'); 
        if (!endElement.classList.contains('e-datetimepicker')) { 
            new DateTimePicker({ value: new Date(endElement.value) || new Date() }, endElement); 
        } 
    } 
} 
 
----------------------- 
----------------------- 
----------------------- 
 
/** 
* Schedule resource header template 
*/ 
window.getResourceImage = function (value) { 
    var resourceNamewindow.getResourceName(value); 
    return resourceName.replace(' ', '-').toLowerCase(); 
}; 
 
window.getResourceName = function (value) { 
    return (value.resourceData) ? value.resourceData[value.resource.textField] : value.resourceName; 
}; 
 
------------------------- 
------------------------- 
------------------------- 
 
// resource templete to show the resources header with resource name and image 
let resourceTemplate = '<div class="template-wrap"><div class="resource-image ${getResourceImage(data)}"></div><div class="resource-details"><div class="resource-name">${getResourceName(data)}</div></div></div>'; 
 
export default class ScheduleControl extends React.Component { 
    render() { 
        return ( 
            <ScheduleComponent height="550px" editorTemplate={editorTemplate} cellTemplate={cellTemplate} dateHeaderTemplate={dateHeaderTemplate} eventSettings={{ dataSource: data, template: eventTemplate }} selectedDate={new Date(2018, 1, 15)} actionBegin={onActionBegin} eventRendered={onEventRendered} navigating={onNavigating} popupOpen={onPopupOpen} renderCell={onRenderCell} group={{ resources: ['Resources'] }} resourceHeaderTemplate={resourceTemplate}> 
                <ResourcesDirective> 
                    <ResourcesModelDirective field='ResourceId' title='Resource Name' name='Resources' allowMultiple={true} 
                        dataSource={resourceData} textField='ResourceName' idField='ResourceId' colorField='ResourceColor'> 
                    </ResourcesModelDirective> 
                </ResourcesDirective> 
                <Inject services={[Day, Week, WorkWeek, Month, Agenda]} /> 
            </ScheduleComponent> 
        ); 
    } 
} 
   
 
main.css page: 
 
.e-schedule .template-wrap .resource-image { 
        height: 45px; 
        background-size: 45px; 
        background-repeat: no-repeat; 
        width: 20%; 
    } 
 
    .e-schedule .template-wrap .resource-image.jim { 
        background-image: url('/jim.png'); 
    } 
 
    .e-schedule .template-wrap .resource-image.john { 
        background-image: url('/john.png'); 
    } 
 
    .e-schedule .template-wrap .resource-image.mohd { 
        background-image: url('/mohd.png'); 
    } 
 
    .e-schedule .e-resource-cells .template-wrap { 
        display: flex; 
    } 
 
    .e-schedule .e-resource-cells .template-wrap .resource-name { 
        padding: 15px; 
    } 
 
 
 
Please refer to the following UG and sample link to know about the Resources.     
     
     
Kindly try with the above sample and let us know if you need any further assistance on this.      
 
Arulraj A 



MO mohd August 28, 2018 06:31 AM UTC

Hello 

I was wondering why the sample does not persist the newly created events automatically? or how to do it? 


AA Arulraj A Syncfusion Team August 29, 2018 03:44 AM UTC

Hi Mohd, 

You need to save the newly created appointment in database to persist that appointment in the Schedule control after refresh. To achieve this requirement refer to the following steps. 

  1. Create the database table with mandatory fields along with required custom fields. Please refer to the following table structure that we have created with all the JS2 Schedule control default fields along with the custom fields (used previously in local data).
 
CREATE TABLE [dbo].[ScheduleEventData] ( 
    [Id]                  INT            NOT NULL, 
    [Subject]             NVARCHAR (MAX) NULL, 
    [StartTime]           DATETIME       NULL, 
    [EndTime]             DATETIME       NULL, 
    [StartTimezone]       NVARCHAR (MAX) NULL, 
    [EndTimezone]         NVARCHAR (MAX) NULL, 
    [IsAllDay]            BIT            NULL, 
    [RecurrenceRule]      NVARCHAR (MAX) NULL, 
    [RecurrenceID]        NVARCHAR (50)  NULL, 
    [RecurrenceException] NVARCHAR (MAX) NULL, 
    [Location]            NVARCHAR (MAX) NULL, 
    [Description]         NVARCHAR (MAX) NULL, 
    [Tags]                NVARCHAR (MAX) NULL, 
    [ImageName]           NVARCHAR (MAX) NULL, 
    [PrimaryColor]        NVARCHAR (MAX) NULL, 
    [SecondaryColor]      NVARCHAR (MAX) NULL, 
    [Category]            NVARCHAR (MAX) NULL, 
    [CustomerName]        NVARCHAR (MAX) NULL, 
    [Price]               INT            NULL, 
    [ResourceId]          INT            NULL, 
    PRIMARY KEY CLUSTERED ([Id] ASC) 
); 
 
  1. Define the LoadData and UpdateData method to read the data from the database table and insert the newly created or updated appointment details into that table. Please refer to the following code example for the LoadData and UpdateData method.
 
        public JsonResult LoadData(Params param)  // Here we get the Start and End Date and based on that can filter the data and return to Scheduler 
        { 
            var data = db.ScheduleEventDatas.Where(app => (app.StartTime >= param.StartDate && app.StartTime <= param.EndDate) || (app.RecurrenceRule != null && app.RecurrenceRule != "")).ToList();  // Here filtering the events based on the start and end date value. 
            return Json(data, JsonRequestBehavior.AllowGet); 
        } 
 
        public class Params 
        { 
            public DateTime StartDate { get; set; } 
            public DateTime EndDate { get; set; } 
        } 
 
        [HttpPost] 
        public JsonResult UpdateData(EditParams param) 
        { 
            if (param.action == "insert" || (param.action == "batch" && param.added != null)) // this block of code will execute while inserting the appointments 
            { 
                var value = (param.action == "insert") ? param.value : param.added[0]; 
                int intMax = db.ScheduleEventDatas.ToList().Count > 0 ? db.ScheduleEventDatas.ToList().Max(p => p.Id) : 1; 
                DateTime startTime = Convert.ToDateTime(value.StartTime); 
                DateTime endTime = Convert.ToDateTime(value.EndTime); 
                ScheduleEventData appointment = new ScheduleEventData() 
                { 
                    Id = intMax + 1, 
                    StartTime = startTime, 
                    EndTime = endTime, 
                    Subject = value.Subject, 
                    Location = value.Location, 
                    Description = value.Description, 
                    IsAllDay = value.IsAllDay, 
                    StartTimezone = value.StartTimezone, 
                    EndTimezone = value.EndTimezone, 
                    RecurrenceRule = value.RecurrenceRule, 
                    RecurrenceID = value.RecurrenceID, 
                    RecurrenceException = value.RecurrenceException, 
                    Tags = value.Tags, 
                    ImageName = value.ImageName, 
                    PrimaryColor = value.PrimaryColor, 
                    SecondaryColor = value.SecondaryColor, 
                    CustomerName = value.CustomerName, 
                    Category = value.Category, 
                    Price = value.Price, 
                    ResourceId = value.ResourceId 
                }; 
                db.ScheduleEventDatas.InsertOnSubmit(appointment); 
                db.SubmitChanges(); 
            } 
            if (param.action == "update" || (param.action == "batch" && param.changed != null)) // this block of code will execute while updating the appointment 
            { 
                var value = (param.action == "update") ? param.value : param.changed[0]; 
                var filterData = db.ScheduleEventDatas.Where(c => c.Id == Convert.ToInt32(value.Id)); 
                if (filterData.Count() > 0) 
                { 
                    DateTime startTime = Convert.ToDateTime(value.StartTime); 
                    DateTime endTime = Convert.ToDateTime(value.EndTime); 
                    ScheduleEventData appointment = db.ScheduleEventDatas.Single(A => A.Id == Convert.ToInt32(value.Id)); 
                    appointment.StartTime = startTime; 
                    appointment.EndTime = endTime; 
                    appointment.StartTimezone = value.StartTimezone; 
                    appointment.EndTimezone = value.EndTimezone; 
                    appointment.Subject = value.Subject; 
                    appointment.Location = value.Location; 
                    appointment.Description = value.Description; 
                    appointment.IsAllDay = value.IsAllDay; 
                    appointment.RecurrenceRule = value.RecurrenceRule; 
                    appointment.RecurrenceID = value.RecurrenceID; 
                    appointment.RecurrenceException = value.RecurrenceException; 
                    appointment.Tags = value.Tags; 
                    appointment.ImageName = value.ImageName; 
                    appointment.PrimaryColor = value.PrimaryColor; 
                    appointment.SecondaryColor = value.SecondaryColor; 
                    appointment.CustomerName = value.CustomerName; 
                    appointment.Category = value.Category; 
                    appointment.Price = value.Price; 
                    appointment.ResourceId = value.ResourceId; 
                } 
                db.SubmitChanges(); 
            } 
            if (param.action == "remove" || (param.action == "batch" && param.deleted != null)) // this block of code will execute while removing the appointment 
            { 
                if (param.action == "remove") 
                { 
                    int key = Convert.ToInt32(param.key); 
                    ScheduleEventData appointment = db.ScheduleEventDatas.Where(c => c.Id == key).FirstOrDefault(); 
                    if (appointment != null) db.ScheduleEventDatas.DeleteOnSubmit(appointment); 
                } 
                else 
                { 
                    foreach (var apps in param.deleted) 
                    { 
                        ScheduleEventData appointment = db.ScheduleEventDatas.Where(c => c.Id == apps.Id).FirstOrDefault(); 
                        if (apps != null) db.ScheduleEventDatas.DeleteOnSubmit(appointment); 
                    } 
                } 
                db.SubmitChanges(); 
            } 
            var data = db.ScheduleEventDatas.ToList(); 
            return Json(data, JsonRequestBehavior.AllowGet); 
        } 
 
        public class EditParams 
        { 
            public string key { get; set; } 
            public string action { get; set; } 
            public List<ScheduleEventData> added { get; set; } 
            public List<ScheduleEventData> changed { get; set; } 
            public List<ScheduleEventData> deleted { get; set; } 
            public ScheduleEventData value { get; set; } 
        } 
 
  1. Use the DataManager to map the Url and CrudUrl. Please refer to the following code example for map Url and CrudUrl.
 
schedule.js page: 
 
var dataManger = new DataManager({ 
    url: 'http://localhost:54738/Home/LoadData', // 'controller/actions' 
    crudUrl: 'http://localhost:54738/Home/UpdateData', 
    adaptor: new UrlAdaptor 
}); 
--------------------------------- 
--------------------------------- 
--------------------------------- 
export default class ScheduleControl extends React.Component { 
   render() { 
        return ( 
            <ScheduleComponent height="550px" editorTemplate={editorTemplate} cellTemplate={cellTemplate} dateHeaderTemplate={dateHeaderTemplate} eventSettings={{ dataSource: dataManger, template: eventTemplate }} selectedDate={new Date(2018, 0, 15)} actionBegin={onActionBegin} eventRendered={onEventRendered} navigating={onNavigating} popupOpen={onPopupOpen} renderCell={onRenderCell} group={{ resources: ['Resources'] }} resourceHeaderTemplate={resourceTemplate}> 
                <ResourcesDirective> 
                    <ResourcesModelDirective field='ResourceId' title='Resource Name' name='Resources' allowMultiple={true} 
                        dataSource={resourceData} textField='ResourceName' idField='ResourceId' colorField='ResourceColor'> 
                    </ResourcesModelDirective> 
                </ResourcesDirective> 
                <Inject services={[Day, Week, WorkWeek, Month, Agenda]} /> 
            </ScheduleComponent> 
        ); 
    } 
} 
 
 
  1. Now, you can perform the CRUD operation and able to persist the data properly.
 
We have modified the previously shared sample with the above changes, which can be downloaded from the following location. 
 
 
Also, we request you to refer to the following UG links to know more about the Schedule data binding and performing CRUD operations. 

 
Note: Run the Service project (i.e. Back End) project before running the Schedule sample (i.e. Front End) sample to load the data properly in Schedule control. 
 
Try with the above sample and let us know if you need any further assistance on this. 
 
Regards,   
Arulraj A   


Loader.
Up arrow icon