Intersoft Support Center

Adding custom fields in WebScheduler using Extensibility feature

This walkthrough shows how to add custom fields in WebScheduler using Extensibility feature.

During this walkthrough, you will learn how to do the following:

  • Bind WebScheduler.NET using ISDataSource.NET
  • Add custom fields using Extensibility feature
  • Enable editing in WebScheduler.NET
  • Modify EditingForm_Extended.aspx
  • Enable editing for custom fields

 Prerequisites

In order to complete this walkthrough, you will need to do the following:

  • Access to the Microsoft Access WebScheduler_EventOrganizer.mdb.
  • Visual Studio 2005/2008/2010 application.

 Step-By-Step Instructions

To add custom fields in WebScheduler using Extensibility feature

Bind WebScheduler.NET using ISDataSource.NET
  1. Create WebScheduler_EventOrganizer.mdb (access database).
  2. Here are the tables that should exist in the database.
    Categories
    FieldName DataType
    CategoryID AutoNumber
    CategoryName Text
    CategoryDescription Text
    CategoryColor Text

    Resources
    FieldName DataType
    IResourceD AutoNumber
    ResourceName Text
    ResourceDescription Text
    ResourceColor Text

    Events
    FieldName DataType
    EventID AutoNumber
    CategoryID Text
    ResourceID Number
    Mode Number
    ClientName Text
    EventDescription Text
    AllDayEvent Yes/No
    StartTime Date/Time
    EndTime Date/Time
    ReminderTimeSpan Number
    Location Text
    Notes Text
    TotalAttendees Number
    Note: The highlighted columns (Notes and TotalAttendees) are custom fields.

    RecurrenceEvents
    FieldName DataType
    EventID AutoNumber
    RecurrenceID Number
    CategoryID Text
    ResourceID Number
    ParentID Number
    Mode Number
    ClientName Text
    EventDescription Text
    AllDayEvent Yes/No
    StartTime Date/Time
    EndTime Date/Time
    ExceptionDate Date/Time
    ExceptionInfo Number
    ReminderTimeSpan Number
    Location Text
    Notes Text
    TotalAttendees Number
    Note: The highlighted columns (Notes and TotalAttendees) are custom fields.

    RecurrenceInfo
    FieldName DataType
    RecurrenceID AutoNumber
    Mode Number
    RangeMode Number
    StartDate Date/Time
    EndDate Date/Time
    TotalRecurrences Number
    NDay Number
    NWeek Number
    NMonth Number
    NYear Number
    WeekDays Text

  3. Launch Visual Studio.NET 2005.
  4. Click on File menu, then select New and click Web Site.
  5. Select ASP.NET Web Site in the Template box and set Location to HTTP.
  6. Named the Web Site and click OK.
  7. Right-click on Project's name and select Add New Item.
  8. Select Intersoft AppForm in the My Templates box and named it as Walkthrough.aspx.
  9. Drag and drop WebScheduler instance from toolbar to WebForm.
  10. Drag and drop ISDataSource instance from toolbar to WebForm.
  11. In the Solution Explorer, right-click on App_Data and select Add Existing Item.
  12. Browse and add WebScheduler_EventOrganizer.mdb (the database that you have created).
  13. In the Solution Explorer, right-click on App_Code and select Add New Item.
  14. Add a Dataset and named itWebScheduler_EventOrganizer.xsd.
  15. Drag and drop the tables from server explorer to the dataset then save the dataset.



  16. In the Solution Explorer, right-click on App_Code and select Add New Item.
  17. Add a new class and named it WebScheduler_EventOrganizer.cs.
  18. Add the following code to the WebScheduler_EventOrganizer.cs.

    C# Copy Code
    namespace EventOrganizerTableAdapters
    { 
       public partial class ResourcesTableAdapter : global::System.ComponentModel.Component
       {   
          [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]   
          [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]   
          [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Insert, true)]   
          public virtual int Insert(int ResourceID, string ResourceName, string ResourceDescription, string ResourceColor)   
          {        
             this.Connection.Open();        
             try        
             {            
                this.Insert(ResourceName, ResourceDescription, ResourceColor);            
                OleDbCommand command = new OleDbCommand();            
                command.CommandText = "SELECT @@IDENTITY";            
                command.Connection = this.Connection;            
                return (int)command.ExecuteScalar();        
             }        
             finally        
             {            
                this.Connection.Close();        
             }   
          }
       } 
    
       public partial class CategoriesTableAdapter : global::System.ComponentModel.Component
       {   
          [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]   
          [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]   
          [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Insert, true)]   
          public virtual int Insert(int CategoryID, string CategoryName, string CategoryDescription, string CategoryColor)   
          {        
             this.Connection.Open();        
             try        
             {            
                this.Insert(CategoryName, CategoryDescription, CategoryColor);            
                OleDbCommand command = new OleDbCommand();            
                command.CommandText = "SELECT @@IDENTITY";         
                command.Connection = this.Connection;            
                return (int)command.ExecuteScalar();        
             }        
             finally        
             {            
                this.Connection.Close();        
             }   
          }
       } 
       public partial class RecurrenceInfoTableAdapter : global::System.ComponentModel.Component
       {   
          [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]   [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
          [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Insert, true)] 
          public virtual int Insert(int RecurrenceID, global::System.Nullable<int> Mode, global::System.Nullable<int> RangeMode, 
          global::System.Nullable<global::system.datetime> StartDate, global::System.Nullable<global::system.datetime> EndDate, 
          global::System.Nullable<int> TotalRecurrences, global::System.Nullable<int> NDay, global::System.Nullable<int> NWeek, 
          global::System.Nullable<int> NMonth, global::System.Nullable<int> NYear, string WeekDays)   
          {        
             this.Connection.Open();        
             try        
             {            
                this.Insert(Mode, RangeMode, StartDate, EndDate, TotalRecurrences, NDay, NWeek, NMonth, NYear, WeekDays);            
                OleDbCommand command = new OleDbCommand();            
                command.CommandText = "SELECT @@IDENTITY";            
                command.Connection = this.Connection;            
                return (int)command.ExecuteScalar();        
    
             }        
             finally        
             {            
                this.Connection.Close();        
             }   
          }
       } 
       public partial class RecurringEventsTableAdapter : global::System.ComponentModel.Component
       {   
          [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]   
          [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]   
          [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Insert, true)] 
          public virtual int Insert(int EventID, global::System.Nullable<int> RecurrenceID, string CategoryID, 
          global::System.Nullable<int> ResourceID, global::System.Nullable<int> ParentID, global::System.Nullable<int> Mode, 
          string ClientName, string EventDescription, bool AllDayEvent, global::System.Nullable<global::system.datetime> StartTime,       global::System.Nullable<global::system.datetime> EndTime, global::System.Nullable<global::system.datetime> ExceptionDate, 
          global::System.Nullable<int> ExceptionInfo, global::System.Nullable<int> ReminderTimeSpan, string Location, string Notes, global::System.Nullable<int> TotalAttendees)         {        
             this.Connection.Open();        
             try        
             {            
                this.Insert(RecurrenceID, CategoryID, ResourceID, ParentID, Mode, ClientName, EventDescription, 
                AllDayEvent, StartTime, EndTime, ExceptionDate, ExceptionInfo, ReminderTimeSpan, Location, Notes, TotalAttendees);            
                OleDbCommand command = new OleDbCommand();            
                command.CommandText = "SELECT @@IDENTITY";            
                command.Connection = this.Connection;            
                return (int)command.ExecuteScalar();        
             }        
             finally        
             {            
                this.Connection.Close();        
             }   
          }
       } 
       public partial class EventsTableAdapter : global::System.ComponentModel.Component
       {   
          [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]   
          [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]   
          [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Insert, true)] 
          public virtual int Insert(int EventID, string CategoryID, global::System.Nullable<int> ResourceID, 
          global::System.Nullable<int> Mode, string ClientName, string EventDescription, bool AllDayEvent, 
          global::System.Nullable<global::system.datetime> StartTime, global::System.Nullable<global::system.datetime> EndTime, 
          global::System.Nullable<int> ReminderTimeSpan, string Location, string Notes, global::System.Nullable<int> TotalAttendees)   
          {        
             this.Connection.Open();        
             try        
             {            
                this.Insert(CategoryID, ResourceID, Mode, ClientName, EventDescription, AllDayEvent, StartTime, EndTime, ReminderTimeSpan, Location, Notes, TotalAttendees);                        OleDbCommand command = new OleDbCommand();            
                command.CommandText = "SELECT @@IDENTITY";            
                command.Connection = this.Connection;            
                return (int)command.ExecuteScalar();        
            }        
            finally        
            {            
               this.Connection.Close();        
            }
         } 
      }
    }
    

  19. Build the solution.
  20. Click the SmartTag and select Configure Data Source… on the upper right of the ISDataSource.
  21. Select SchemaType to DataSet and Schema Name to WebScheduler_EventOrganizer then click Next.



  22. Make sure the Select, Insert, Update and Delete tab for each table is not empty then click Finish. Note that you need to choose the Insert method that is specified in WebScheduler_EventOrganizer.cs.



  23. Select WebScheduler instance and press F4 to show the WebScheduler’s properties.
  24. Set the following properties:

    Property Value
    DataSourceID ISDataSource1
    CategoriesDataMember Events
    RecurrenceDataMember RecurrenceInfo
    RecurringEventsDataMember RecurringEvents
    ResourcesDataMember Resources



  25. Expand DataBinding and specify the fields of CategoryBinding, EventsBinding, RecurrenceBinding, RecurrenceEventsBinding and ResourcesBinding based on the database fields.


