Skip Navigation LinksHome / Community & Support / Code Library / ASP.NET and ASP.NET AJAX > Scheduler > Filter appointments by sending additional information to the Web Service and the provider

Not answered Filter appointments by sending additional information to the Web Service and the provider

Feed from this thread
  • Posted on Nov 23, 2011 (permalink)

    Requirements

    RadControls version

     Q1 2011 or later

    .NET version

     4.0

    Visual Studio version

     2010

    programming language

     C# and VB.NET

    browser support

    all browsers supported by RadControls


    PROJECT DESCRIPTION

    The attached samples show how to filter appointments by sending additional information to the Web Service and the provider. Here are the help topics that describe the approach in a step-by-step fashion: SchedulerDbProvider.zip contains a demo with a custom Data Base Scheduler provider. You can add this scenario to your application using Telerik Visual Studio Extensions - http://screencast.com/t/6mBhGX6KYoa

    SchedulerCustomXmlProvider.zip contains a stand-alone sample of the Web Service Binding online demo.

    Here is a step-by-step tutorial on how the SchedulerCustomXmlProvider is implemented:

    1. Create a custom class that inherits from SchedulerInfo and expose a property that will carry the filter criteria. In this case we will need an array of strings to take on the names of the selected resources. 

      App_Code/MySchedulerInfo.cs:
      public class MySchedulerInfo : SchedulerInfo
      {
          public string[] CategoryNames { get; set; }
          public MySchedulerInfo(ISchedulerInfo baseInfo, string[] categoryNames)
              : base(baseInfo)
          {
              CategoryNames = categoryNames;
          }
          public MySchedulerInfo()
          {
       
          }
      }

       
    2. In SchedulerWebService.cs, change the parameter type for all the methods from SchedulerInfo to MySchedulerInfo. Also specify the provider - CustomXmlSchedulerProvider, which we will create in step 5.
      public class SchedulerWebService : WebService, IRequiresSessionState
      {
          private WebServiceAppointmentController _controller;
          public const string ProviderSessionKey = "SchedulerWebServiceData";
       
          private WebServiceAppointmentController Controller
          {
              get
              {
                  CustomXmlSchedulerProvider provider;
                  if ((Session[ProviderSessionKey] == null))
                  {
                      provider = new CustomXmlSchedulerProvider(Server.MapPath("~/App_Data/Appointments_Outlook.xml"), false);
                      Session[ProviderSessionKey] = provider;
                  }
                  else
                  {
                      provider = (CustomXmlSchedulerProvider)Session[ProviderSessionKey];
                  }
       
                  if (_controller == null)
                  {
                      _controller = new WebServiceAppointmentController(provider);
                  }
       
                  return _controller;
              }
          }
           
          [WebMethod(EnableSession = true)]
          public IEnumerable<AppointmentData> GetAppointments(MySchedulerInfo schedulerInfo)
          {
              return Controller.GetAppointments(schedulerInfo);
          }
       
          [WebMethod(EnableSession = true)]
          public IEnumerable<AppointmentData> InsertAppointment(MySchedulerInfo schedulerInfo, AppointmentData appointmentData)
          {
              return Controller.InsertAppointment(schedulerInfo, appointmentData);
          }
       
          [WebMethod(EnableSession = true)]
          public IEnumerable<AppointmentData> UpdateAppointment(MySchedulerInfo schedulerInfo, AppointmentData appointmentData)
          {
              return Controller.UpdateAppointment(schedulerInfo, appointmentData);
          }
       
          [WebMethod(EnableSession = true)]
          public IEnumerable<AppointmentData> CreateRecurrenceException(MySchedulerInfo schedulerInfo, AppointmentData recurrenceExceptionData)
          {
              return Controller.CreateRecurrenceException(schedulerInfo, recurrenceExceptionData);
          }
       
          [WebMethod(EnableSession = true)]
          public IEnumerable<AppointmentData> RemoveRecurrenceExceptions(MySchedulerInfo schedulerInfo, AppointmentData masterAppointmentData)
          {
              return Controller.RemoveRecurrenceExceptions(schedulerInfo, masterAppointmentData);
          }
       
          [WebMethod(EnableSession = true)]
          public IEnumerable<AppointmentData> DeleteAppointment(MySchedulerInfo schedulerInfo, AppointmentData appointmentData, bool deleteSeries)
          {
              return Controller.DeleteAppointment(schedulerInfo, appointmentData, deleteSeries);
          }
       
          [WebMethod(EnableSession = true)]
          public IEnumerable<ResourceData> GetResources(MySchedulerInfo schedulerInfo)
          {
              return Controller.GetResources(schedulerInfo);
          }
      }
    3. In RadSchedulerWebForm.aspx, handle onchange of the checkboxes to rebind RadScheduler. Also, extract the names of the selected checkboxes and store them in an array using jQuery.
      <script type="text/javascript">
      var categoryNames = new Array();
       
      function addSelectedCategoriesToArray(categoryNamesArray) {
                  var $ = $telerik.$;
                  var categoryPanelBar = $find('<%=RadPanelBar1.ClientID %>');
                  $(':checkbox:checked', categoryPanelBar.get_element()).each(function () {
                      categoryNames.push($(this).attr('name'));
                  });
              }
       
       
      function rebindScheduler() {
                  var scheduler = $find('<%=RadScheduler1.ClientID %>');
                  scheduler.rebind();
              }
      ***
      </script>
       
      <input id="chkDevelopment" type="checkbox" title="Development" onchange="rebindScheduler()"
                                                      value="Development" checked="checked" name="Development" />
                                                  <span>Development</span>
    4. Populate the MySchedulerInfo property by handling OnClientAppointmentsPopulating:
      function OnClientAppointmentsPopulating(sender, eventArgs) {
                  addSelectedCategoriesToArray(categoryNames);
                  eventArgs.get_schedulerInfo().CategoryNames = categoryNames;
                  categoryNames = new Array(); //clear the array
              }
    5. Create a custom provider that inherits from XmlSchedulerProvider.

      App_Code/ CustomXmlSchedulerProvider.cs:
      public class CustomXmlSchedulerProvider : XmlSchedulerProvider
      {
          public CustomXmlSchedulerProvider(string dataFileName, bool persistChanges)
              : base(dataFileName, persistChanges)
          {
       
          }
      }

      Creating a custom provider might sound like a laborious task, but in this case it is quite simple and easy. We only need to override the GetAppointments method and let the XmlSchedulerProvider base do the rest of the work such as Inserting, Updating or Deleting appointments.
    6. Override the GetAppointments method and access the value of the CategoryNames property by casting the schedulerInfo parameter to MySchedulerInfo:
      public override IEnumerable<Appointment> GetAppointments(ISchedulerInfo schedulerInfo)
         {
             var myInfo = schedulerInfo as MySchedulerInfo;
             if (myInfo.CategoryNames != null)
             {
                 var appointmentsList = base.GetAppointments(schedulerInfo);
                 var appointmentsWithCalendarResource = appointmentsList.Where(a => a.Resources.GetResourceByType("Calendar") != null).Select(a => a);
       
                 var predicate = PredicateBuilder.False<Appointment>();
       
                 foreach (string categoryName in myInfo.CategoryNames)
                 {
                     string temp = categoryName;
                     predicate = predicate.Or(a => a.Resources.GetResourceByType("Calendar").Text == temp);
                 }
       
                 return appointmentsWithCalendarResource.AsQueryable().Where(predicate).Select(a => a).AsEnumerable();
             }
             else
             {
                 return base.GetAppointments(schedulerInfo);
             }
         }
    7. Once you get a hold of the selected category names (myInfo.CategoryNames) there are various ways to filter the appointments list (base.GetAppointments(schedulerInfo)).  Using LINQlambda expressions and a predicate builder for example is a neat way to do this. You will need to add the System.Linq.Expressions namespace and a PredicateBuilder class:
      public static class PredicateBuilder
      {
          public static Expression<Func<T, bool>> True<T>() { return f => true; }
          public static Expression<Func<T, bool>> False<T>() { return f => false; }
       
          public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                              Expression<Func<T, bool>> expr2)
          {
              var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
              return Expression.Lambda<Func<T, bool>>
                    (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
          }
       
          public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                               Expression<Func<T, bool>> expr2)
          {
              var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
              return Expression.Lambda<Func<T, bool>>
                    (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
          }
      }

      Note that when using a predicate builder, it is important to create a temp string variable because categoryName is of type string which is a reference type. Otherwise, the predicate builder will use just the last value for catergoryName in the foreach cycle .
      foreach (string categoryName in myInfo.CategoryNames)
      {
          string temp = categoryName;
          predicate = predicate.Or(a => a.Resources.GetResourceByType("Calendar").Text == temp);
      }

       

    Reply

  • Alok avatar

    Posted on Jan 4, 2012 (permalink)

    Hi

         I have went through http://demos.telerik.com/aspnet-ajax/scheduler/examples/resourceavailability/defaultcs.aspx ,in which all available  room displayed ,i have same situation in which i need to display all my resources and his available time.how can i do the same thing MVC 3 project. can i get a sample application using .net 4.0 and MVC 3.

     

    Thanks

    Alok Gupta

    Reply

Back to Top

Skip Navigation LinksHome / Community & Support / Code Library / ASP.NET and ASP.NET AJAX > Scheduler > Filter appointments by sending additional information to the Web Service and the provider