Sample App : Extend WideLens to Display Salesforce.com Custom Events

Page Status: Beta

Back to WideLens

WideLens is a Bungee Connect’s reference calendaring web application. It not only serves as a commercial-grade application that you can use to aggregate and update distributed calendars from a variety of sources, it also serves as a model for how you can extend any application built on the Bungee Connect platform.

Contents

Overview

This article will show you how to reuse and extend Bungee objects to create new data sources for your own calendar web application using WideLens as your starting point.

When finished with the article, you will have done the following with WideLens:
  • Import the source code into your DesignGroup and run it as an application
  • Identify the default data source, enable additional calendar data sources and display them simultaneously
  • View the Bungee Logic source code for the WideLens Salesforce.com Events driver
  • Extend the Events driver to create a new Opportunities driver which displays Salesforce.com opportunities by their close date
  • Add your custom calendar source to the list of existing WideLens calendar sources
  • Copy the generic event detail form and modify it to display Salesforce.com opportunity details
  • Embed your deployed WideLens application into the Salesforce.com dashboard
When finished with the article you will understand how to do the following with Bungee:
  • Customize and extend an existing Bungee application to meet the unique needs of your department or organization
  • Create new objects from existing Bungee objects without having to re-create much, if any, of the existing code
  • Embed a Bungee application into another website
This article provides a basic, high-level demonstration of the WideLens reference application and Bungee Connect. For a more comprehensive introduction to Bungee Connect’s development environment, I suggest that you read “Getting Started with Bungee Connect” on your Bungee Connect Start Tab.

Getting Oriented

WideLens is a sophisticated and powerful web application providing a highly interactive and rich user interface with connectivity to multiple web services (SOAP and POX / REST) and leveraging a relational data store (in this case MySQL).
 
WideLens supports the viewing of and interaction with multiple distributed calendars in a single integrated web application and is super extensible in terms of new data sources, user experience and functionality. In this article I will introduce you to the power of the Bungee Connect platform by explaining how WideLens can be extended and customized to meet your organizational needs using its powerful object inheritance model.
 
We start by showing you the WideLens calendar source that is enabled by default along with additional built-in calendar sources you may enable such as Microsoft Exchange, Facebook Calendars, Google Calendars, Salesforce.com Calendars and iCal Calendars.
Note: In the next section, we show you how to extend WideLens by creating your own custom calendar driver. And at the end of the article we also show you how to embed your WideLens calendar into a third-party application such as Salesforce.com.
First, let’s do the easy part. Let’s see which calendar is enabled when you first log into WideLens. Import and run the WideLens reference application within Bungee Connect by following these steps:
Figure 1. Importing WideLensReferenceApp
Import WideLens into your Bungee Connect DesignGroup: 
  • To do this, you must first have a Bungee Connect developer account. You can create a developer account at http://builder.bungeeconnect.com.
  • Once logged into your Bungee Connect developer account, click on the Design Tab, click WideLensReferenceApp under Open Example Code, Premiere Examples.
  • In the dialog, you can choose a DesignGroup and enter a Solution Name. Then click OK to import the WideLens application.

Figure 2. Bungee Builder reference figure

Once the WideLens Solution is imported, you run it from within Bungee Builder by opening the WideLens Main form and clicking the Run button in the toolbar. Follow these steps to open the Main form:
  • To run the WideLens, click the green Run button on the Toolbar. WideLens will open in a new browser window. If it is your first time, you will need to create a WideLens user account. Once you have completed the registration and logged in, you will see a typical calendar layout with month view on the left and the calendar on the right.
Figure 3. WideLens Reference Application

 

My Calendars

To view the calendar sources enabled by default in WideLens, click the drop-down button next to “My Calendars” in the upper left corner of your browser window.  As you can see in Figure 3, the calendar available is called “dave’s Calendar”. This is your default calendar source, though it will display the username of the account holder. As we enable additional calendars sources, they will appear here too.
 

