DotNetNuke Helper Functions


Module User Interfaces

Chapter 12 introduced you to module structure and how to manually create references to controls to define your module. Each module consists of a couple of user controls that enable the user to interface with your application logic. These controls provide a means to view and modify the data contained in the database supporting the module. DotNetNuke provides you with the ability to define these controls and interface them into your application using a module definition.

Table 15-1 lists the files that make up a module, their keys (see Chapter 12), and their function. This example continues with the Events module as in previous chapters.

Table 15-1: Module Definitions in Relation to the Events Module

Type

Filename (Events Module)

Key

Description

View

DesktopModules\Events\Events.ascx

 

The control your users will see on the first request to the module. You can define multiple view controls for your module. The main thing to keep in mind is that the purpose of the view is to display your data.

Edit

DesktopModules\Events\EditEvents.ascx

DesktopModules\Events\Settings.ascx

Edit Settings

Used to edit information contained in the database. A DesktopModule can consist of several edit controls based on the complexity of the module. Security for edit permissions is normally done at the module level contained within a specific page.

Admin

N/A

N/A

Not used in the Events module example, but this control will be displayed to administrators for a portal.

Anonymous

N/A

N/A

Provides an anonymous view of your data for your DesktopModule.

Host

N/A

N/A

For displaying a host-only control for your module.

As you can see from this table, several controls are available that you can make use of in your development. The defined types are specific to the user role within a portal. For module development, there may be data that you want to allow certain roles to access. For example, if the module manipulates the application settings or file system, you would want to restrict that functionality to the host who has control over the overall application instance. Your module may modify settings configured at a portal level, like the banner ad management system, in which case you could restrict the control to just administrators within a portal.

You can select many different configurations when doing module development. For now, the focus is to continue the Events module development covered in the previous two chapters.

The preceding table covered the controls specific to the Events module. The Events module consists of three primary user controls for displaying and manipulating data:

  • View (DesktopModules\Events\Events.ascx): Displays the events either in a listing format sorted by event date or in a calendar format.

  • Settings (DesktopModules\Events\Settings.ascx): Used to configure module-specific settings like the display.

  • Edit (DesktopModules\Events\EditEvents.ascx): Used to add and update information for each specific event

The next few sections describe each control, and display data from the collection that was defined in the Business Logic Layer covered in Chapter 14.

View Control

In the Events module, the View control is located in the DesktopModules\Events directory and is called Events.ascx. Open the Events project and look at the user interface to see the controls it contains. There are two primary controls: DataList and Calendar. These two controls provide the module with two different views on the events data based on what is configured via the Edit control (discussed later in the chapter). Listing 15-1 reviews the DataList control from the Events.ascx file.

Listing 15-1: DataList Control in the Events.ascx Page

image from book
 <asp:datalist  runat="server" EnableViewState="false" image from book summary="Events Design Table">     <itemtemplate>         <table summary="Events Design Table">             <tr>                 <td  runat="server" valign="top" align="center" image from book rowspan="3" width='<%# DataBinder.Eval(Container.DataItem,"MaxWidth") %>'>                     <asp:Image  AlternateText='<%# image from book DataBinder.Eval(Container.DataItem,"AltText") %>' runat="server" ImageUrl= image from book '<%# FormatImage(DataBinder.Eval(Container.DataItem,"IconFile")) %>' Visible= image from book '<%# FormatImage(DataBinder.Eval(Container.DataItem,"IconFile")) <> "" image from book %>'></asp:Image>                 </td>                 <td>                     <asp:HyperLink  NavigateUrl='<%# EditURL;image from book  ("ItemID",DataBinder.Eval(Container.DataItem,"ItemID")) %>' Visible="<%# image from book IsEditable %>" runat="server"><asp:Image  ImageUrl=image from book "~/images/edit.gif" Visible="<%# IsEditable %>" AlternateText="Edit"image from book runat="server" /></asp:HyperLink>                      <asp:Label  Runat="server" Cssclass=image from book "SubHead" text='<%# DataBinder.Eval(Container.DataItem,"Title") %>'></asp:Label>                 </td>             </tr>             <tr>                 <td>                     <asp:Label  Runat="server" Cssclass=image from book "SubHead" text='<%# FormatDateTime(DataBinder.Eval(Container.DataItem,image from book "DateTime")) %>'></asp:Label>                 </td>             </tr>             <tr>                 <td>                     <asp:Label  Runat="server" CssClass=image from book "Normal" text='<%# DataBinder.Eval(Container.DataItem," Description") %>'>image from book </asp:Label>                 </td>             </tr>         </table>     </ItemTemplate> </asp:datalist> 
image from book

You are going to bind the DataList to values from your database that are returned from a stored procedure and then up to the provider covered in Chapter 13. The field names are MaxWidth, AltText, IconFile, ItemID, Title, DateTime, and Description.

The Calendar control contained in the page provides an alternative view for the module (see Listing 15-2).

Listing 15-2: Calendar Control within the Events.ascx Provides Another View

image from book
 <asp:calendar  runat="server" BorderWidth="1" Css image from book SelectionMode="None" summary="Events Calendar Design Table">     <dayheaderstyle backcolor="#EEEEEE" css borderwidth="1">image from book </DayHeaderStyle>     <daystyle css borderwidth="1" verticalalign="Top"></DayStyle>     <othermonthdaystyle forecolor="#FFFFFF"></OtherMonthDayStyle>     <titlestyle font-bold="True"></TitleStyle>     <nextprevstyle css></NextPrevStyle> </asp:calendar> 
image from book

View Control Code-Behind Class

Now that you have some controls on the form, you need to bind some data to them for display. Recall from Chapter 13 that you can take data from an abstraction class, which DotNetNuke can then convert to a collection of objects via the Custom Business Object (CBO) helper class (see Chapter 7). Now you need to take the ArrayList of objects and bind them to your controls in the Events.ascx.vb code-behind file, located in the Events project.

At the top of your class, you first need to do your name imports, declare your namespace, and define your class:

 Imports DotNetNuke Imports System.Web.UI.WebControls Namespace DotNetNuke.Modules.Events Public MustInherit Class Events             Inherits Entities.Modules.PortalModuleBase 

PortalModuleBase Class

You inherit from the Entities.Modules.PortalModuleBase class. The PortalModuleBase class file is located n the main DotNetNuke project in the <webroot>\Components\Modules\PortalModuleBase.vb file. In ddition to inheriting from the UserControl class of ASP.NET, this class is central to your module development efforts. It provides several important methods and properties for your module (see Table 15-2).

Table 15-2: Some PortalModuleBase Class Exposed Methods and Properties

Property

Type

Description

IsEditable

Boolean

Can be used as a reference to check and see if the current user has permissions to edit the module. This is defined in the properties for the DesktopModule in DotNetNuke. For example:

      If IsEditable Then            txtEditField.Visible = True      End If 

LocalResourceFile

String

Contains the path value of the resource file that is being used for the module. This enables you to support localization for your modules. This is covered in more detail in Chapter 8.

HelpFile

String

Contains a value to a local path for a text file containing help information.

HelpURL

String

Contains a value for a URL for an external help file for the specific module.

ModuleConfiguration

ModuleInfo

Provides information about a specific module.

PortalId

Integer

ID of the current portal that the request is for. This is an integer value that is generated by DotNetNuke when a host creates a new portal.

