|
phdcc.Data DNN modules |
| Form programmer hooks |
In any DNN program code, you can use the phdcc.Data.Form.FormController method GetResultSetsForUser() to obtain a list of filled-in-forms for a particular user for a specified form. Method GetResultSetsCountForUser() returns the count of forms filled in by the user. For example, you could use the phdcc.CodeModule DNN module to interrogate results from phdcc.Data.Form.
Here are the C# method definitions in phdcc.Data.Form.FormController:
public System.Collections.Generic.List<ResultSetInfo> GetResultSetsForUser(string FormIdName, int PortalId, int UserID);
public int GetResultSetsCountForUser(string FormIdName, int PortalId, int UserId);
phdcc.Data.Form.ResultSetInfo and associated classes are defined below.
GetResultSetsForUser() never returns null.
The list is ordered with the most recent ResultSets first.
Each time a form's Submit button is pressed, a new ResultSetInfo is generated, each containing a list of ResultInfo individual answers. Use the ResultSetInfo Validates and Authorised properties to determine the state of each ResultSet. You can use the ResultSetInfo Form() method to find the answers provided for individual questions.
Here is some example C# code that builds a list of all the Town answers given by a user on the specified form:
using phdcc.Data.Form;
...
string rv = "Towns:";
FormController fc = new FormController();
List<ResultSetInfo> rsis = fc.GetResultSetsForUser("idAboutPreferences", PortalId, UserID);
foreach( ResultSetInfo rsi in rsis)
if( rsi.Validates) rv += " "+rsi.Form("isQTown");
You can hide a question on a form for an individual user by setting a Session variable to "hidden".
For example, use this Visual Basic code to hide the question that has id "idSurveySex":
<% Page.Session("idSurveySex") = "hidden" %>
The question is only hidden while the user's session is stored, so if the user closes their browser and returns later then the session variable will (probably) not be still be set. You might wish to set the session variable in a form hook event handler (see below), or perhaps elsewhere using the phdcc.CodeModule programmable DNN module.
The question is not hidden if you are a user in DNN edit mode, eg a DNN administrator. The question is hidden by changing the question control to "Question_Hidden" and the question type to "hiddenfield". Any previously stored values for a question are kept if updated by a user while hidden.
You can add to the phdcc.Data.Form functionality by writing ASP.NET VB or C# code that handles various form events. Currently, you can handle these events:
FormLoaded() - called after the form has been loadedFormEditing() - called when a form starts editingFormStored() - called after form data has been storedFormAuthorised() - called after a form has been authorised by an administratorUserRegistered() - called after a user has been registered in a Profile/Register formLet us know if you require hooks for other events.
If you output any information that a user provided, please remember to make it HTML safe by calling Server.HtmlEncode().
To add your form event hook handlers, write a user control in VB or C#. Upload the file to the
DesktopModules\phdcc.Data.Form directory. In the form editor, enter the name of your control
in the "Form hook control" box.
Use the following as the basis of a VB user control.
Only include methods for the events that you wish to handle.
The following code is in a file called FormHookVB.ascx so that it matches
the chosen ClassName property (without the extension).
The filename must not start with a number and should not contain periods and spaces.
Your code will usually also contain the various Import lines.
<%@ Control Language="VB" ClassName="FormHookVB" Inherits="phdcc.Data.Form.FormHookBase" AutoEventWireup="true" %>
<%@ Import Namespace="phdcc.Data.Form" %>
<%@ Import Namespace="DotNetNuke.Entities.Modules" %>
<%@ Import Namespace="DotNetNuke.Entities.Profile" %>
<%@ Import Namespace="DotNetNuke.Entities.Users" %>
<%@ Import Namespace="DotNetNuke.Services.Mail" %>
<script runat="server">
Public Overrides Function FormLoaded(ByVal viewForm As PortalModuleBase, ByVal form As FormInfo) As Boolean
Return True
End Function
Public Overrides Sub FormEditing(ByVal viewForm As PortalModuleBase, ByVal form As FormInfo)
End Sub
Public Overrides Sub FormStored(ByVal viewForm As PortalModuleBase, ByVal form As FormInfo, ByVal rsi As ResultSetInfo)
End Sub
Public Overrides Sub FormAuthorised(ByVal viewForm As PortalModuleBase, ByVal form As FormInfo, ByVal rsi As ResultSetInfo)
End Sub
Public Overrides Sub UserRegistered(ByVal viewForm As PortalModuleBase, ByVal form As FormInfo, ByVal CreatedUserInfo As UserInfo)
End Sub
</script>
If your code does not compile, then the compile error exception and stack trace will be shown in red above the form Admin box if you are in DNN edit mode, ie you are logged in as a DNN administrator.
If there are any runtime exceptions, then these are caught. For ordinary users, these exceptions are not shown. If you are in DNN edit mode, ie you are logged in as a DNN administrator, then the exception and stack trace are shown in red before the form Admin box.
Please consult the DNN documentation or code and the phdcc.Data.Form code for details of these objects. phdcc.Data.Form.ResultSetInfo is detailed below.
Each instance corresponds to a form answer is added as a row to DNN database table phdcc_Data_Results.
The FormLoaded event hook is called after the form has been loaded but before the group and question controls are created. If you return false then the form is not generated (even the Admin block is not visible).
The FormEditing event hook is called if the form is editable, ie when first shown, after Amend pressed and when validation fails. It is called after the form has been loaded and the group and question controls are created (in the page PreRender phase).
The FormStored event hook is called after a user has submitted a form.
Property rsi.Validates indicates whether the form validated.
The FormAuthorised event hook is called after a form has been authorised by an administrator.
The string value in Session("EditResultType") indicates what type of admin operation is in progress:
The UserRegistered event hook is called after a user has been created in a Profile/Register form.
The following C# example shows how to handle the FormAuthorised event hook. The code determines if this is the first time that a set of results has been authorised for this user. If so, then it resends the standard email with the user registration details, including their password. This email could be enhanced to show more information using [Custom:0] tokens, eg submitted form values.
The code first inspects the form LastAuthorised and LastResultsAuthorised fields
to determine if this is the first set of authorised results for this user.
If it is, the DNN UserInfo is retrieved.
Normally, the Membership.Password field is blank at this stage, so the code uses a sneaky
technique to obtain this direct from the ASP.NET System.Web.Security.Membership class.
The code then uses standard DNN techniques to retrieve a localised email subject and body from the GlobalResources. Note that the password will be replaced with ******* if the user is a SuperUser. Finally, DNN class DotNetNuke.Services.Mail.Mail is used to send the email.
<%@ Control Language="C#" ClassName="FormHookCS" Inherits="phdcc.Data.Form.FormHookBase" AutoEventWireup="true" %>
<%@ Import Namespace="phdcc.Data.Form" %>
<%@ Import Namespace="DotNetNuke.Entities.Modules" %>
<%@ Import Namespace="DotNetNuke.Entities.Profile" %>
<%@ Import Namespace="DotNetNuke.Entities.Users" %>
<%@ Import Namespace="DotNetNuke.Services.Mail" %>
<script runat="server">
public override void FormAuthorised(PortalModuleBase viewForm, FormInfo form, ResultSetInfo rsi)
{
// Determine if this is the first set of authorised results
bool FirstSetOfAuthorisedResults = false;
if (!form.LastAuthorised)
FirstSetOfAuthorisedResults = (form.LastResultsAuthorised.Count == 0);
if( FirstSetOfAuthorisedResults)
{
// Get DNN user
UserInfo ui = UserController.GetUser(viewForm.PortalId, rsi.UserId,true);
// Sneakily get password
MembershipUser user = Membership.GetUser(ui.Username);
string pwd = user.GetPassword();
ui.Membership.Password = pwd;
// Get subject from GlobalResources
string Subject = Localization.GetSystemMessage(viewForm.PortalSettings.DefaultLanguage, viewForm.PortalSettings, "EMAIL_USER_REGISTRATION_PUBLIC_SUBJECT", ui);
// Get body from GlobalResources
string Body = Localization.GetSystemMessage(viewForm.PortalSettings.DefaultLanguage, viewForm.PortalSettings, "EMAIL_USER_REGISTRATION_PUBLIC_BODY", ui); // pwd will be replaced with ******* if SuperUser
// Send the email
string SendMailError = Mail.SendMail(viewForm.PortalSettings.Email, ui.Email, form.EmailTo, Subject, Body, "", "text", "", "", "", "");
}
}
</script>
You can write a user control to show your own custom question -
select the control question type.
You can program in either VB or C#, following the instructions given here.
Your user control must be in the DesktopModules/phdcc.Data.Form directory -
the full filename must be specified in the ControlFilename question option.
In essence, your user control must let the user answer a question. The answer is always returned to phdcc.Data.Form as a string. You must get any previously entered value and display it. You must provide custom validation and store the answer string.
For a profile form that has been filled in, the initial display has an "Amend" button with all the questions disabled. The phdcc.Data.Form code automatically disables and enables all of your controls. If there is any special enable handling, then do this job in the Enabled property setter.
phdcc.Data.Form primarily works with ViewState turned off, ie all controls have EnableViewState="false". It is recommended that you follow this practice.
Your user control must be based on phdcc.Data.Form.QuestionUserControlBase and override the following methods and property (defined here in C#):
qc to access question and form information.
Available for download (ExampleUserControl.zip) is an example question user control. It is written in Visual Basic (VB) with a separate codebehind file.
The user control displays a list box with five options available for multiple selection.
The currently selected items are shown to the right.
JavaScript is used to update the display on the right as items are selected.
The control stores the currently selected items as a string, with each selected option appended, comma separated.
The control uses an asp:ListBox control with a hard-coded list of options.
The currently selected items are displayed as the InnerHtml of an HTML TD element which has the following
attributes to make it usable server-side:
ID="litChosen" EnableViewState="false" runat="server"
The list box has its onchange client-side event handler set to JavaScript function SetStaffSelected.
This JavaScript works out which items are selected and re-creates the TD contents to match.
The VB codebehind for the control implements all the required methods and properties - it shows how to do standard tasks such as loading default and previous values, validation and storage.