This is a migrated thread and some comments may be shown as answers.

RadScheduler Design Patterns

10 Answers 303 Views
Scheduler
This is a migrated thread and some comments may be shown as answers.
Doug Odegaard
Top achievements
Rank 2
Doug Odegaard asked on 14 Mar 2008, 12:32 PM
I am collecting feedback from other users of RadScheduler to find out how far beyond the examples you take database access to create and edit appointments.  In the telerik demos they are heavily dependent on the Radscheduler control and providers.  Has anyone gone outside of this and done a large amount of schedule and resource manipulation directly with the database tables not using the control but having pages that employ it for GUI purposes?  Has anyone found joy or pitfalls in this approach?  Code examples are still minimal so I'm curious what other users are doing.

I am using MS SQL 2005 and ASP.NET with C#.

Thanks in advance.
Doug

10 Answers, 1 is accepted

Sort by
0
Piyush Bhatt
Top achievements
Rank 2
answered on 14 Mar 2008, 07:25 PM
Doug,

I can't exactly understand what answer you need, but I will explain my scenario - I would like to know how you and others use RadScheduler too.

I am using RadScheduler only for the display purpose. My application has some resources who give appointments to different people. I store the appointments, people and resources in the database independently of what Radscheduler needs.

I created a class called 'ApptSlot' that is used only for the display purpose. I query all the data I need in given date range, resources and then prepare a list of ApptSlot according to how I want to display - with many attributes like Status, Subject, people id, resource id etc, tooltip info etc.

Then I simply bind the List to the Scheduler (currently in PreRender). I used OnAppointmentDoubleClick to display a RadWindow to create appointment instead of AppointmentInsertTemplate. After each operation that may affect the scheduling, I rebind the Scheduler to list of 'ApptSlot'.

I am not sure if this is the best approach according to Telerik guys, but so far it has worked out.

The problem I have/am facing are
- not each Client Event has enough properties
- ResizeStart/End is there but there is no MoveStart/End
- If I want to prompt user before/after Resize/Move, there is no way on client side

-Piyush
0
Peter
Telerik team
answered on 17 Mar 2008, 02:52 PM
Hello Piyush,

RadScheduler now has the OnClientAppointmentMoving event. Using the following methods you can get the start time of the original appointment as well as the start time of the modified appointment:
 function OnClientAppointmentMoving(sender, eventArgs)  
        {  
            eventArgs.get_appointment();  
            eventArgs.get_newStartTime();  
 
        } 

In additon, RadScheduler also exposes OnClientAppointmentResizeStart and OnClientAppointmentResizeEnd.


Peter
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Piyush Bhatt
Top achievements
Rank 2
answered on 17 Mar 2008, 03:21 PM
Peter,

I know what you are saying and I wrote the same thing in my mail - that there is ResizeStart/End, but there is no MoveStart/End. There is only Moving.

And you can't do enough validation with it starttime/newtime - you need old/new resources too. One of my earlier question was answered that such validation can only be handled on the server side - no problem! I did that.

In Moving() - I wanted to prompt some questions to users - but that is not supported - because as soon as Moving() is over - the scheduler either resets the appt or posts back.

-Piyush

0
Doug Odegaard
Top achievements
Rank 2
answered on 17 Mar 2008, 04:13 PM
Thanks Piyush.  I have modeled my scheduler around the provider model given with the demos but am used to having a business and data layer to interact with.  Was just curious of models that people have used outside the demo models.

Thanks.
D
0
Peter
Telerik team
answered on 18 Mar 2008, 11:45 AM
Hello Doug,

If you come upon any interesting scenarios with RadScheduler, we will be glad to learn about them. We might prepare online demos out of them.

Pyush, your point is well taken about the client side API. We will expose the events which you require in the near future.

By the way, the OnClientAppointmentMoving event can be cancelled. Here is an example:

 function OnClientAppointmentMoving(sender, eventArgs)  
        {             
            var answer = confirm ("Are you sure you want to move the appointment?")  
            if (answer)  
            {  
              
            }  
            else 
            {                
                eventArgs.set_cancel(true);  
            }              
        } 



Greetings,
Peter
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Sanjay Kumar
Top achievements
Rank 1
answered on 27 Mar 2008, 04:19 AM
Hi Piyush,

I intend to use scheduler in a very similar manner; for display of appointments and for initiating client actions on appointments.  I am debating between using an ApptSlot list and a datatable.  The advantage with datatable is that I can prepare it with all the attributes in  sproc and have a C# that returns the datatable.  I am using a similar approach for RadGrid and it has worked well.  However, I am not able to get my arms around the rebind behavior for scheduler.    Can one declaratively specify a method that the scheduler can call when the rebind is invoked? 

Also,  when someone creates or updates an appointment, do you let the scheduler check the resource availability or do you do it yourself? 

Your thoughts??

Sanjay
0
Piyush Bhatt
Top achievements
Rank 2
answered on 27 Mar 2008, 12:29 PM
Sanjay,

In my case, I had multiple sources of appointments and some business logic to determine where appointment is possible and where not! Hence, the stored procedure was not sufficient for me. But if its straight forward for your case you can use that.

In my current implementation I bind the scheduler everytime there is some change - so almost on every pre-render. I don't say this is good idea - but until I find alternative way to do it. The way Rebind() works in other controls is it calls NeedDataSource method and that's where you assign the datasource to the scheduler. probably scheduler should have similar thing.