TabId

Integer

ID of the current page that the request is going to. This is generated by DotNetNuke when an admin creates a new page within the portal.

TabModuleId

Integer

Contains a value of module within a tab. Multiple tab modules can point to the same Module ID, allowing two instances of a module to point to the same date.

ModuleId

Integer

Returns the current ID of a specific module instance. This is an integer value that is generated by DotNetNuke when you add a new instance of a module into a page.

UserInfo

UserInfo

Contains information for the portal users.

UserId

Integer

Returns the ID of the current logged-on user.

PortalAlias

PortalAliasInfo

Contains various information pertaining to the current portal.

PortalSettings

PortalSettings

Contains setting information specific to a portal, such as the admin e-mail.

Settings

HashTable

The Settings hash table is very important to module development, and is probably one of the most common tools you'll use. Consider it analogous to the registry in Windows. You can use the Settings hash to store and retrieve a key/value pair specific to your module instance. For example, to retrieve a value from the Settings hash:

   Dim myVar As String = Settings("mykey").ToString 

To set a value:

   Dim objModules As New    Entities.Modules.ModuleController objModules.UpdateTabModuleSetting (TabModuleId, "mykey", myVar) 

ContainerControl

Control

Provides a container to wrap a module (see Chapter 6 to learn about what a container is).

HasModulePermission

Boolean

Checks permissions for a specific module instance, such as edit and view.

DotNetNuke Optional Interfaces

Right below your class declaration, you have the option to implement several interfaces:

 Implements Entities.Modules.IActionable Implements Entities.Modules.IPortable Implements Entities.Modules.ISearchable 

These interfaces provide you with the ability to tie into the Menu control for your module. As covered previously in this book, each module contains a menu with a list of action items. To add items to the menus you need to implement the IActionable interface. This is also true with the IPortable interface, which provides an export and import function for the module, and the ISearchable interface, which enables your module to take advantage of the integrated search engine within DotNetNuke. (See Chapter 8 and Chapter 14 for more information on these interfaces and how to use them in your modules.)

These interfaces are optional. At the bottom of the Events.ascx.vb class file, there is a code region with the name "Optional Interfaces." Within this region is the code showing you how to implement these interfaces (see Listing 15-3).

Listing 15-3: Optional Interfaces Region of the Events Module

image from book
 #Region "Optional Interfaces"         Public ReadOnly Property ModuleActions() As _                   Entities.Modules.Actions.ModuleActionCollection Implements _                   Entities.Modules.IActionable.ModuleActions             Get                 Dim Actions As New _                    Entities.Modules.Actions.ModuleActionCollection                 Actions.Add(GetNextActionID, _     Localization.GetString(Entities.Modules.Actions.ModuleActionType.AddContent, _     LocalResourceFile), Entities.Modules.Actions.ModuleActionType.AddContent, _     "", "", EditUrl(), False, Security.SecurityAccessLevel.Edit, True, False)                 Return Actions             End Get         End Property         Public Function ExportModule(ByVal ModuleID As Integer) As String _             Implements Entities.Modules.IPortable.ExportModule             ' included as a stub only so that the core knows this             ' module Implements Entities.Modules.IPortable         End Function         Public Sub ImportModule(ByVal ModuleID As Integer, _             ByVal Content As String, ByVal Version As String, ByVal UserId As _             Integer) Implements Entities.Modules.IPortable.ImportModule             ' included as a stub only so that the core knows             ' this module Implements Entities.Modules.IPortable         End Sub         Public Function GetSearchItems(ByVal ModInfo As _             Entities.Modules.ModuleInfo) As _             Services.Search.SearchItemInfoCollection Implements _             Entities.Modules.ISearchable.GetSearchItems             ' included as a stub only so that the core knows this             ' module Implements Entities.Modules.ISearchable         End Function #End Region 
image from book

As you can see in Listing 15-3, the first method is ModuleActions. Here you implement the IActionable interface to add items into the menu for the module. You have a collection of menu items, with an accompanying action. In this example, you add a menu item using the Actions.Add method. You can see that instead of passing an absolute value for the menu listing, you're using a localized string using the Localization.GetString method. By using the localization interface provided by DotNetNuke (see Chapter 8), you can have menu items displayed in the language of the current user's profile. Because this action is going to be for editing the module, you will pass EditURL as the action property for this item. This will load your Edit control when the user selects this option from the menu. In addition to localization and the control to load properties, there are security parameters to pass as well. By specifying the security type for the item display, you can restrict the functionality to specific roles configured within your portal. In this example, you check for users with edit permissions for the module by passing the value Security.SecurityAccessLevel.Edit.

Below the menu action item method in Listing 15-3 are the methods covered in Chapter 14 for implementing search and import/export functionality for the module. Recall that these methods make a call to the GetEvents method within the Business Logic Layer (BLL) class. You then iterate through all the events for this module instance and either load them into the search or generate an XML feed for export. Now, you need to implement a stub for these methods for the core to know that the module implements the interfaces. DotNetNuke will then execute the corresponding methods contained in your BLL class.

Code-Behind Regions

You need to break your class into several regions. DotNetNuke makes use of named regions throughout the code to provide some organization to the code, and for better readability. Here's a breakdown of the code regions for this specific module. The first of these regions are the Controls and Private Members regions. As in any ASP.NET development, you need to declare your web controls to expose the actions, properties, and methods that they contain. In addition, for this specific example there are some private members — an array of events defined and an integer value for the current month (see Listing 15-4)

Listing 15-4: Controls and Private Members Regions of the Events Module

image from book
 #Region "Controls"             Protected WithEvents lstEvents As System.Web.UI.WebControls.DataList             Protected WithEvents calEvents As System.Web.UI.WebControls.Calendar #End Region #Region "Private Members"             Dim arrEvents(31) As String             Dim intMonth As Integer #End Region 
image from book

Following these two regions, you begin to get into some code that is going to do something. This code is contained in the Private Methods region. Normally, your private methods are going to contain methods that will obtain your data and bind to your controls. In this example, there is one method called the GetCalendarEvents subroutine, which accepts a start date and an end date for obtaining information from your database (see Listing 15-5). Chapter 13 covered the various stored procedures for this module, and this method is what calls that process of obtaining a collection from the Business Logic Layer by calling the GetEvents method. With abstraction, the BLL then calls the abstraction layer, which contains a method that is overridden by the physical provider class that calls the SQL stored procedure GetEvents. The stored procedure then returns the fields matching the query to the physical provider, which finally is converted by DotNetNuke's Custom Business Object helper class to a collection of objects you define in the BLL. This collection, or ArrayList, is then bound to the controls that were placed on the page, in this case either a Calendar or DataList control.

Listing 15-5: GetCalendarEvents Method of the Events Module