Add custom fields using Extensibility feature
  1. Open WebScheduler_EventOrganizer.cs.
  2. Add EOEvent class which is inherited from WebSchedulerEvent object and add the custom properties. The custom properties must have XmlSerializable and BinarySerializable attributes.
    In this walkthrough, Notes and TotalAttendees custom properties are added.

    C# Copy Code
    using System;
    using ISNet.WebUI.WebScheduler;
    using System.ComponentModel;
    using ISNet.Serialization;
    using System.Data.OleDb;
    public class EOEvent : WebSchedulerEvent
    { 
       private string _notes = ""; 
       private int _totalAttendees = 0;
       [NotifyParentProperty(true)]
       [XmlSerializable(), BinarySerializable()] 
       public string Notes
       {     
          get { return this._notes; }     
          set { this._notes = value;}
       }
       [NotifyParentProperty(true)]
       [XmlSerializable(), BinarySerializable()] 
       public int TotalAttendees       
       {     
          get { return this._totalAttendees; }     
          set { this._totalAttendees = value; }
       }
    }
    

  3. Add EORecurringEvent class which is inherited from WebSchedulerRecurringEvent object and add the custom properties. The custom properties must have XmlSerializable and BinarySerializable attributes. In this walkthrough, Notes and TotalAttendees custom properties are added.

    C# Copy Code
    public class EORecurringEvent : WebSchedulerRecurringEvent
    { 
       private string _notes = ""; 
       private int _totalAttendees = 0;
       [NotifyParentProperty(true)]
       [XmlSerializable(), BinarySerializable()] 
       public string Notes
       {     
          get { return this._notes; }     
          set { this._notes = value; }
       }
       [NotifyParentProperty(true)]
       [XmlSerializable(), BinarySerializable()] 
       public int TotalAttendees
       {     
          get { return this._totalAttendees; }     
          set { this._totalAttendees = value; }
       }
    }
    

  4. Open ExtensibilityWalkthrough.aspx.
  5. Add the following script code. You need to create the same extended class in client side. In this walkthrough, we will add EOEvent and EORecurringEvent class in client side.

    Javascript Copy Code
    <script type="text/javascript">
         
       //inherit the class from WebSchedulerEvent class     
       function EOEvent()     
       {     
          WebSchedulerEvent.call(this);          
           this._Type = "EOEvent";                       
           this.Notes = "";         
           this.TotalAttendees = 0;     
       }          
    
       //inherit the class from WebSchedulerRecurringEvent class     
       function EORecurringEvent()     
       {         
          WebSchedulerRecurringEvent.call(this);          
          this._Type = "EORecurringEvent";                       
          this.Notes = "";         
          this.TotalAttendees = 0;     
       }
    </script>
    

  6. Switch to Design view and set ExtendedEventTypeName and ExtendedRecurringEventTypeName properties.


  7. Add OnDataBound server side event. In this event, the custom fields are bound to the related field in database.

    C# Copy Code
    protected void WebScheduler1_DataBound(object sender, ISNet.WebUI.WebScheduler.WebSchedulerDataBoundDataArgs e)
    {     
       switch (e.Type)     
       {         
          case ISNet.WebUI.WebScheduler.WebSchedulerObjectType.Event:             
             EOEvent evt = e.DataObject as EOEvent;             
             evt.Notes = e.DataRow["Notes"].ToString();             
             if (e.DataRow["TotalAttendees"] != System.DBNull.Value)                 
                evt.TotalAttendees = int.Parse(e.DataRow["TotalAttendees"].ToString());             
             break;
    
          case ISNet.WebUI.WebScheduler.WebSchedulerObjectType.RecurringEvent:             
             EORecurringEvent recurringEvent = e.DataObject as EORecurringEvent;             
             recurringEvent.Notes = e.DataRow["Notes"].ToString();             
             if (e.DataRow["TotalAttendees"] != System.DBNull.Value)                 
                recurringEvent.TotalAttendees = int.Parse(e.DataRow["TotalAttendees"].ToString());             
             break;     
       }
    }
    

