DotNetNuke 5.4 Cookbook
(For more resources on DotNetNuke, see here.)
Showing data in a Treeview
A Treeview control is used when you have information arranged in a hierarchy like the organizational chart of a company. The Treeview control will show each level in the hierarchy with an icon to drill-down or expand to the next level.
Getting ready
To follow along with this recipe you must have completed the following recipes:
- Deploying a module as a standalone package
- Displaying a Datagrid with filter controls
- Adding web controls to your Toolbox
The Treeview control requires that the employees in the Employee table have been assigned to managers. Here is the data that was used in this recipe:
In this example, the employees are arranged in a simple two-level hierarchy. If your ManagerNo is 0 it means you are a manager. Otherwise the manager number on your record is the ItemID of your manager. So John Smith is a manager (his ManagerNo=0) and he manages Kevin Jones and Amy Roe (as their ManagerNo is John Smith’s ItemID).
How to do it…
- Launch the Development Tool and load the Employee project.
- In the Solution Explorer, look under the references and make sure your project includes a reference to DotNetNuke.WebUtility.dll.
- Double-click to open the ViewEmployee.ascx file.
- Start by adding a new register directive at the top of the file:
<%@ Register tagprefix="DNN" assembly="DotNetNuke.WebControls"
namespace="DotNetNuke.UI.WebControls" %> - Next, we’ll create a simple tree control by placing the following code at the bottom of the file, right after the paging control:
<dnn:PagingControl ID="ctlPagingControl" runat="server">
</dnn:PagingControl>
<br />
<DNN:DnnTree ID="treeManager" runat="server"
CollapsedNodeImage="~imagesplus.gif"
ExpandedNodeImage="~imagesminus.gif">
</DNN:DnnTree> - Next, open the ViewEmployee.ascx.vb file.
- Look at the top of the file and make sure the following imports are there:
Imports System.Data.SqlClient
Imports DotNetNuke.UI.WebControls - We must create a procedure to populate the tree control with records from the database. Find the Private Methods region at the top of the file and add the following new procedures:
#Region "Private Methods"
Private Sub PopulateTreeControl()
' set the images to use for the nodes
treeManager.ImageList.Add("..imagesicon_hostusers_16px.gif")
treeManager.ImageList.Add("..imagesicon_users_16px.gif")
' reset the tree control
treeManager.TreeNodes.Clear()
Dim objParentNode As TreeNode
' get the list of all managers and create a parent node for each
one
Dim objEmployeeController As New EmployeeController
Dim drMgr As SqlDataReader
drMgr = objEmployeeController.GetManagersDR(ModuleId)
If drMgr.HasRows Then
Do While drMgr.Read()
objParentNode = New TreeNode()
objParentNode.Text = drMgr("EmpLastName") + ", " +
drMgr("EmpFirstName")
objParentNode.ImageIndex = 0 ' manager image
objParentNode.ClickAction = eClickAction.Expand ' when click
on a manager, expand
objParentNode.HasNodes = True
treeManager.TreeNodes.Add(objParentNode)
PopulateEmployeeNodes(objParentNode, drMgr("ItemId"))
Loop
End If
drMgr.Close()
End Sub
Private Sub PopulateEmployeeNodes(ByRef objParentNode As TreeNode,
ByVal ParentItemId As Integer)
Dim objChildNode As TreeNode
' get the list of all employee with the given manager
Dim objEmployeeController As New EmployeeController
Dim colEmployees As ArrayList
Dim objEmployeeInfo As EmployeeInfo
Dim TotalRecords As Integer
colEmployees = objEmployeeController.GetEmployeesByFilter
(ModuleId, ParentItemId, -1, 0, 1000, TotalRecords)
If colEmployees.Count > 0 Then
' add a node to the parent that was passed
For intEmp = 0 To colEmployees.Count - 1
objEmployeeInfo = CType(colEmployees(intEmp), EmployeeInfo)
objChildNode = New TreeNode(objEmployeeInfo.EmpLastName + ", "
+ objEmployeeInfo.EmpFirstName)
objChildNode.ImageIndex = 1 ' employee image
objParentNode.TreeNodes.Add(objChildNode)
Next intEmp
End If
End Sub
#End Region - What we are doing here is calling a new GetManagersDR function for the first level of the tree, then calling the GetEmployeesByFilter function to get the list of employees for each manager.
- Next, we need to call these new procedures when the page loads, so scroll down to the Page_Load procedure and add the following code inside the IsPostBack check:
If Page.IsPostBack = False Then
If Not Request.QueryString("PageRecords") Is Nothing Then
ddlRecordsPerPage.SelectedValue =
Request.QueryString("PageRecords")
End If
BindManagerDropDown()
BindSalaryDropDown()
BindData()
PopulateTreeControl()
End If - Next, open the EmployeeController.vb file.
- The last step is to create the new GetManagersDR function. This is just like the GetManagers function, but this the function returns the list of managers as a DataReader. Add the following code to the bottom of the Public Methods region:
Public Function GetManagersDR(ByVal ModuleId As Integer) As
SqlDataReader
Return DataProvider.Instance().GetManagers(ModuleId)
End Function
#End Region - Select Save All from the File menu.
- To check the results, build and deploy the module to a development portal for testing.
- Go to the ACME Employee page to see the list of employees in a tree control.
How it works…
In this recipe we saw the tasks to organize database records in a hierarchy tree control:
- We placed the control in the .ascx file
- We defined the images to use for the expand and collapse indicators
- In the code behind file we changed the Page_Load procedure to populate the tree
- We created a PopulateTreeControl procedure with two parts:
- Query the database for the employee managers
- For each manager add them to the tree and query the database for the employees they manage
Using a TabStrip to separate content
There are many times when you have a lot of information to display, but not enough space on the page. The TabStrip control maximizes the available space by separating the content into tabs and displaying one tab at a time.
To demonstrate this control we’re going to take the five fields of the Edit Employee page and split them onto two different tabs.
Getting ready
To follow along with this recipe you must have completed the following recipes:
- Adding web controls to your Toolbox
- Deploying a module as a standalone package
How to do it…
- Launch the Development Tool and load the Employee project.
- In the Solution Explorer, look under the references and make sure your project includes a reference to DotNetNuke.WebUtility.dll.
- Double-click to open the EditEmployee.ascx file.
- Make sure the following register directive is at the top of the file:
<%@ Register tagprefix="DNN" assembly="DotNetNuke.WebControls"
namespace="DotNetNuke.UI.WebControls" %> - We will replace the existing HTML table containing the employee fields with a TabStrip control table holding the name fields under the first tab and the information fields under the second tab. Replace the existing HTML table with the following highlighted code:
<%@ Control language="vb" Inherits="ACME.Modules.Employee.EditEmployee" AutoEventWireup="false
Explicit="True" Codebehind="EditEmployee.ascx.vb" %>
<%@ Register TagPrefix="dnn" TagName="Label"
Src="~/controls/LabelControl.ascx" %>
<%@ Register TagPrefix="dnn" TagName="TextEditor"
Src="~/controls/TextEditor.ascx"%>
<%@ Register TagPrefix="dnn" TagName="Audit"
Src="~/controls/ModuleAuditControl.ascx" %>
<%@ Register tagprefix="DNN" assembly="DotNetNuke.WebControls"
namespace="DotNetNuke.UI.WebControls" %>
<DNN:DNNTabStrip
ID="tsEmployee"
runat="server"
TabRenderMode="All"
CssTabContainer="LoginTabGroup"
CssContentContainer="LoginContainerGroup"
DefaultContainerCssClass="LoginContainer"
DefaultLabel-CssClass="LoginTab"
DefaultLabel-CssClassHover="LoginTabHover"
DefaultLabel-CssClassSelected="LoginTabSelected"
visible="true" >
<dnn:DNNTab Label-Text="Employee Name" ID="tab1">
<table width="650" cellspacing="0" cellpadding="0" border="0"
summary="Edit Table">
<tr valign="top">
<td class="SubHead" width="125"><dnn:label
id="lblEmpFirstName" runat="server"
controlname="lblEmpFirstName" suffix=":">
</dnn:label>
</td>
<td>
<asp:TextBox ID="txtEmpFirstName" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="valEmpFirstName"
resourcekey="valEmpFirstName.ErrorMessage"
ControlToValidate="txtEmpFirstName"
CssClass="NormalRed" Display="Dynamic"
ErrorMessage="<br>EmpFirstName is required"
Runat="server" />
</td>
</tr>
<tr valign="top">
<td class="SubHead" width="125"><dnn:label
id="lblEmpLastName" runat="server"
controlname="lblEmpLastName" suffix=":">
</dnn:label>
</td>
<td>
<asp:TextBox ID="txtEmpLastName" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="valEmpLastName"
resourcekey="valEmpLastName.ErrorMessage"
ControlToValidate="txtEmpLastName"
CssClass="NormalRed" Display="Dynamic"
ErrorMessage="<br>EmpLastName is required"
Runat="server" />
</td>
</tr>
</table>
</dnn:DNNTab>
<dnn:DNNTab Label-Text="Information" ID="tab2">
<table width="650" cellspacing="0" cellpadding="0" border="0"
summary="Edit Table">
<tr valign="top">
<td class="SubHead" width="125"><dnn:label
id="lblManagerNo" runat="server"
controlname="lblManagerNo" suffix=":">
</dnn:label>
</td>
<td>
<asp:TextBox ID="txtManagerNo" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="valManagerNo"
resourcekey="valManagerNo.ErrorMessage"
ControlToValidate="txtManagerNo"
CssClass="NormalRed" Display="Dynamic"
ErrorMessage="<br>ManagerNo is required"
Runat="server" />
</td>
</tr>
<tr valign="top">
<td class="SubHead" width="125"><dnn:label
id="lblHireDate" runat="server"
controlname="lblHireDate" suffix=":">
</dnn:label>
</td>
<td>
<asp:TextBox ID="txtHireDate" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="valHireDate"
resourcekey="valHireDate.ErrorMessage"
ControlToValidate="txtHireDate"
CssClass="NormalRed" Display="Dynamic"
ErrorMessage="<br>HireDate is required"
Runat="server" />
</td>
</tr>
<tr valign="top">
<td class="SubHead" width="125"><dnn:label id="lblSalary"
runat="server" controlname="lblSalary" suffix=":">
</dnn:label>
</td>
<td>
<asp:TextBox ID="txtSalary" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="valSalary"
resourcekey="valSalary.ErrorMessage"
ControlToValidate="txtSalary"
CssClass="NormalRed" Display="Dynamic"
ErrorMessage="<br>Salary is required" Runat="server" />
</td>
</tr>
</table>
</dnn:DNNTab>
</dnn:DNNTabStrip>
<br /><br />
<p>
<asp:linkbutton cssclass="CommandButton" id="cmdUpdate"
resourcekey="cmdUpdate" runat="server"
borderstyle="none" text="Update">
</asp:linkbutton>
<asp:linkbutton cssclass="CommandButton" id="cmdCancel"
resourcekey="cmdCancel" runat="server"
borderstyle="none" text="Cancel"
causesvalidation="False">
</asp:linkbutton>
<asp:linkbutton cssclass="CommandButton" id="cmdDelete"
resourcekey="cmdDelete" runat="server"
borderstyle="none" text="Delete"
causesvalidation="False">
</asp:linkbutton>
</p>
<dnn:audit id="ctlAudit" runat="server" /> - Select Save All from the File menu.
- To check the results, build and deploy the module to a development portal for testing.
- Go to the ACME Employee page and click on the edit icon (the little pencil) next to an employee to display the Edit Employee page.
- When you edit the employee record you will see the fields have been separated into two separate tabs. Clicking on Employee Name displays the first tab with the name fields:
- Clicking on Information reveals the remaining fields:
The appearance of the tab strip is controlled by the styles we apply to it (CssTabContainer, CssContentContainer, DefaultLabel-CssClass, DefaultLabel-CssClassHover, and DefaultLabel-CssClassSelected). In this example we used the same styles as the DNN Login page so we have a similar look and feel. The styles are defined in the /portals/_default/default.css by default.
How it works…
In this recipe we saw the tasks to use a TabStrip control:
- We placed the control in the .ascx file
- We separated the existing content onto separate tabs