image from book
 #Region "Private Methods"    Private Sub GetCalendarEvents(ByVal StartDate As String, ByVal _       EndDate As String)       Try          Dim objEvents As New EventController             Dim strDayText As String             Dim datTargetDate As Date             Dim datDate As Date             Dim blnDisplay As Boolean             Array.Clear(arrEvents, 0, 32)             Dim Arr As ArrayList = objEvents.GetEvents(ModuleId, _                Convert.ToDateTime(StartDate), _                      Convert.ToDateTime(EndDate))             Dim i As Integer             For i = 0 To Arr.Count - 1                Dim objEvent As EventInfo = CType(Arr(i), EventInfo)                'While dr.Read()                If objEvent.Period.ToString = "" Then                   strDayText = "<br>"                If Not objEvent.IconFile = "" Then                   strDayText += "<img alt=""" & objEvent.AltText & """ _                      src="/books/3/435/1/html/2/"" & FormatImage(objEvent.IconFile) & """ _                      border=""0""><br>"                End If                If IsEditable Then                   strDayText += "<a href=""" & _                      CType(Common.Globals.ApplicationPath, String) & _                      "/" & glbDefaultPage & "?tabbackground-color:d9d9d9">                     "&m&ctl=Edit" & "&Itembackground-color:d9d9d9">                     objEvent.ItemId & "&VisibleDate=" & _                      calEvents.VisibleDate.ToShortDateString & _                      """><img alt=""Edit"" src="/books/3/435/1/html/2/"" & _                      CType(Common.Globals.ApplicationPath, String) & _                      "/images/edit.gif"" border=""0""></a>&nbsp;"               End If               strDayText += "<span class=""ItemTitle"">" & _                  objEvent.Title & "</span>"               If objEvent.DateTime.ToString("HH:mm") <> "00:00" Then                  strDayText += "<br><span class=""Normal"">" & _                     objEvent.DateTime.ToShortTimeString & "</span>"               End If               strDayText += "<br><span class=""Normal"">" & _                  Server.HtmlDecode(objEvent.Description) & "</span>"               arrEvents(CDate(objEvent.DateTime).Day) += strDayText            Else                                   ' recurring event                     datTargetDate = CType(objEvent.DateTime, Date)                  datDate = Date.Parse(StartDate) While datDate <= Date.Parse(EndDate)     blnDisplay = False     Select Case objEvent.Period Case CType("D", Char)                              ' day    If DateDiff(DateInterval.Day, datTargetDate.Date, _              datDate) Mod objEvent.Every = 0 Then blnDisplay = True             End If Case CType("W", Char)                              ' week    If DateAdd(DateInterval.WeekOfYear, _              DateDiff(DateInterval.WeekOfYear, _              datTargetDate.Date, datDate), _              datTargetDate.Date) = datDate Then If DateDiff(DateInterval.WeekOfYear, _            datTargetDate.Date, datDate) Mod _            objEvent.Every = 0 Then                                     blnDisplay = True                               End If                             End If                         Case CType("M", Char)      ' month If DateAdd(DateInterval.Month, _        DateDiff(DateInterval.Month, datTargetDate.Date, _        datDate), datTargetDate.Date) = datDate Then If DateDiff(DateInterval.Month, _          datTargetDate.Date, datDate) Mod _          objEvent.Every = 0 Then blnDisplay = True                          End If                      End If                 Case CType("Y", Char)              ' year                     If DateAdd(DateInterval.Year, _                       DateDiff(DateInterval.Year, datTargetDate.Date, _                       datDate), datTargetDate.Date) = datDate Then                       If DateDiff(DateInterval.Year, datTargetDate.Date, _                         datDate) Mod objEvent.Every = 0 Then                           blnDisplay = True                       End If                     End If                 End Select                 If blnDisplay Then                   If datDate < datTargetDate.Date Then                     blnDisplay = False                   End If                 End If                 If blnDisplay Then                   If Not _                     Common.Utilities.Null.IsNull(objEvent.ExpireDate) Then                       If datDate > CType(objEvent.ExpireDate, Date) Then                         blnDisplay = False                       End If                   End If                 End If                 If blnDisplay Then                   strDayText = "<br>"                   If Not objEvent.IconFile = "" Then                      strDayText += "<img alt=""" & objEvent.AltText & """ _                         src="/books/3/435/1/html/2/"" & FormatImage(objEvent.IconFile) & """ _                         border=""0""><br>"                   End If                   'check to see if the current user has edit permissions                   If IsEditable Then                     strDayText += "<a href=""" & _                       CType(Common.Globals.ApplicationPath, String) & _                       "/" & glbDefaultPage & "?tabbackground-color:d9d9d9">                      "&m&ctl=Edit" & "&Itembackground-color:d9d9d9">                      objEvent.ItemId & "&VisibleDate=" & _                       calEvents.VisibleDate.ToShortDateString & _                       """><img alt=""Edit"" src="/books/3/435/1/html/2/"" & _                       CType(Common.Globals.ApplicationPath, String) & _                       "/images/edit.gif"" border=""0""></a>&nbsp;"                 End If                 strDayText += "<span class=""ItemTitle"">" & _                     objEvent.Title & "</span>"                 If objEvent.DateTime.ToString("HH:mm") <> "00:00" Then                      strDayText += "<br><span class=""Normal"">" & _                         objEvent.DateTime.ToShortTimeString & "</span>"                   End If                   strDayText += "<br><span class=""Normal"">" & _                     Server.HtmlDecode(objEvent.Description) & "</span>"                   arrEvents(datDate.Day) += strDayText                     End If                 datDate = DateAdd(DateInterval.Day, 1, datDate)               End While             End If           Next        intMonth = CDate(StartDate).Month        calEvents.DataBind()       Catch exc As Exception                       'Module failed to load       ProcessModuleLoadException(Me, exc)       End Try     End Sub #End Region 
image from book

The majority of the code in Listing 15-5 is specific to what you're doing for displaying the data. In a simple module, you'd bind the result set to a control, like so:

 Dim objEvents As New EventsController myDatalist.DataSource = objEvents.GetEvents(ModuleId, _                          Convert.ToDateTime(StartDate), _                          Convert.ToDateTime(EndDate)) myDataList.DataBind 

However, because you have some criteria on how you want to display events, you load the result set into an ArrayList, which you then iterate through and format the data for display.

Other items to note in Listing 15-5 include the use of the IsEditable Boolean value to check to see if the user has permissions to edit content for the module. If the value is true, you display an edit icon to enable the user to edit events that are displayed.

Finally, in the exception catching, there's a call to ProcessModuleLoadException. The DotNetNuke framework provides this method for error trapping, which is discussed later in this chapter.

The next region in this example is the Public Methods region, where you expose any methods that you want to make available outside of this class. Here you're dealing primarily with formatting methods and calculating the day of the month (see Listing 15-6). Note that these methods should be declared public because your acsx class needs to access them at runtime.

Listing 15-6: Public Methods Contained in the Events Module

image from book
 #Region "Public Methods"     Public Function FormatDateTime(ByVal DateTime As Date) As String Try     FormatDateTime = DateTime.ToLongDateString     If DatePart(DateInterval.Hour, DateTime) <> 0 Or _          DatePart(DateInterval.Minute, DateTime) <> 0 Or _          DatePart(DateInterval.Second, DateTime) <> 0 Then FormatDateTime = FormatDateTime & " at " & _       DateTime.ToShortTimeString                 End If             Catch exc As Exception                 'Module failed to load                   ProcessModuleLoadException(Me, exc)             End Try          End Function          Public Function FormatImage(ByVal IconFile As String) As String             Try                     If Not IconFile = "" Then                   FormatImage = PortalSettings.HomeDirectory & IconFile.ToString                 End If             Catch exc As Exception                 'Module failed to load                ProcessModuleLoadException(Me, exc)             End Try          End Function     Public Function GetFirstDayofMonth(ByVal datDate As Date) As String             Try                     Dim datFirstDayofMonth As Date = DateSerial(datDate.Year, _                datDate.Month, 1)                 Return GetMediumDate(datFirstDayofMonth.ToString)             Catch exc As Exception                 'Module failed to load                 ProcessModuleLoadException(Me, exc)             End Try          End Function          Public Function GetLastDayofMonth(ByVal datDate As Date) As String             Try                  Dim intDaysInMonth As Integer = Date.DaysInMonth(datDate.Year, _                datDate.Month)                 Dim datLastDayofMonth As Date = DateSerial(datDate.Year, _                datDate.Month, intDaysInMonth)                 Return GetMediumDate(datLastDayofMonth.ToString)             Catch exc As Exception                 'Module failed to load                 ProcessModuleLoadException(Me, exc)             End Try          End Function #End Region 