Enable editing in WebScheduler.NET
  1. Open WebScheduler_EventOrganizer.cs.
  2. Set the following properties

    FieldName DataType
    DataEditing-AllowAdd Yes
    DataEditing-AllowEdit Yes
    DataEditing-AllowResize Yes
    DataEditing-allowMova Yes

  3. When AllowEdit is set to Yes, you will be prompted to add EditingForm.aspx to the solution. The default path is WebScheduler/EditingForm.aspx. The EditingUrl property will be set to that path.
  4. Browse to WebScheduler/EditingForm.aspx and rename it to EditingForm_Extended.aspx.
  5. In the Solution Explorer, right click in Bin, and add the following assemblies from each product folder.

    FieldName DataType
    ISNet.WebUI.WebCombo.dll C:\Program Files\Intersoft Solutions\WebCombo.NET 4.0\Bin
    ISNet.WebUI.WebInput.dll C:\Program Files\Intersoft Solutions\WebInput.NET 3.0\Bin
    ISNet.WebUI.WebDesktop.dll C:\Program Files\Intersoft Solutions\WebDesktop.NET 2.5\Bin

Modify EditingForm_Extended.aspx
  1. Open WebScheduler/EditingForm_Extended.aspx
  2. Add two rows under Categories row for Notes and TotalAttendees fields.
  3. Add two WebInput controls for the two fields, and name them wiTotalAttendees and wiNotes.
  4. The following is the complete added code. You can get EditingForm_Extended.aspx from Live Sample (C:\Program Files\Intersoft Solutions\Intersoft WebUI Studio.NET 2008 R2\ISNet.WebUI.Samples\cs\WebScheduler\WebScheduler).
    <tr> 
       <td>
          Total Attendees:
       </td>
       <td>
          <ISWebInput:WebInput ID="wiTotalAttendees" runat="server" Width="40px" NumericInput="True">
          <CalculatorEditor>
             <WindowInfo DisplayType="Normal">
             </WindowInfo>
          </CalculatorEditor>
          <CultureInfo CultureName="en-US">
          </CultureInfo>
          <DateTimeEditor>
             <WindowInfo DisplayType="Normal">
             </WindowInfo>
          </DateTimeEditor>
          </ISWebInput:WebInput>
       </td>
    </tr>
    
    <tr style="vertical-align: top;">
       <td>
          Notes:
       </td>
       <td>
          <ISWebInput:WebInput ID="wiNotes" runat="server" Width="90%" Rows="8" TextMode="MultiLine" Height="80px">
          <CultureInfo CultureName="en-US">
          </CultureInfo>
          <TextBoxStyle>
             <Active CssClass="textbox">
             </Active>
             <Over CssClass="textbox">
             </Over>
             <Normal CssClass="textbox">
             </Normal>
          </TextBoxStyle>
          </ISWebInput:WebInput>
       </td>
    </tr>