-Piyush
0
Fabio Honigmann
Top achievements
Rank 2
answered on 06 May 2008, 09:45 PM
Doug,

You said:
"
I have modeled my scheduler around the provider model given with the demos but am used to having a business and data layer to interact with."

Just like you, I only allow my business layer to manipulate data, so i have  implemented the DBProvider to use my existing business layer.


A couple highlights of my implementation:
        public override IEnumerable<Appointment> GetAppointments(RadScheduler owner) 
        { 
            List<Appointment> appointments = new List<Appointment>(); 
 
            foreach (Event _event in EventList.GetEventList(1, null)) 
            { 
                Appointment apt = new Appointment(); 
                apt.Owner = owner; 
                apt.ID = _event.Id; 
                apt.Subject = _event.Description; 
                apt.Start = _event.StartDateTime; 
                apt.End = _event.EndDateTime; 
                apt.RecurrenceRule = _event.RecurrenceRule; 
                if(_event.RecurrenceParentId == Guid.Empty) 
                    apt.RecurrenceParentID = null
                else 
                    apt.RecurrenceParentID = _event.RecurrenceParentId; 
                apt.Attributes["Name"] = _event.Name; 
                apt.Attributes["LocationName"] = _event.LocationName; 
                apt.Attributes["Address1"] = _event.Address1; 
                apt.Attributes["Address2"] = _event.Address2; 
                apt.Attributes["City"] = _event.City; 
                apt.Attributes["PostalCode"] = _event.PostalCode; 
                apt.Attributes["Phone1"] = _event.Phone1; 
                apt.Attributes["ContactName"] = _event.ContactName; 
                apt.Attributes["IsActive"] = _event.IsActive.ToString(); 
                 
                if (apt.RecurrenceParentID != null
                { 
                    apt.RecurrenceState = RecurrenceState.Exception; 
                } 
                else if (apt.RecurrenceRule != string.Empty) 
                { 
                    apt.RecurrenceState = RecurrenceState.Master; 
                }                
                appointments.Add(apt); 
            } 
 
            return appointments; 
        } 
 

...

        public override void Update(RadScheduler owner, Appointment appointmentToUpdate) 
        { 
            if (!PersistChanges) 
            { 
                return
            } 
 
            Event _event = Event.GetEvent(new Guid(appointmentToUpdate.ID.ToString())); 
             
            _event.Name = appointmentToUpdate.Attributes["Name"]; 
            _event.StartDateTime = appointmentToUpdate.Start; 
            _event.EndDateTime = appointmentToUpdate.End; 
            _event.Description = appointmentToUpdate.Subject; 
            _event.LocationName = appointmentToUpdate.Attributes["LocationName"]; 
            _event.Address1 = appointmentToUpdate.Attributes["Address1"]; 
            _event.Address2 = appointmentToUpdate.Attributes["Address2"]; 
            _event.City = appointmentToUpdate.Attributes["City"]; 
            Resource state = _appointmentToUpdate.Resources.GetResourceByType("StateId"); 
            if (state != null
                _event.StateId = Convert.ToInt32(state.Key); 
            _event.PostalCode = appointmentToUpdate.Attributes["PostalCode"]; 
            _event.Phone1 = appointmentToUpdate.Attributes["Phone1"]; 
            _event.ContactName = appointmentToUpdate.Attributes["ContactName"]; 
            Resource isActive = appointmentToUpdate.Resources.GetResourceByType("IsActive"); 
            if (isActive != null
                _event.IsActive = Convert.ToBoolean(isActive.Key); 
            _event.RecurrenceRule = appointmentToUpdate.RecurrenceRule; 
            if (appointmentToUpdate.RecurrenceParentID != null
                _event.RecurrenceParentId = new Guid(appointmentToUpdate.RecurrenceParentID.ToString()); 
 
 
            _event.Save(); 
 
        } 
 


Of course this could have been implemented in many other ways and probably better, but this was my quick way out of it.

Regards

Fabio Honigmann
0
jonnyO
Top achievements
Rank 1
answered on 21 May 2008, 08:15 PM
Hello Peter
About a potential demo...
I'm trying to wrap my brain around the Provider in VB.  Got everything working with a custom SQL data design but I'm having difficulty association with a Custom Advanced Template scenario.  I want the flexibility to add a 1) description TextBox, 2) event Type RadComboBox (personal, work, family, etc), to 3) add an image RadUpload, and 4) attachment doc RadUpload and a 5) hidden field UserID(int) based on login that will act as a filter during GetAppointments.  The image would be rendered in the Appointment cell and the attachment (if present) rendered via an Appointment cell button onclick event or RadWindow event.
What do you think?
Thanks
0
Peter
Telerik team
answered on 22 May 2008, 11:27 AM

Thanks, Jonny. That's an interesting scenario which wraps a lot of advanced functionalities for RadScheduler. We will certainly consider it for an online demo. Meahnwhile, you can review the Customizing the Advanced Template  example and the KB article on How to pass parameters to a custom database provider which will help you with this scneario.



All the best,
Peter
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
Tags
Scheduler
Asked by
Doug Odegaard
Top achievements
Rank 2
Answers by
Piyush Bhatt
Top achievements
Rank 2
Peter
Telerik team
Doug Odegaard
Top achievements
Rank 2
Sanjay Kumar
Top achievements
Rank 1
Fabio Honigmann
Top achievements
Rank 2
jonnyO
Top achievements
Rank 1
Share this question
or