image from book

The next region in the code is the Event Handlers section. As you know from ASP.NET programming, event handlers are methods that respond to a certain action, be it an action performed by a user, such as a click event, or a system action such as the page loading. The page load event in your module is usually where you determine the initial state of your user control. For example, you may check to see if the request is a postback, which means the user clicked a link button or form button to call the module again. Listing 15-7 looks at the code in the Event Handlers section to see how the page load is handled in this module.

Listing 15-7: Event Handlers Region in the Events Module

image from book
 #Region "Event Handlers"         Private Sub Page_Load(ByVal sender As System.Object, ByVal e As _          System.EventArgs) Handles MyBase.Load             Try                 Dim EventView As String = CType(Settings("eventview"), _                  String)                 If EventView Is Nothing Then                   EventView = "C"                  ' calendar                 End If                 Dim objEvents As New EventController             Select Case EventView                 Case "L"                           ' list                     lstEvents.Visible = True                     calEvents.Visible = False                     lstEvents.DataSource = objEvents.GetEvents(ModuleId, _                      Convert.ToDateTime(Common.Utilities.Null.NullDate), _                      Convert.ToDateTime(Common.Utilities.Null.NullDate))                     lstEvents.DataBind()                 Case "C"                           ' calendar                     lstEvents.Visible = False                     calEvents.Visible = True                 If Not Page.IsPostBack Then                         If Not Request.QueryString("VisibleDate") _                         Is Nothing Then                           calEvents.VisibleDate = _                           CType(Request.QueryString("VisibleDate"), _                           Date)                       Else                          calEvents.VisibleDate = Now                       End If                     If CType(Settings("eventcalendarcellwidth"), _                       String) <> "" Then    calEvents.Width = _  System.Web.UI.WebControls.Unit.Parse(CType(Settings("eventcalendarcellwidth"), _                       String) & "px")                    End If                     If CType(Settings("eventcalendarcellheight"), _                       String) <> "" Then                       calEvents.Height = _   System.Web.UI.WebControls.Unit.Parse(CType(Settings("eventcalendarcellheight"), _                       String) & "px")                     End If                 Else                     If calEvents.VisibleDate = #12:00:00 AM# Then                       calEvents.VisibleDate = Now                     End If                   End If                 Dim StartDate As String = _                 GetFirstDayofMonth(calEvents.VisibleDate) & " 00:00"                 Dim EndDate As String = _                 GetLastDayofMonth(calEvents.VisibleDate) & " 23:59"                 GetCalendarEvents(StartDate, EndDate)               End Select             Catch exc As Exception                 'Module failed to load               ProcessModuleLoadException(Me, exc)             End Try         End Sub         Private Sub calEvents_DayRender(ByVal sender As Object, ByVal e As _             System.Web.UI.WebControls.DayRenderEventArgs) Handles _             calEvents.DayRender             Try               If e.Day.Date.Month = intMonth Then                  Dim ctlLabel As Label = New Label                  ctlLabel.Text = arrEvents(e.Day.Date.Day)                  e.Cell.Controls.Add(ctlLabel)               End If             Catch exc As Exception                 'Module failed to load               ProcessModuleLoadException(Me, exc)             End Try         End Sub         Private Sub calEvents_VisibleMonthChanged(ByVal sender As Object, _           ByVal e As System.Web.UI.WebControls.MonthChangedEventArgs) Handles _           calEvents.VisibleMonthChanged             Try               Dim StartDate As String = GetFirstDayofMonth(e.NewDate.Date) & _               " 00:00"               Dim EndDate As String = GetLastDayofMonth(e.NewDate.Date) & _               "23:59"               GetCalendarEvents(StartDate, EndDate)          Catch exc As Exception                    'Module failed to load               ProcessModuleLoadException(Me, exc)             End Try         End Sub #End Region 
image from book

In the Page_Load event, one of the first things you do is check the value contained within the Settings hash. Remember from Table 15-2 that the Settings hash is similar to the Windows registry where you can store key/value pairs. For example, you first check to see the view:

 Dim EventView As String = CType(Settings("eventview"), String) 

This is the purpose of the Settings hash — it enables you to have unique values for each module's instance. It provides maximum code reuse to similar functions. In the Events module example, you can specify different displays for events for each instance. That could be applied to any module to provide maximum flexibility for your application. You can see that throughout this method there are various keys checked for this module to obtain values.

Continuing through Listing 15-7, you can see that some of the private methods covered earlier in this chapter are called for displaying of date information. In addition, you also make a call to the EventsController to bind to your DataList. This is based on the value contained within your Settings ("eventview") key. If you're in list view (L), you will bind to the controller and call the GetEvents method. Remember, you bring the data from the various layers starting with the physical database provider to the BLL:

 Dim objEvents As New EventController :: :: lstEvents.DataSource = objEvents.GetEvents(ModuleId, _                         Convert.ToDateTime(Common.Utilities.Null.NullDate), _                         Convert.ToDateTime(Common.Utilities.Null.NullDate)) lstEvents.DataBind() 

The call to Common.Utilities.Null.NullDate provides you with a null object of the date type to pass to your method to return all events rather than just events within a specified range, as you did previously in this chapter.

This section explored the basic structure of a View control for a DesktopModule, but there are more items to deal with to complete the module. For instance, several times in the View control's code-behind class, you made calls to values contained within a Settings hash. These values are going to be configured within the Edit control, which is used for configuring the settings for this specific module instance. The Settings.ascx control was defined in the module definition in DotNetNuke for the Events module (see Chapter 12).

Settings Control

Now you need to create a control that enables you to customize your module. In the Events module, this will set the values contained in the Settings hash table. The keys you create are primarily for defining the display of the module. You set options for defining whether to display events in a list format or a calendar format.

Listing 15-8 reviews the user control for this module. This file is located in the Events project folder called Settings.ascx.

Listing 15-8: Settings User Control for the Events Module

