We have received a lot of requests from our clients on how to extend the backend Forms page and add functionality to display the emails of the users subscribed to receive email notifications on form submission. In this blog post I am going to demonstrate how to add a link under the Forms Actions menu and when clicking on the link to display the subscribers emails.
Creating the service interface and the service class to retrieve the subscribers emails by form id
We can start with implementing the web service which will retrieve the subscriber’s emails by form id. In order to do this, we can create a folder named CustomServices under the root folder of the Sitefinity project and add a new interface under this folder named IFormsServiceExtended.cs.
It is important that we mark the interface with the ServiceContract attribute and this way define it as a service contract. Next, we will define a GetSubscribers method in the service interface and will expose it as a web service method by adding the OperationContract attribute. We can also map a URI to the service operation by setting the UriTemplate property of the WebGet attribute. Here is a sample implementation of the interface:
using
System.ServiceModel;
using
System.ServiceModel.Web;
using
Telerik.Sitefinity.Utilities.MS.ServiceModel.Web;
namespace
SitefinityWebApp.CustomServices
{
[ServiceContract]
public
interface
IFormsServiceExtended
{
/// <summary>
/// Tests the connection to the service.
/// </summary>
[WebHelp(Comment =
"Tests the connection to the service. Result is returned in JSON format."
)]
[WebGet(UriTemplate =
"GetSingleFormSubscribers/?itemId={formId}"
, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
string
GetSubscribers(
string
formId);
}
}
Now, we can create the service class under the CustomServices folder which inherits from the IFormsServiceExtended interface. In this class we can add the logic for getting the emails of the forms subscribers from the notification service and retrieve the emails in the GetSubscribers method or display a custom message if there are no subscribers for the selected form. You can use the following sample code for the service class:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.ServiceModel;
using
System.ServiceModel.Activation;
using
System.ServiceModel.Web;
using
System.Text;
using
Telerik.Sitefinity.Modules.Forms;
using
Telerik.Sitefinity.Services;
using
Telerik.Sitefinity.Services.Notifications;
using
Telerik.Sitefinity.Web.Services;
namespace
SitefinityWebApp.CustomServices
{
[ServiceBehavior(IncludeExceptionDetailInFaults =
true
, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public
class
FormsServiceExtended : IFormsServiceExtended
{
public
string
GetSubscribers(
string
formId)
{
string
subscriberEmails = FormSubscriberEmails(formId);
if
(
string
.IsNullOrEmpty(subscriberEmails))
{
return
"There are no subscribers for this form!"
;
}
return
subscriberEmails;
}
public
string
FormSubscriberEmails(
string
formId)
{
var formManager = FormsManager.GetManager();
var id =
new
Guid(formId);
var form = formManager.GetForms().Where(f => f.Id == id).SingleOrDefault();
var subscriptionListId = form.SubscriptionListId;
var notificationService = SystemManager.GetNotificationService();
var serviceContext =
new
ServiceContext(
"ThisApplicationKey"
, formManager.ModuleName);
List<ISubscriberResponse> formSubscribers = notificationService.
GetSubscribers(serviceContext, subscriptionListId,
new
QueryParameters())
.ToList();
List<
string
> subscriberEmails =
new
List<
string
>();
if
(formSubscribers !=
null
)
{
foreach
(var subscriber
in
formSubscribers)
{
subscriberEmails.Add(subscriber.Email);
}
}
string
result =
string
.Join(
"</br>"
, subscriberEmails);
return
result;
}
}
}
After we are ready with the service design and implementation we can create the service hosting in Sitefinity. In order to do this, please navigate to the ~/Sitefinity/Public/Services folder where by convention all web services are located. Create a folder named GetFormsSubscribers and add a WCF service named GetSubscribers.svc.
In order to implement the service with Sitefinity, please open the newly created GetSubscribers.svc file and set the Factory attribute on the service to Telerik.Sitefinity.Web.Services.WcfHostFactory and the Service attribute to the namespace of the service retrieving the data as shown below:
<%@ ServiceHost Language=
"C#"
Debug=
"true"
Service=
"SitefinityWebApp.CustomServices.FormsServiceExtended"
Factory=
"Telerik.Sitefinity.Web.Services.WcfHostFactory"
%>
Using the service
After we implement the service, we can create a javascript file under the root folder of the project and name it ExtendedFormsMasterViewSript.js. In this javascript file we will execute the service using a jQuery AJAX call and also we will add custom logic for displaying the results on a web page. Please open the newly created ExtendedFormsMasterViewSript.js file and add the following code:
var
str =
""
;
function
getpagesCommandHandler(sender, args) {
if
(args._commandName ==
"GetSubscribers"
) {
jQuery.ajax({
type:
"GET"
,
url: sender._baseUrl +
"Sitefinity/Public/Services/GetFormsSubscribers/GetSubscribers.svc/GetSingleFormSubscribers/?itemId="
+ args._dataItem.Id,
contentType:
"application/json; charset=utf-8"
,
dataType:
"json"
,
processdata:
false
,
success:
function
(data) {
if
(data !=
"ERROR"
) {
var
myWindow = window.open(
""
,
"MsgWindow"
+ args._dataItem.Id,
"toolbar=yes, scrollbars=yes,menubar=yes, resizable=yes, top=500, left=500, width=400, height=400"
);
myWindow.document.write(
"<html><head></head><body></body></html>"
);
myWindow.document.write(
"<h2>Emails of the users subscribed for forms notifications are:</h2>"
+ data);
}
},
error:
function
(data) { }
});
}
}
function
OnMasterViewLoadedCustom(sender, args) {
sender.add_itemCommand(getpagesCommandHandler);
}
After performing the above steps, please build the solution.
Register the custom javascript
The next step will be to register the custom javascript (ExtendedFormsMasterViewSript.js) which will be loaded by the Forms grid view and which will execute the GetSubscribers command . Please go to Administration -> Settings -> Advanced -> Forms -> Controls -> FormsBackend -> Views -> FormsBackendList -> Scripts and create a new entry by clicking on the Create new button.
In the Script location field enter the relative path to the custom ExtendedFormsMasterViewSript.js file. According to the sample in this blog post the javascript file is under the root directory of the project folder and the relative path should be ~/ExtendedFormsMasterViewSript.js
In the Name of the load method field enter OnMasterViewLoadedCustom
Command button type: Standard
Name: GetSubscribers
CommandText: GetSubscribers
WrapperTagId: Li
WrapperTagName: Unknown
Type: Telerik.Sitefinity.Web.UI.Backend.Elements.Widgets.CommandWidget, Telerik.Sitefinity
Please restart the application by re-saving your web.config file in order for the changes to take effect.
After performing the above steps a GetSubscribers link will appear under the Actions menu for each form under Content -> Forms. On click, the emails of the form subscribers will appear in a separate window.
I have also recorded a short video for your reference demonstrating the above steps on my side and the results.
You can get and fork the full sample from the GitHub.
I hope that you will find the blog post useful.
Sabrie Nedzhip
Sabrie Nedzhip is a Tech Support Engineer at Telerik. She joined the Sitefinity Support team in December 2013.