Enable editing for custom fields
  1. Open WebScheduler_EventOrganizer.cs
  2. Add OnEditingFormInitialize client side event, where the custom fields’ initial value can be set.

    Javascript Copy Code
    function WebScheduler1_OnEditingFormInitialize(controlId, action, eventView, eventType, newType)
    {          
       var s = ISGetObject(controlId);          
       var editWindow = s.GetEditingFormWindow();          
       var originalObject = eventView.GetOriginalObject();                  
    
       var notes = "";          
       var totalAttendees = 0;                    
    
       if (action == "Edit")          
       {              
          notes = originalObject.Notes;              
          totalAttendees = originalObject.TotalAttendees;          
       }                    
       
       var wiNotes = editWindow.ISGetObject("wiNotes");          
       wiNotes.SetValueData(notes);                    
     
       var wiTotalAttendees = editWindow.ISGetObject("wiTotalAttendees");          
       wiTotalAttendees.SetValueData(totalAttendees);                    
    
       return true;
    }
                                

  3. Add OnBeforeAdd and OnBeforeEdit client side events, to save the custom fields’ value during add and edit process.

    Javascript Copy Code
    function WebScheduler1_OnBeforeAdd(controlId, evt)
    {     
       var s = ISGetObject(controlId);                           
       SetFields(s, evt.Parent);                           
       return true;
    }                    
    
    function WebScheduler1_OnBeforeEdit(controlId, evt)
    {      
       var s = ISGetObject(controlId);                             
       SetFields(s, evt.Parent);                             
       return true;
    }                    
    
    function SetFields(s, eventView)
    {       
       var editWindow = s.GetEditingFormWindow();               
       
       var notes = "";       
       var totalAttendees = 0;               
    
       if (editWindow != null)       
       {           
          notes = editWindow.ISGetObject("wiNotes").GetValueData();           
          totalAttendees = editWindow.ISGetObject("wiTotalAttendees").GetValueData();       
       }               
    
       eventView.SetProperty("Notes", notes);       
       eventView.SetProperty("TotalAttendees", totalAttendees);
    }
    

The custom fields are added to the architecture and UI of WebScheduler. You can try to run the page and add/edit the custom fields’ value. The process will be updated to physical database.

Previous Next