image from book
 <%@ Control language="vb" CodeBehind="Settings.ascx.vb" AutoEventWireup= image from book "false" Explicit="True" Inherits="DotNetNuke.Modules.Events.Settings" %> <%@ Register TagPrefix="dnn" TagName="Label" src="/books/3/435/1/html/2/~/controls/LabelControl.ascx" %> <table cellspacing="0" cellpadding="2" summary="Edit Events Design Table" image from book border="0">   <tr>     <td  width="175"><dnn:label  runat="server" image from book controlname="optView" suffix=":"></dnn:label></td>     <td valign="bottom" width="125">       <asp:radiobuttonlist  runat="server" repeatdirection= image from book "Horizontal" css>         <asp:listitem resourcekey="List" value="L">List</asp:listitem>         <asp:listitem resourcekey="cmdCalendar" value="C">Calendar</asp:listitem>       </asp:radiobuttonlist>     </td>   </tr>   <tr valign="top">     <td  width="175"><dnn:label  runat="server" image from book controlname="txtWidth" suffix=":"></dnn:label></td>     <td valign="bottom" width="125"><asp:textbox  runat= image from book "server" css columns="5"></asp:textbox></td>   </tr>   <tr valign="top">     <td  width="175"><dnn:label  runat="server" image from book controlname="txtHeight" suffix=":"></dnn:label></td>     <td valign="bottom" width="125"><asp:textbox  runat= image from book "server" css columns="5"></asp:textbox></td>   </tr> </table> 
image from book

You can see the various controls used here to display data — most are standard ASP.NET controls. One exception to this is the use of the DNN Label control. By using DotNetNuke intrinsic controls, you can take advantage of localization within your modules.

In addition to the DNN Label control, you can see how to specify the Settings hash table values for the view type. If you review Listing 15-7, you can see you checked the value of the Settings ("eventview") to determine in the View control how the events would be displayed. In the Settings.ascx control, you can see the optView form field, which has options for how to display the events in the module. You read these values in your code-behind page for the Settings.ascx control and then pass the values to the Settings hash, which you then use to check the view for the module.

Settings Control Code-Behind Class

If you look through the code-behind, you'll notice this file is much smaller than the code-behind for the View control because you're primarily concerned with specifying how you want the module to look. Listing 15-9 shows the class imports and the class definition in the Settings.ascx.vb file.

Listing 15-9: Defining the Settings Control for the Events Module

image from book
 Imports DotNetNuke Namespace DotNetNuke.Modules.Events       Public MustInherit Class Settings             Inherits Entities.Modules.ModuleSettingsBase 
image from book

You can see here that you inherit the Entities.Modules.ModuleSettingsBase class. This class is provided by DotNetNuke and inherits PortalModuleBase as discussed earlier in the chapter, but it extends the PortalModuleBase to include some additional properties. The ModuleSettingsBase class provides methods and properties specific to configuring values for the module instance. Table 15-3 reviews what this class provides for your module development.

Table 15-3: ModuleSettingsBase Class

Name

Type

Description

ModuleId

Integer

ID of a specific single module instance.

TabModuleId

Integer

ID of the module container within a tab. For example, two module instances in two different tabs could point to the same Module ID, enabling them to mirror data.

ModuleSettings

Hashtable

Configuration options that affect all instances of a module.

TabModuleSettings

Hashtable

Affects only a specific instance of a module. This enables you to display the same information for a module, but in a different way.

One item to clarify here is the difference between the two module IDs (ModuleID and TabModuleID) and the two hash tables (ModuleSettings and TabModuleSettings). This is provided so you can use the same data in two different module instances. So, for example, if you want to update the event view for all instances of the same type of module, you would do so as follows:

 Dim objModules As New Entities.Modules.ModuleController              objModules.UpdateModuleSetting(ModuleId, "eventview", _                optView.SelectedItem.Value) 

In the next section, you update the specific instance using the UpdateTabModuleSettings method. This updates the view of all module containers pointing to the same data for a specific module, which is identified by its Module ID.

Code-Behind Regions

Next in the Settings class, the various code sections are broken down into code regions.

Note 

You'll notice that throughout DotNetNuke, certain standards are applied for coding conventions. As a module developer, you should strive to emulate the DotNetNuke coding style for easier readability and management.

The first and only section in the Settings.ascx.vb file is the Base Method Implementations region (see Listing 15-10). Here you have two methods: LoadSettings to load settings from your hash table, and UpdateSettings to update the settings values in the hash table.

Listing 15-10: Base Method Implementations of Events Module's Settings.ascx.vb

image from book
 #Region "Base Method Implementations"     Public Overrides Sub LoadSettings() Try     If (Page.IsPostBack = False) Then                    If CType(TabModuleSettings("eventview"), String) <> "" image from book Then optView.Items.FindByValue(CType(TabModuleSettings("eventview"), _                   String)).Selected = True                   Else                     optView.SelectedIndex = 1      ' calendar                   End If                   txtWidth.Text = _                    CType(TabModuleSettings("eventcalendarcellwidth"), String)                   txtHeight.Text = _                    CType(TabModuleSettings("eventcalendarcellheight"), String)                 End If             Catch exc As Exception                 'Module failed to load                 ProcessModuleLoadException(Me, exc)             End Try           End Sub           Public Overrides Sub UpdateSettings()             Try                 Dim objModules As New Entities.Modules.ModuleController              objModules.UpdateTabModuleSetting(TabModuleId, "eventview", _                optView.SelectedItem.Value)                 objModules.UpdateTabModuleSetting(TabModuleId, _                "eventcalendarcellwidth", txtWidth.Text)                 objModules.UpdateTabModuleSetting(TabModuleId, _                "eventcalendarcellheight", txtHeight.Text)             Catch exc As Exception                 'Module failed to load             ProcessModuleLoadException(Me, exc)             End Try           End Sub #End Region 
image from book

That's all it takes to configure the settings for your module. The next section covers the second Edit control for editing events for the module.

Edit Control

Because you're displaying events in your module, you need a way to add and update events in the database to display them. As in the View control, you're going to make a call to your BLL to pass an update or insert SQL command to your physical provider.

Open the EditEvents.ascx control contained in the Events module project to look at the user interface for adding your events data (see Listing 15-11).

Listing 15-11: Registering Controls for the EditEvents.ascx Control

image from book
 <%@ Register TagPrefix="dnn" TagName="Label" src="/books/3/435/1/html/2/~/controls/LabelControl.ascx" %> <%@ Register TagPrefix="Portal" TagName="URL" src="/books/3/435/1/html/2/~/controls/URLControl.ascx" %> <%@ Register TagPrefix="Portal" TagName="Audit" Src=image from book "~/controls/ModuleAuditControl.ascx" %> <%@ Register TagPrefix="dnn" TagName="TextEditor" Src=image from book "~/controls/TextEditor.ascx"%> <%@ Control language="vb" CodeBehind="EditEvents.ascx.vb" AutoEventWireup=image from book "false" Explicit="True" Inherits="DotNetNuke.Modules.Events.EditEvents" %> 
image from book

You're registering several DotNetNuke intrinsic controls. You did this with the Label control in your Settings class, but you're implementing several more in this file. Table 15-4 lists the controls provided by DotNetNuke and explains their purpose.

Table 15-4: DotNetNuke Controls

Control

Location

Description

Label

<approot>\controls\LabelControl.ascx

Provided by the DotNetNuke framework, supports features provided by DNN such as multiple languages based on user profile.

URL

<approot>\controls\URLControl.ascx

Additional support for multi-language support of DotNetNuke based on profile.Portal structure, security, and other DNN intrinsic information.

Audit

<approot>\controls\ModuleAuditControl.ascx

Provides information on who created the information and the creation date.

Text Editor

<approot>\controls\TextEditor.ascx

Provides both a text-based and WYSIWYG environment for editing text and HTML for your module.