Check the box next to the calendar source to turn it on or off. If there are events in the selected calendar source, they will appear in your calendar when the box is checked.

Note: Watch this video for an overview of the WideLens in action here.

Manage My Account

To manage the calendar sources that appear in your ‘My Calendars’ list, click the ‘Settings’ button in toolbar. The Settings window opens and you will see a list of calendars that have been enabled. Click the ‘My Calendars’ item on the left, to see the list of supported calendar sources.
 
To add a new calendar, select one of the supported calendar source types from the drop down list; fill in the required information and click “Add New Calendar”.
 

Close the Settings window and go back to the “My Calendars” section in the main calendar. You should see your new calendar source displayed along with your default data source. Checking its checkbox will enable a second source of calendar events.

Figure 4. Settings

 Extending the Salesforce.com Driver

As you can see, it is easy to enable one of the five pre-integrated calendar sources. But if you need to view an external calendar that is not already supported, there is another option. WideLens and its source code are provided for you to view, update, change or extend as you see fit. And with Bungee’s powerful inheritance and reuse capabilities, you will see how quickly you can integrate a new calendar source. 
 
In this section, we will drill down into the drivers that provide data to the calendar and examine the changes required to create a custom driver to enable additional calendars, such as the Salesforce.com Opportunities calendar.
 
Before we integrate the new Salesforce.com data source, you might find it helpful to take a moment to learn how the WideLens user interface is designed and how it gets event data to display to the user. So before continuing, it is recommended that you read the Quick Tour of the Source Code section at the end of this article. Of course you may skip this section if you are already familiar with how Bungee Connect forms and controls relate to each other within WideLens.
 

Getting Started

Open the Main form within the Main class within the Main project within WideLens (if you don’t have the Bungee Calendar solution listed within one of your Design Groups, follow the instructions in the Getting Oriented section of this article to install WideLens and open the Main form in design view). For reference, you may want to open the Main form and view it in action. With the Main form displayed in design view, click Run in the Bungee Builder toolbar. This will launch WideLens.
Figure 5. Main form open within Bungee Builder

Choosing a Source of Data

Before we begin, we need to decide upon a new, and hopefully useful, data source that contains time-based information. And to show off the flexibility of the WideLens and the Bungee Connect platform, we’ll use a data source that is not typically considered an event, such as a Salesforce.com Opportunity.
 
Within Salesforce.com, the Opportunities tab contains a Close Date field which represents the date a sales rep expects to close a sale. We will use this Close Date to represent the start date and time for each Opportunity. This new list of Opportunity events should be useful to sales reps who want to keep on top of their sales pipeline.
Figure 6. Close Date on Salesforce.com Opportunities tab

Inheritance and Extension

Now let’s have a look at how WideLens connects to additional data sources through a set of reusable driver classes. One of the goals for the creators of this WideLens reference application was to design the driver framework to make it relatively easy to add additional driver classes. And since a Salesforce.com Events driver already exists within WideLens, we can demonstrate this by inheriting the functionality of the driver classes and then extending them to add new Opportunity-specific fields.
 

Salesforce.com Driver Classes

The following is a list of the classes that make up the Salesforce.com Event driver:
  • SalesforceConfig – inherits from ConnectionConfig base class in the DriverBase project and is the class that references all configuration for the driver including the calendar resource, credentials, capabilities, and display settings.  This is also where you would set the icon for a calendar type by overriding the getIcon function.
  • SalesforceConnection – inherits from Connection base class in the DriverBase project and is the class that contains all the fields and functions for providing the two way communication between the calendar app and a specific calendar source.  These are the functions that interface with the SOAP or the REST service to perform the basic actions: create, update, retrieve, delete.
  • SalesforceCredential – inherits from Credential base class in the DriverBase project and is the class that contains the functions and fields for storing information about a specific calendar. Contains username and password and the form used when adding a new calendar instance.
  • SalesforceEvent – inherits from Event base class in the PIM project and is the class that contains the functions and fields for storing information about an event and operating on an event.  This is where the date returned from a SOAP or REST call is converted to an Event.
