I have a web app in which a RadSchedule is used to organize events for multiple users. A user may create an event for himself (by default) and also include other users for which the event will show up. I have created a custom schedule provider that interfaces appointment and user data from my database services with the radSchedule. To allow multiple users to be selected, a user resource is added which allows multiple values in the provider.
When an appointment is inserted/edited a 'checkable' list of the available users shows up in the advanced edit form. Also, at this point debug shows that a resource has been loaded for the appointment.
However, when the user commits the change, and the provider attempts to persist the changes, the appointment object contains no resources.
Basically I just need a list of selected users (ID or names) from the advanced form to pass on to my service.
The provider:
The ASPX:
The code behind:
When an appointment is inserted/edited a 'checkable' list of the available users shows up in the advanced edit form. Also, at this point debug shows that a resource has been loaded for the appointment.
However, when the user commits the change, and the provider attempts to persist the changes, the appointment object contains no resources.
Basically I just need a list of selected users (ID or names) from the advanced form to pass on to my service.
The provider:
| public class CalendarProvider : SchedulerProviderBase |
| { |
| private const string DateFormatString = "yyyy-MM-ddTHH:mmZ"; |
| private ICalendarService _calendarService; |
| private Guid _clientID; |
| private String _userName; |
| private SecurityToken _securityToken; |
| public CalendarProvider(Page page) |
| { |
| _calendarService = ServiceManager.Locate<ICalendarService>("calendar.service"); |
| _clientID = SecurityHelper.GetClientID(page); |
| _securityToken = SecurityHelper.GetUserToken(page); |
| _userName = SecurityHelper.GetUserName(page); |
| } |
| public override bool SupportsMultipleResourceValues |
| { |
| get |
| { |
| return true; |
| } |
| } |
| public override IEnumerable<Appointment> GetAppointments(RadScheduler owner) |
| { |
| List<Appointment> appointments = new List<Appointment>(); |
| IList<CalendarItem> items = _calendarService.FindCalendarItemsByClient(_clientID, _securityToken); |
| foreach (CalendarItem item in items) |
| { |
| Appointment apt = new Appointment(); |
| apt.Owner = owner; |
| apt.ID = item.CalendarItemID; |
| apt.Subject = item.Subject; |
| apt.Start = DateTime.SpecifyKind(item.StartDate, DateTimeKind.Utc); |
| apt.End = DateTime.SpecifyKind(item.EndDate, DateTimeKind.Utc); |
| apt.RecurrenceRule = item.RecurrenceRule; |
| apt.RecurrenceParentID = item.RecurrenceParentID; |
| if (apt.RecurrenceParentID != null) |
| { |
| apt.RecurrenceState = RecurrenceState.Exception; |
| } |
| else if (apt.RecurrenceRule != string.Empty) |
| { |
| apt.RecurrenceState = RecurrenceState.Master; |
| } |
| LoadUsers(apt); |
| apt.Attributes.Add("Location", item.Location); |
| appointments.Add(apt); |
| } |
| return appointments; |
| } |
| private void LoadUsers(Appointment apt) |
| { |
| IList<User> users = _calendarService.FindUsersByCalendarItem(new Guid(apt.ID.ToString()), _securityToken); |
| foreach (User u in users) |
| { |
| Resource student = apt.Owner.Resources.GetResource("User", u.UserID); |
| apt.Resources.Add(student); |
| } |
| } |
| public override IEnumerable<ResourceType> GetResourceTypes(RadScheduler owner) |
| { |
| ResourceType[] types = new ResourceType[1]; |
| types[0] = new ResourceType("User", true); |
| return types; |
| } |
| public override IEnumerable<Resource> GetResourcesByType(RadScheduler owner, string resourceType) |
| { |
| if (resourceType.Equals("User")) |
| { |
| IList<Resource> resources = new List<Resource>(); |
| IList<User> users = ServiceManager.Locate<IClientService>("client.service").FindUsersByClient(_clientID, null); |
| foreach (User u in users) |
| { |
| Resource res = new Resource("User", u.UserID, u.UserName); |
| resources.Add(res); |
| } |
| return resources; |
| } |
| else |
| { |
| throw new InvalidOperationException("Unknown resource type: " + resourceType); |
| return null; |
| } |
| } |
| public override void Insert(RadScheduler owner, Appointment aptInsert) |
| { |
| Guid? RecurrenceID = null; |
| if (aptInsert.RecurrenceParentID != null) |
| { |
| RecurrenceID = new Guid(aptInsert.RecurrenceParentID.ToString()); |
| } |
| Guid AptID; |
| if (aptInsert.ID != null) |
| { |
| AptID = new Guid(aptInsert.ID.ToString()); |
| } |
| else |
| { |
| AptID = Guid.NewGuid(); |
| } |
| string Recurrence = String.Empty; |
| if (aptInsert.RecurrenceRule != null) |
| { |
| Recurrence = aptInsert.RecurrenceRule; |
| } |
| try |
| { |
| CalendarItem item = new CalendarItem(AptID, RecurrenceID, aptInsert.Start, aptInsert.End, |
| aptInsert.Subject, aptInsert.Attributes["Location"] , Recurrence); |
| //AT THIS POINT EVEN THOUGH USERS HAVE BEEN SELECTED, RESOURCES ARE EMPTY. |
| foreach (Resource res in aptInsert.Resources.GetResourcesByType("User")) |
| { |
| item.Resources.Add(new UserCalendarItem((Guid)res.Key, AptID)); |
| } |
| _calendarService.Create(item, _securityToken); |
| } |
| catch |
| { |
| //Show message: Unable to create Calendar Event. |
| } |
| } |
| public override void Update(RadScheduler owner, Appointment aptUpdate) |
| { |
| Guid? RecurrenceID = null; |
| if (aptUpdate.RecurrenceParentID != null) |
| { |
| RecurrenceID = new Guid(aptUpdate.RecurrenceParentID.ToString()); |
| } |
| Guid AptID; |
| if (aptUpdate.ID != null) |
| { |
| AptID = new Guid(aptUpdate.ID.ToString()); |
| } |
| else |
| { |
| AptID = Guid.NewGuid(); |
| } |
| string Recurrence = String.Empty; |
| if (aptUpdate.RecurrenceRule != null) |
| { |
| Recurrence = aptUpdate.RecurrenceRule; |
| } |
| try |
| { |
| CalendarItem item = new CalendarItem(AptID, RecurrenceID, aptUpdate.Start, aptUpdate.End, |
| aptUpdate.Subject, aptUpdate.Attributes["Location"], Recurrence); |
| //AT THIS POINT EVEN THOUGH USERS HAVE BEEN SELECTED, RESOURCES ARE EMPTY. |
| foreach (Resource res in aptInsert.Resources.GetResourcesByType("User")) |
| { |
| item.Resources.Add(new UserCalendarItem((Guid)res.Key, AptID)); |
| } |
| _calendarService.Update(item, _securityToken); |
| } |
| catch |
| { |
| //Show message: Unable to create Calendar Event. |
| } |
| } |
| public override void Delete(RadScheduler owner, Appointment aptDelete) |
| { |
| _calendarService.Remove(new Guid(aptDelete.ID.ToString()), _securityToken); |
| } |
| } |
The ASPX:
| <rad3:RadScheduler runat="server" ID="RadScheduler1" Width="700px" Height="564px" |
| SelectedView="WeekView" TimeZoneOffset="03:00:00" SelectedDate="2008-02-01" DayStartTime="08:00:00" |
| DayEndTime="18:00:00" ReadOnly="false" RadControlsDir="~/App_Themes/RadControls/" |
| CustomAttributeNames="Location" EnableCustomAttributeEditing="true" StartEditingInAdvancedForm="true" |
| OnAppointmentCreated="RadScheduler_AppointmentCreated" OnAppointmentInsert="RadScheduler_AppointmentInserted" |
| Skin="Office2007" OnClientAppointmentContextMenu="appointmentContextMenu" OnClientTimeSlotContextMenu="timeSlotContextMenu"> |
| <AppointmentTemplate> |
| <asp:Label runat="server" ID="Subject" Font-Bold="true" /> |
| <br /> |
| <asp:Label runat="server" ID="Location" ForeColor="Gray" /> |
| </AppointmentTemplate> |
| <ResourceTypes> |
| <rad3:ResourceType Name="Users" AllowMultipleValues="true" /> |
| </ResourceTypes> |
| </rad3:RadScheduler> |
The code behind:
| protected void Page_Load(object sender, EventArgs e) |
| { |
| //Provide Client ID and user token |
| RadScheduler1.Provider = new CalendarProvider(this); |
| if (!IsPostBack) |
| { |
| RadScheduler1.SelectedView = SchedulerViewType.WeekView; |
| RadScheduler1.StartInFullTime = false; |
| RadScheduler1.TimeZoneOffset = new TimeSpan(3,0,0); |
| RadScheduler1.SelectedDate = System.DateTime.Now.Date; |
| RadCalendar1.SelectedDate = RadScheduler1.SelectedDate; |
| RadCalendar1.FocusedDate = RadScheduler1.SelectedDate; |
| } |
| } |
| protected override void OnPreRender(EventArgs e) |
| { |
| base.OnPreRender(e); |
| RadCalendar1.SelectedDate = RadScheduler1.SelectedDate; |
| } |
| protected void RadCalendar1_SelectionChanged(object sender, SelectedDatesEventArgs e) |
| { |
| if (RadCalendar1.SelectedDates.Count > 0) |
| { |
| RadScheduler1.SelectedDate = RadCalendar1.SelectedDate; |
| } |
| } |
| protected void RadScheduler_AppointmentInserted(object sender, SchedulerCancelEventArgs e) |
| { |
| //AT THIS POINT RESOURCES ARE ALSO EMPTY. |
| } |
| protected void OnCreateEvent(object sender, EventArgs e) |
| { |
| if (RadCalendar1.SelectedDates.Count > 0) |
| { |
| RadScheduler1.ShowAdvancedInsertForm(RadCalendar1.SelectedDates[0].Date); |
| } |
| } |
| protected void RadScheduler_AppointmentCreated(object sender, AppointmentCreatedEventArgs e) |
| { |
| String subject = e.Appointment.Subject; |
| if (subject != null) |
| { |
| Label label = (Label)e.Container.FindControl("Subject"); |
| label.Text = subject; |
| } |
| string location = e.Appointment.Attributes["Location"]; |
| if (location != null && location != string.Empty) |
| { |
| Label label = (Label)e.Container.FindControl("Location"); |
| label.Text = "Location: " + location; |
| } |
| } |