Address

<approot>\controls\Address.ascx

Provides an address entry form used in the user registration within DotNetNuke.

Dual List

<approot>\controls\DualListControl.ascx

Provides two lists for passing values from one list to the other. An example of this control is implemented in the security settings for a module or page.

Help

<approot>\controls\Help.ascx

Provides inline help for your controls. Supports localization.

Section Head

<approot>\controls\SectionHeadControl.ascx

Provides expandable areas for sections of your module. This is implemented throughout DotNetNuke.

Skin

<approot>\controls\SkinControl.ascx

A drop-down list of skins installed for a portal. Primarily used in framework applications like under the Admin and Host menus.

Skin Thumbnail

<approot>\controls\SkinThumbnailControl.ascx

Generates a thumbnail image of the skin. You can view the functionality in the DotNetNuke skins section under the Admin menu.

URL Tracking

<approot>\controls\URLTrackingControl.ascx

Supports localization and click tracking.

As you can see from this table, DotNetNuke provides several controls, all of which you can use in your own development. Because DotNetNuke is open source, you can easily open any of the pages of code to find an implementation of these controls. This example covers controls specific to this module.

Now that the control has been registered in the page and your code-behind declared, you can continue on with the rest of the control and remove some of the formatting parameters for readability (see Listing 15-12).

Listing 15-12: EditEvents.ascx Control

image from book
 <asp:panel  runat="server">       <TABLE width="600" summary="Edit Events Design Table">      <TR vAlign="top">             <TD>                 <dnn:label  runat="server" controlname="txtTitle"              suffix=":"></dnn:label></TD>             <TD width="450">                 <asp:textbox  runat="server></asp:textbox> <asp:requiredfieldvalidator  runat="server" resourcekey=image from book "valTitle.ErrorMessage" controltovalidate="txtTitle" errormessage="Title Is image from book Required" display="Dynamic"></asp:requiredfieldvalidator></TD>           </TR>           <TR vAlign="top">             <TD>                 <dnn:label  runat="server"              controlname="txtDescription" suffix=":"></dnn:label></TD>             <TD width="450">                 <dnn:texteditor  runat="server"></dnn:texteditor>                 <asp:requiredfieldvalidator  runat="server"              resourcekey="valDescription.ErrorMessage"              controltovalidate="teDescription" errormessage="Description Is              Required" display="Dynamic"></asp:requiredfieldvalidator></TD>          </TR>          <TR vAlign="top">            <TD>                <dnn:label  runat="server" controlname="cboImage"              suffix=":"></dnn:label></TD>            <TD width="450">                <portal:url  runat="server" showtabs="False"              showurls="False" urltype="F" showtrack="False" showlog="False"              required="False"></portal:url></TD>          </TR>          <TR>            <TD>                <dnn:label  runat="server" controlname="txtAlt"              suffix=":"></dnn:label></TD>            <TD width="450">                <asp:textbox  runat="server"></asp:textbox>                <asp:requiredfieldvalidator  runat="server"              resourcekey="valAltText.ErrorMessage" controltovalidate="txtAlt"              errormessage="<br>Alternate Text Is Required"              display="Dynamic"></asp:requiredfieldvalidator></TD>          </TR>          <TR>            <TD>                <dnn:label  runat="server" controlname="txtEvery"              suffix=":"></dnn:label></TD>            <TD width="450">                <asp:textbox  runat="server"></asp:textbox>&nbsp;                <LABEL style="DISPLAY: none"              for="<%=cboPeriod.ClientID%>">Period</LABEL>                <asp:dropdownlist  runat="server">                  <asp:listitem value=""></asp:listitem>                  <asp:listitem resourcekey="Days" value="D">Day(s) image from book </asp:listitem>                  <asp:listitem resourcekey="Weeks" value="W">Week(s) image from book </asp:listitem>                  <asp:listitem resourcekey="Months"                 value="M">Month(s)</asp:listitem>                  <asp:listitem resourcekey="Years" value="Y">Year(s) image from book </asp:listitem>               </asp:dropdownlist></TD>           </TR>           <TR>             <TD  width="125">                 <dnn:label  runat="server"               controlname="txtStartDate" suffix=":"></dnn:label></TD>             <TD width="450">                 <asp:textbox  runat="server"               columns="20"></asp:textbox>&nbsp;                 <asp:hyperlink  runat="server"               resourcekey="Calendar">Calendar</asp:hyperlink>                 <asp:requiredfieldvalidator  runat="server"               resourcekey="valStartDate.ErrorMessage"                  controltovalidate="txtStartDate" errormessage="<br>Start Date Is               Required" display="Dynamic"></asp:requiredfieldvalidator>                 <asp:comparevalidator  runat="server"               resourcekey="valStartDate2.ErrorMessage"                  controltovalidate="txtStartDate" errormessage="<br>Invalid start               date!" display="Dynamic" type="Date"                  operator="DataTypeCheck"></asp:comparevalidator></TD>           </TR>           <TR>             <TD  width="125">                 <dnn:label  runat="server" controlname="txtTime"                  suffix=":"></dnn:label></TD>             <TD width="450">                 <asp:textbox  runat="server"></asp:textbox></TD>           </TR>           <TR>             <TD  width="125">                 <dnn:label  runat="server" controlname=image from book "txtExpiryDate"               suffix=":"></dnn:label></TD>             <TD width="450">                 <asp:textbox  runat="server"></asp:textbox>&nbsp;                 <asp:hyperlink  runat="server"               resourcekey="Calendar">Calendar</asp:hyperlink>                 <asp:comparevalidator  runat="server"               resourcekey="valExpiryDate.ErrorMessage"                  controltovalidate="txtExpiryDate" errormessage="<br>Invalid expiry               date!" display="Dynamic" type="Date"                  operator="DataTypeCheck"></asp:comparevalidator></TD>           </TR>       </TABLE>       <P>           <asp:linkbutton  runat="server" resourcekey="cmdUpdate"       text="Update"></asp:linkbutton>&nbsp;           <asp:linkbutton  runat="server" resourcekey="cmdCancel"       text="Cancel" causesvalidation="False"></asp:linkbutton>&nbsp;           <asp:linkbutton  runat="server" resourcekey="cmdDelete"       text="Delete" causesvalidation="False"></asp:linkbutton></P>           <portal:audit  runat="server"></portal:audit> </asp:panel> 
image from book

As you can see in Listing 15-12, the EditEvents form consists of several controls. Many are ASP.NET controls, such as the linkbutton, textbox, validators, and others. In addition to the ASP.NET controls, there are several of the DotNetNuke controls covered in Table 15-4. The first control you encounter is the DNN Label control:

 <dnn:label  runat="server" controlname="txtTitle" suffix=":"></dnn:label></TD> 

Initially you registered the control, and now it is placed into the form. Since the label is a DNN control, it performs like any other label because it inherits from the ASP.NET control, but in addition you can associate information with the control, such as multiple languages from a resource file.

Further down the code is the TextEditor control:

 <dnn:texteditor  runat="server"></dnn:texteditor> 

By default, DotNetNuke uses FreeTextBox, which is a freely available open source control that you can use in your own applications. Because DotNetNuke uses a Provider Model for the TextEditor control, you can easily use any third-party control.