The base classes act as interfaces from which all customized vendor drivers inherit, allowing the all the code to be written with reference to the base classes.  At runtime, the running app will determine the actual type of an Event instance, for example, SalesforceEvent.  The app will then use the function overrides within the SalesforceEvent class as needed.
 
These classes provide much of the functionality we’ll need for our Opportunity driver. But every calendar has its own unique features that require customization in order to integrate. So it is the intention of the creators of the WideLens reference application to build a driver framework that reduces much of the duplicate effort to create new calendar drivers, while providing enough flexibility to handle the wide variety and types of data that users require. So using their framework, we’ll create a parallel set of objects that inherit from these existing driver classes and extend the functionality to meet the unique needs of our new driver.
 

Opportunity Driver

Within Salesforce.com, the Opportunity Close Date is bound to a simple dateTime field. This is different model than the standard Salesforce.com Event because it is made up of opportunity close dates rather than meeting times and locations. In other words, the opportunity data source contains opportunities, not events. Fortunately both the Event object and Opportunities object are inherited from the same base class. So we’ll be able to extend the Salesforce.com driver’s Event object to support the additional data required by the Salesforce Opportunity object without much additional effort.
 
The following steps summarize how to create a new calendar source:
    1. Copy the four Salesforce driver classes plus the SalesforceTest class
    2. Create override functions and fields to modify the behavior of some of the inherited functions
    3. Modify the driver’s SOQL query string to retrieve Opportunity objects instead of Event objects
    4. Replace the Salesforce.com username and password with your own
Once your driver is finished, you just need to add one record to your database to make your driver available to use. Since Bungee apps are model driven, you don’t have to modify the user interface in any way. Your opportunity close dates should begin appearing at once.
 

Creating a Driver: Step by Step

 
Prerequisites for completing this exercise:
-          WideLens must be imported into your Bungee Connect DesignGroup
-          You must have a Salesforce.com account (or a Salesforce.com Developer Edition account) with API access enabled
-          You must create at least one Opportunity in your Salesforce.com account 

Follow these steps to create your new Opportunity driver:

  1. Create the following classes within the VendorDrivers project or another project of your choice.
  • SalesforceOppConfig - inherits from SalesforceConfig
  • SalesforceOppConnection - inherits from SalesforceConnection
  • SalesforceOppCredential - inherits from SalesforceCredential
  • SalesforceOppEvent - inherits from SalesforceEvent
To create a class:
o   Right-click on the project folder containing your classes and select Add Class.
o   Give your class a name, making sure your project is selected in the list of projects
o   Select the class you want to inherit from and click OK
o   If you are asked to check out the project, click OK.
Figure 7. Adding a Class that Inherits from another
  1. Copy the SalesforceTest class and rename it SalesforceOppTest
To copy a class:
o   Select the SalesforceTest class
o   Right-click and select Copy
o   Right-click on the VendorDrivers project folder and select Paste
o   Find the new SalesforceTest1 class and rename it SalesforceOppTest
  1. Within SalesforceOppConnection, create Override functions for createNewEvent and removeEvent, and getCapabilities.
To create the Override functions:
o   Right-click on SalesforceOppConnection and select Add Override
o   Add createNewEvent and removeEvent to the right column
o   Click OK
o   Open the createNewEvent function and add the following code:
     createNewEvent.ok = true;
     return;  
o   Open the removeEvent function and add the following code:
     removeEvent.ok = true;
     return;