Next in line are controls that were registered using the "portal" prefix. These controls are for tracking activity within the portal. For example, when someone clicks on an event or any item in the portal, you can use these controls to track how many were clicked and who clicked on them. Of course to track who clicked on an item, users need to be logged on to the portal:

 <portal:url  runat="server" showtabs="False" showurls="False" urltype="F" showtrack="False" showlog="False" required="False"></portal:url> 

Some of the options enable you to show a log of clicks next to the item, tracking and other information for tracking activity, and display of the item. The control also integrates with DNN security, which enables you to display navigation of tab structure and still maintain the security so only those who have permissions for the resource see the information.

At the bottom of the page is an Audit control for tracking activity of the module. The Portal Audit control provides you with information on who created the information and the created date:

 <portal:audit  runat="server"></portal:audit> 

Now check out the code-behind to see how to work with the data and the controls. So far, you've dealt with displaying data from the BLL. Next you're going to be adding and updating information, so you'll need to pass parameters to your stored procedures in SQL. Refer to Chapters 13 and 14 to see how this all comes together.

Edit Events Code-Behind Class

Now that you've covered the front-end control that the user interacts with, take a look at the code-behind file and see how the class is structured. As before, you import the namespaces and define the class:

 Imports DotNetNuke Imports System.Web.UI.WebControls Namespace DotNetNuke.Modules.Events     Public MustInherit Class EditEvents              Inherits Entities.Modules.PortalModuleBase 

You'll notice again you inherit from the PortalModuleBase class as you did in the View control. Because this control is for adding data specific to your application, you'll inherit PortalModuleBase. Just to be clear on the difference between this control and the Settings control, which inherits from the ModuleSettingsBase class of DotNetNuke, the Settings control is specific to the operation of the module, not the item data that is entered in tables that you create. The Settings data is stored within internal tables native to DotNetNuke, so you need to inherit from the ModuleSettingsBase, which is focused on this task. An Edit control is specific to your application so it inherits from PortalModuleBase.

Edit Events Code Regions

Again, each section in the class is broken down into code regions for readability and organization. Here you review the regions specific to the EditEvents.ascx.vb file.

The first region is the Controls region, where you declare the controls you have created in your web form in the EditEvents.ascx control (see Listing 15-13).

Listing 15-13: Controls Region of the EditEvents.ascx.vb File

image from book
 #Region "Controls"     Protected WithEvents pnlContent As System.Web.UI.WebControls.Panel     Protected plTitle As UI.UserControls.LabelControl     Protected WithEvents txtTitle As System.Web.UI.WebControls.TextBox     Protected WithEvents valTitle As _        System.Web.UI.WebControls.RequiredFieldValidator     Protected plDescription As UI.UserControls.LabelControl     Protected WithEvents teDescription As UI.UserControls.TextEditor     Protected WithEvents valDescription As _        System.Web.UI.WebControls.RequiredFieldValidator     Protected plImage As UI.UserControls.LabelControl     Protected WithEvents ctlImage As UI.UserControls.UrlControl     Protected plAlt As UI.UserControls.LabelControl     Protected WithEvents txtAlt As System.Web.UI.WebControls.TextBox     Protected WithEvents valAltText As _        System.Web.UI.WebControls.RequiredFieldValidator     Protected plEvery As UI.UserControls.LabelControl     Protected WithEvents txtEvery As System.Web.UI.WebControls.TextBox     Protected WithEvents cboPeriod As System.Web.UI.WebControls.DropDownList     Protected plStartDate As UI.UserControls.LabelControl     Protected WithEvents txtStartDate As System.Web.UI.WebControls.TextBox     Protected WithEvents cmdStartCalendar As _        System.Web.UI.WebControls.HyperLink     Protected WithEvents valStartDate As _        System.Web.UI.WebControls.RequiredFieldValidator     Protected WithEvents valStartDate2 As _        System.Web.UI.WebControls.CompareValidator     Protected plTime As UI.UserControls.LabelControl     Protected WithEvents txtTime As System.Web.UI.WebControls.TextBox     Protected plExpiryDate As UI.UserControls.LabelControl     Protected WithEvents txtExpiryDate As System.Web.UI.WebControls.TextBox     Protected WithEvents cmdExpiryCalendar As _        System.Web.UI.WebControls.HyperLink     Protected WithEvents valExpiryDate As _        System.Web.UI.WebControls.CompareValidator     'tasks     Protected WithEvents cmdUpdate As System.Web.UI.WebControls.LinkButton     Protected WithEvents cmdCancel As System.Web.UI.WebControls.LinkButton     Protected WithEvents cmdDelete As System.Web.UI.WebControls.LinkButton     'footer     Protected WithEvents ctlAudit As _        DotNetNuke.UI.UserControls.ModuleAuditControl #End Region 
image from book

Most of the controls are ASP.NET controls as previously covered in Listing 15-12. You can see where you declare the DotNetNuke controls:

  • Label controls:

     Protected plTitle As UI.UserControls.LabelControl Protected plDescription As UI.UserControls.LabelControl Protected plImage As UI.UserControls.LabelControl Protected plEvery As UI.UserControls.LabelControl Protected plTime As UI.UserControls.LabelControl Protected plExpiryDate As UI.UserControls.LabelControl 

  • URL control:

     Protected WithEvents ctlImage As UI.UserControls.UrlControl 

  • Audit control:

     Protected WithEvents ctlAudit As DotNetNuke.UI.UserControls.ModuleAuditControl 

The next region is the Private Members region for storing an item ID value (see Listing 15-14). Because you're in the module's Edit control, you use this to add and update individual items. This variable is used to store the primary key of the individual event contained in the Events table.

Listing 15-14: Private Members Region of the Edit Control

image from book
 #Region "Private Members"         Private itemId As Integer = -1 #End Region 
image from book

The next region is the Event Handlers region for dealing with click events and the Page_Load event for the control. Here you start with the Page_Load event and then see what is happening in each event for the Edit control of the Events module (see Listing 15-15).

Listing 15-15: Events Handlers Region of the Edit Control — Page Load Event

image from book
 Private Sub Page_Load(ByVal sender As System.Object, ByVal e As _      System.EventArgs) Handles MyBase.Load     Try           ' Determine ItemId of Events to Update          If Not (Request.QueryString("ItemId") Is Nothing) Then              itemId = Int32.Parse(Request.QueryString("ItemId"))               End If         'this needs to execute always to the         'client script code is registered in InvokePopupCal          cmdStartCalendar.NavigateUrl = _            CType(Common.Utilities.Calendar.InvokePopupCal(txtStartDate), String)          cmdExpiryCalendar.NavigateUrl = _            CType(Common.Utilities.Calendar.InvokePopupCal(txtExpiryDate), String)         ' If the page is being requested the first time, determine if an         ' event itemId value is specified, and if so populate page         ' contents with the event details         If Page.IsPostBack = False Then             cmdDelete.Attributes.Add("onClick", "javascript:return confirm('" & _               Localization.GetString("DeleteItem") & "');")             If Not Common.Utilities.Null.IsNull(itemId) Then                 ' Obtain a single row of event information                 Dim objEvents As New EventController                 Dim objEvent As EventInfo = objEvents.GetEvent(itemId, ModuleId)                 ' Read first row from database                 If Not objEvent Is Nothing Then                     txtTitle.Text = objEvent.Title                     teDescription.Text = objEvent.Description                     ctlImage.FileFilter = glbImageFileTypes                     ctlImage.Url = objEvent.IconFile                     If Not objEvent.IconFile = "" Then                         valAltText.Visible = False                     Else                         valAltText.Visible = True                     End If                     txtAlt.Text = objEvent.AltText                     txtEvery.Text = objEvent.Every.ToString                     If txtEvery.Text = "1" Then                         txtEvery.Text = ""                     End If                     If objEvent.Period <> "" Then                         cboPeriod.Items.FindByValue(objEvent.Period).Selected = _                         True                     Else                         cboPeriod.Items(0).Selected = True                     End If                     txtStartDate.Text = objEvent.DateTime.ToShortDateString                     txtTime.Text = objEvent.DateTime.ToShortTimeString                     If objEvent.DateTime.ToString("HH:mm") = "00:00" Then                         txtTime.Text = ""                     End If                     If Not Common.Utilities.Null.IsNull(objEvent.ExpireDate) Then                         txtExpiryDate.Text = objEvent.ExpireDate.ToShortDateString                     Else                         txtExpiryDate.Text = ""                     End If                     ctlAudit.CreatedByUser = objEvent.CreatedByUser                     ctlAudit.CreatedDate = objEvent.CreatedDate.ToString                 Else  ' security violation attempt to                       ' access item not related to this Module                     Response.Redirect(NavigateURL(), True)                 End If             Else                 cmdDelete.Visible = False                 ctlAudit.Visible = False                 valAltText.Visible = False             End If         End If     Catch exc As Exception    'Module failed to load         ProcessModuleLoadException(Me, exc)     End Try End Sub 
image from book

The first thing the Page_Load event does is to check the query string to determine whether you're working with a new or existing item in the Events table.

Further down you check for a null value by using the Common.Utilities.Null.IsNull method and passing it the itemID value. If the event ID is not null, you instantiate the EventsController class and execute the GetEvent method. Remember, this GetEvent method is contained in the Business Logic Layer, which then executes a call to the abstraction class, and eventually the physical provider that executes the corresponding stored procedure within the SQL database:

 Dim objEvents As New EventController Dim objEvent As EventInfo = objEvents.GetEvent(itemId, ModuleId) 

You pass not only the itemID value to the stored procedure, but when you add a record you also add a value for ModuleID. The ModuleID is being provided by PortalModuleBase, which exposes the current module instance's ID to your class. The ID is a unique identifier provided by DotNetNuke that is generated each time a module is placed in the page. This ID provides the developer with a means to reuse modules, but have unique data for each instance.

Further down in the Page_Load event, you can see another DotNetNuke-specific item, and that is where you populate your Audit control with the information on the user creating the new event item:

 ctlAudit.CreatedByUser = objEvent.CreatedByUser ctlAudit.CreatedDate = objEvent.CreatedDate.ToString 

This provides tracking internally so you can see who performed what action in your module. All these controls are optional for you to use in your module development.

Now you can move on to button action events. Listing 15-16 contains click events for cmdCancel, cmdDelete, and cmdUpdate link buttons.

Listing 15-16: Handling Linkbutton Events in the EditEvents Class

image from book
 Private Sub cmdCancel_Click(ByVal sender As Object, ByVal e As EventArgs) _     Handles cmdCancel.Click     Try         Response.Redirect(NavigateURL(), True)     Catch exc As Exception    'Module failed to load         ProcessModuleLoadException(Me, exc)     End Try End Sub Private Sub cmdDelete_Click(ByVal sender As Object, ByVal e As EventArgs) _     Handles cmdDelete.Click     Try           Dim objEvents As New EventController          objEvents.DeleteEvent(itemId)          objEvents = Nothing          ' Redirect back to the portal home page          Response.Redirect(NavigateURL(), True)     Catch exc As Exception    'Module failed to load                ProcessModuleLoadException(Me, exc)     End Try End Sub Private Sub cmdUpdate_Click(ByVal sender As Object, ByVal e As EventArgs) _     Handles cmdUpdate.Click     Try          Dim strDateTime As String          ' Only Update if the Entered Data is Valid          If Page.IsValid = True Then              strDateTime = txtStartDate.Text              If txtTime.Text <> "" Then                  strDateTime += " " & txtTime.Text              End If              Dim objEvent As New EventInfo              objEvent.ItemId = itemId              objEvent.ModuleId = ModuleId              objEvent.CreatedByUser = UserInfo.UserID.ToString              objEvent.Description = teDescription.Text              objEvent.DateTime = Convert.ToDateTime(strDateTime)              objEvent.Title = txtTitle.Text              If txtEvery.Text <> "" Then                   objEvent.Every = Convert.ToInt32(txtEvery.Text)              Else                   objEvent.Every = 1              End If              objEvent.Period = cboPeriod.SelectedItem.Value              objEvent.IconFile = ctlImage.Url              objEvent.AltText = txtAlt.Text              If txtExpiryDate.Text <> "" Then                   objEvent.ExpireDate = Convert.ToDateTime(txtExpiryDate.Text)              End If              ' Create an instance of the Event DB component              Dim objEvents As New EventController              If Common.Utilities.Null.IsNull(itemId) Then                   ' Add the event within the Events table                   objEvents.AddEvent(objEvent)              Else                   ' Update the event within the Events table                   objEvents.UpdateEvent(objEvent)              End If              objEvents = Nothing              ' Redirect back to the portal home page              Response.Redirect(NavigateURL(), True)          End If      Catch exc As Exception    'Module failed to load          ProcessModuleLoadException(Me, exc)      End Try End Sub 
image from book

The first event you're handling in Listing 15-16 is cmdCancel_Click. Basically all you want to do is redirect the users back to where they started from, which is the default view of the module. In this case, it would be the View control talked about earlier in the chapter. One thing you'll notice is the use of NavigateURL, which is a function that returns a string for your module's view page. NavigateURL is provided by the DotNetNuke framework to provide navigation through your module logic to load the appropriate controls based on the module's key that you defined when you first configured DotNetNuke to interface with the module (see Chapter 12). Another key feature to the navigation methods provided by DotNetNuke is the support of friendly URLs (which you learn about later in this chapter), which eliminates query strings being passed in the URL and uses a directory structure for passing parameters.

The second event is cmdDelete_Click, which captures when the user deletes a specific event from the listing. You make another call to your EventsController, and pass the ID of the event you want deleted so eventually the stored procedure is called to delete the event. After the event is deleted, you redirect back to the initial View control of the module.

The final event is cmdUpdate_Click. This event handler contains a little more code than the previous methods. Initially you create an instance of the EventController class and populate the properties for an EventInfo object. These values are passed from the user controls contained in the web form on the web control. After the values are populated, you check to see if this is an existing event by looking at the item ID. If it's an existing event, you call the UpdateEvent method of the controller class. If you're adding an event, you call the AddEvent method of the EventController class. Finally, you use the NavigateURL function and redirect to the initial View control of the module.

That completes the architectural review of a DotNetNuke module.




Professional DotNetNuke 4.0 (c) Open Source Web Application Framework for ASP. NET 4.0
Professional DotNetNuke 4: Open Source Web Application Framework for ASP.NET 2.0 (Programmer to Programmer)
ISBN: 0471788163
EAN: 2147483647
Year: 2006
Pages: 182

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net