o   Open the getCapabilities function and add the following code (to call the original function, in the call function statement for getCapabilities, select "Parent" in from the drop-down list labeled "Scope":
     Parent.getCapabilities(getCapabilities.capabilities);
     getCapabilities.capabilities.canCreate = false;
     return;
These overrides will prevent the new driver from creating or deleting Salesforce.com opportunities.
  1. Within SalesforceOppConnection, copy and paste the Override function for computeEvents:

o   Select the computeEvents function within the SalesforceConnection parent class

o   Right-click and select Copy

o   Right-click on your new SalesforceOppConnection class folder and select Paste, it will also be named computeEvents

o   Double click the SalesforceOppConnection class to open it in the Design Editor

This new computeEvents function override will be executed instead of the inherited function, however many of its variables and functions are still the type of the parent class. To resolve this issue open your new function and update each object that is of a parent class type (e.g. "SalesforceEvent" becomes "SalesforceOppEvent") so it points to the new class. 

For your new computeEvents function, change the following code:
o   var SalesforceEvent newEvent to: var SalesforceOppEvent newEvent;
o   newEvent = new SalesforceEvent to: newEvent = new SalesforceOppEvent;
  1. To add the actual driver logic, do the following. Within the computeEvents function, modify the SOQL query string to retrieve Opportunity objects instead of Event objects
o   You may remove the condition statement as it is not needed
o   Replace the soql variable expression with "SELECT o.CloseDate, o.Account.Description, o.Account.Name, o.Account.Rating, o.Account.Type,
     o.Description, o.ForecastCategory, o.Id, o.LeadSource, o.Name, o.StageName, o.Type FROM Opportunity o"
Note: When testing SOQL statements, you may find Apex Explorer (also known as Force.com Explorer) very useful.
  1. We will now copy and paste the updateEvent override function from our base class SalesforceConnection to our new SalesforceOppConnection class:

o   Select the updateEvent function within the SalesforceConnection class in the Solution Detail pane.

o   Right-click and select Copy

o   Right-click on the SalesforceOppConnection class folder and select Paste, it will also be named updateEvent

o   Double click the SalesforceOppConnection class to open it in the Design Editor

Once again, many of this functions variables and functions are still referencing the base class type. To resolve this issue open your new function and update each object that is of the base type to the new class types "SalesforceOpp..".

 
For your new removeEvents function, change the following code:
o   var SalesforceEvent SalesforceEvent = updateEvent.event; to:
     var SalesforceOppEvent SalesforceOppEvent = updateEvent.event;
  1. Within SalesforceOppEvent, create an Override functions for initFromService, ok, and updateToService
To create the Override function:
o   Right-click on SalesforceOppEvent and select Add Override
o   Add initFromService, ok, and updateToService to the right column
o   Click OK
o   Open the initFromService function and add the following code:
 
o   Open the ok function and add the following code:
     hideIcon = true;

o   Open the updateToService function and add the following code:

Detail Form:
Since a Salesforce opportunity has different information than a Salesforce event, we wanted to display a Salesforce opportunity with a form specific to opportunities.  To do this, we used cut the SalesforceEvent Detail form and paste it into the SalesforceOppEvent class.  (Cut and Paste are right click options on a form.)  We then changed the labels on the form to describe elements of an opportunity (Account Name, Opportunity Name, Stage, Close Date, etc.) and bound other labels to the fields in order to display the values of Account Name, etc.

 

Description field:

There was not a field available in SalesforceOppEvent that made sense to contain the Salesforce opportunity description (we had already used subject for Account Name, location for Opportunity Name, annotation for stage) so we created a new field within SalesforceOppEvent to contain the opportunity description.  Also by using subject and location for Account Name and Opportunity Name, these two pieces of information are displayed on the event in the calendar app’s month, day or week views. 
 

Finishing Touches

 
Now that you have completed all of the steps to create your Opportunity driver, there are a few finishing touches.
 
The last item is to make the application aware of your new driver by simply inserting a new row into the database. The way to do this is to expand the MySQLDatabase project, the MySQL Datasource, and double click on the SQL Console, modify and insert the following SQL statement, and click Execute Query:
 
If you chose to put your new driver classes in a new project, other than VendorDrivers, you must put the name of the project and a forward slash in front of each class name in the SQL statement: (e.g. ‘MyDriverProject/SalesforceOppConfig’) .
 
INSERT INTO App_Driver (type, displayName, encryptCredential, credentialClass, configClass, connectionClass, ssoClass) VALUES ('SalesforceOPP', 'Salesforce Opportunities', 1, 'SalesforceOppCredential', 'SalesforceOppConfig', 'SalesforceOppConnection', 'SalesforceSSO')
 
Now that you’re done creating your new Opportunity driver, you’re probably wondering how the application finds the driver classes. In the Main project, the DriverManager class queries the App_Driver table in the database, which creates a drivers collection of type Driver. The Driver class contains the names of the classes, and two functions called loadClass, and loadObject. These functions dynamically return the class definition and class instance, respectively. Using these functions, the driver subclasses are loaded at runtime, and allow the system to easily be enhanced with additional drivers.
 

Testing

 
The easiest way to test your opportunity driver:
  1. Within the SalesforceOppTest class
o   change connection field Type property to SalesforceOppConnection
o   change events field Type property to SalesforceOppEvent
o   within login function, change the credential password and username to your own

Troubleshooting Tips 

If your code seems to work, but you aren’t getting back any data, check your variables to confirm that they are not only pointing to the correct variable, but that the variable is in the correct class. For example, you may have selected a variable within SalesforceEvent, when you should have chosen the same variable within SalesforceOppEvent.

 

Import SalesforceOpps_WideLensDerivative (Finished Product of this Article)

SalesforceOpps_WideLensDerivative is the finished product of this article. It is available on the Home tab for import.

Figure 8. Importing WideLensReferenceApp

Import SalesforceOpps_WideLensDerivative into your Bungee Connect DesignGroup: 
  • To do this, you must first have a Bungee Connect developer account. You can create a developer account at http://builder.bungeeconnect.com.
  • Once logged into your Bungee Connect developer account, click on the Design Tab, click SalesforceOpps_WideLensDerivative under Open Example Code, Applications.
  • In the dialog, you can choose a DesignGroup and enter a Solution Name. Then click OK to import the SalesforceOpps_WideLensDerivative application.

Embed WideLens into Salesforce.com  

Another way to take advantage of your new WideLens calendar is to embed it into your Salesforce.com account. This is an easy way to extend Salesforce.com too. 
 
Prerequisites
You don’t need to make any changes to your Bungee application.
 
To embed WideLens within your Salesforce.com account:
    1. Log into Bungee Builder and get the Application URL to your deployed instance of WideLens. You will find the Application URL under Deployement Settings on the Staging tab after selecting the name of your WideLens deployment under Deployments (see figure 9). The Application URL will look something like this:
      http://testdeploy.bungeeconnect.com/39832297-F566-4ED5-BA54-D063EAB8972D
    2. Log into your salesforce.com account as an Administrator or log into your Developer Edition account.
    3. Click the Setup link at the top of the page
    4. Under App Setup, Click the Build / Tabs link
    5. Next to Web Tabs, click New
    6. Follow the Steps provides:
Step 1: Select Full page width (the default) and click Next
Step 2: Select ‘URL’ for Tag Type. Name the Tab Label ‘WideLens’. Select any Style (such as Chalkboard) and click Next
Step 3: Paste the Application URL to your WideLens instance into the Button or Link URL section. Then add the following string to the Application URL.
 
?ssoType=Salesforce&sessionId={!User.Session_ID}&ApiServer= {!API.Enterprise_Server_URL_110}
 
This string includes Salesforce.com variables required to log into your WideLens account from within your Salesforce.com account. The result will look similar to this:
 
http://testdeploy.bungeeconnect.com/39832297-F566-4ED5-BA54-D063EAB8972D?ssoType=Salesforce&sessionId;={!User.Session_ID}&ApiServer;={!API.Enterprise_Server_URL_110}
 
Step 4: Leave the default and click Next
Step 5: Leave the default and click Save
A new WideLens tab will appear at the top of the page along with your other tabs. Click the tab and start using your new calendar right away.
Figure 9. Application URL

Additional Ideas

Bungee has made WideLens extensible and open to any number of modifications. There are many ways you can extend it to provide even more functionality to your end users. For instance, you could extend the Opportunity Event Detail form to display additional information about the Opportunity. Or you could enable further editing so an end user can create an opportunity without leaving the app.
 
You could also add the total dollar amount for the opportunities expected to close next to the calendar name in the upper left corner. Or add a custom class below Month View to display a list of upcoming Opportunity Close Dates. You could even embed a list of next steps to close the opportunity into the Event view or even turn them into their own calendar type.
 
Armed with this introduction to WideLens, take a new look at your business problems and you’ll begin to see many useful ways WideLens and Bungee Connect can help solve them.
 

Quick Tour of the Source Code

If you are new to WideLens or to building applications with Bungee Builder, you might help you get a sense of what is required to integrate a new calendar driver.  In this section we will walk through the My Calendars section, a portion of the source code of the WideLens reference application. We will start with the Main form of the application and drill down until we find the My Calendars form and the controls it uses to display the list of available Calendars.
 

Peeling Back the Layers of the My Calendars Form

 
Often times a form may contain another form which contains yet another form. Nested forms like these can be difficult to follow and understand. Eventually, though, you will get to a control on a form which is bound to a field which provides some data to display in the control. The Main form is no exception as it contains multiple nested forms and controls. The following paragraphs show you how to peel back the many layers of WideLens to identify how the My Calendars section nests itself within WideLens.
 

Layer 1 & 2: Main form and Navigation form

The control on the left side of the Main form (see Figure 5) is an embedded form named calendarList containing one of more controls and bound to a field named navigation. Double-click the calendarList embedded form to open the original form called Navigation. Since the navigation field bound to the embedded form is of type CalendarNav, you will find the Navigation form listed in the Solution Detail within the CalendarNav class found within the Navigation project. Forms are located within the class of data they represent.
 

Layer 3: FormList control with Collection(Section)

Within the Navigation form is another FormList control named FormList. By looking at the Path property in the Behavior section of its Property Editor, you can see that it is bound to the sections field within the CalendarNav class. The sections field is of type Collection(Section), which means it is a collection of objects of type Section. And so we should expect there to be multiple Sections within FormList. And in fact, when you run WideLens (see Figure 3), you will find a My Calendars widget as well as a Month View widget. Both of these Section classes get put into Collection(Section) at runtime and the FormList displays each of them with their appropriate form.
 

Layer 4: Section class

The developers of WideLens intended the Section class to be very generic. That way you could design your own section or view and add it into the left column without changing the rest of the application. In order to find the forms that populate the Section collection, we must look in the Section class within the Navigation project. The form that will display the collection of Section objects will be within the Section class.
 

Layer 5: Default form

The way to tell which form will be used to display each Section in the FormList on the Navigation form is to see which Form Adapter the FormList control is going to look for and compare that Form Adapter to the Adapter List property for each form in the Section class. Forms within the same class must have unique Form Adapters in their Adapter List so that there is no ambiguity as to which form to display at runtime. In this case, the Navigation form’s Element Form (Adapter tab of the Property Editor) property is set to Default. Not surprisingly, it is the form named Default whose Adapter List property is set to Default. So the Default form displays the My Calendars Section within the FormList.
 

Layer 6: DynamicForm1 control

To see how the My Calendar Section is put together, open the Default form by double-clicking it in the Solution Detail (the Section class must be selected). You will find that it contains two DynamicFrom controls: one called DynamicForm and another called DynamicForm1. DynamicForms let you embed one or more forms which can automatically swap in and out during runtime. So we should expect to see multiple forms within DynamicForm and DynamicForm1. Let’s take a look at DynamicForm1.
Figure 10. The Default form is bound to the Default FormAdapter

Layer 7: ConnectionAdapter

According to the Dynamic property on the Adapter tab in the Property Editor, DynamicForm1 is bound to ExpandDynamicFormAdapter, which is actually a ConnectionAdapter. They work differently than FormAdapters in that they contain Bungee Logic. If you are familiar with the concept of Model View Controller, a ConnectionAdapter is similar to a Controller in MVC.
 

Layer 8: ExpandDynamicFormAdapter

According to the Path property on the Behavior tab in the Property Editor, DynamicForm1 is bound to a class named ‘this’. ‘this’ is Bungee’s way of referring to the class at runtme (similar to the “this” pointer in C++), which in this case, is Section. So we should expect to find a ConnectionAdapter within the Section class named ExpandDynamicFormAdapter. And sure enough, there is. When the DynamicForm1 is deciding which form to display, it runs the Bungee Logic code within ExpandDynamicFormAdapter to decide.
 

Layer 9: Bungee Logic

Double-click ExpandDynamicFormAdapter to view its Bungee Logic code. (see Figure 11). Following the logic, you can see that when the expanded field value is true, its formAdapter is set to Content (which is connected to the Content form) and so the Content form is displayed. When the expanded field value is false, then DynamicForm1’s formAdapter is set to Empty and the Empty form is displayed. This is the behavior you see demonstrated when you click the double arrows image next to My Calendars in Figure 3.

 

Figure 11. Bungee Logic within ExpandDynamicFormAdapter

Layer 10: Empty form and Content form

Open up the Empty form. It is of no surprise to see that the Empty form contains nothing. So when it is displayed, nothing is displayed within DynamicForm1 and the My Calendar section collapses to its non-selected state. Open up the Content form. It contains a MultiColumnList control named items1.
 

Layer 11: MultiColumnList control

MultiColumnList controls display field values from the collection they are bound to. In this example, according to its Path property (Behavior tab within the Property Editor), items1 is bound to items. The items field is of type Collection(SectionItem), which means it is a collection of SectionItems.
 

Layer 12: Column Setting property

Click on the ellipse next to MultiColumnList’s Column Setting property and you see the Display Name column. Click on Display Name, then choose the Object Edit tab, you will see the Display Name column’s Object Read Only Form property is set to a Content FormAdapter.

Figure 12. MultiColumnList control’s Display Name column refers to the CalendarItem Content form

Layer 13: SectionItem class

The Bungee platform has the unique ability to not only override inherited functions, but also forms as well. So the Content FormAdapter on the Object Read Only Form property  will display the Content form of a subclass of SectionItem. In our case, CalendarItem inherits from the SectionItem class, and has its own Content form, displaying the icon and name of the calendar.
 

Layer 14: CalendarItem object

The sectionItems collection was populated with an instance of the CalendarItem class using Bungee Logic during the Main form’s startup process. You can investigate this startup process by opening the main function within the Main class and following it to the getCalendarItems function within the CalendarManager class . For now, we will skip a detailed explanation and just say that during this process, sectionItems was populated with a CalendarItem object, which inherits from SectionItem and has its own Content form. Thus, this new Content form displays its Calendar information within the My Calendars Section.

Figure 13. Content form within the CalendarItem class

Layer 15: Content form

Open the Content form from within the CalendarItem class. You will see that its Path property is bound to the field connection.config.calendarResource.displayName. This value (as well as the checkbox) is directly populated from a database query during the startup process referred to in Layer 14.
 
While complex and sometimes even obscure, the developers of this application wanted to demonstrate the power of inheritance. As you can see, many of the classes are inherited from other classes, which while increase in complexity, can reduce development time and application upkeep and reuse. They also wanted to demonstrate how Bungee Connect applications can be extended, as demonstrated by the Sections collection, to which you can add your own Section object. Bungee's powerful inheritance model allows not only to reuse but override visual elements for customization.

Additional Resources

 
    Copyright © 2005 - 2007 Bungee Labs. All rights reserved.