The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.
Recently there have been a number of requests for adding a CAPTCHA to the Sitefinity Forms widgets. Since the standard CAPTCHA controls that work with postback are not suitable for the Forms control, I am going to walk you through the process of implementing a client-side CAPTCHA control which can be used on Sitefinity Forms. I've stumbled on this blog post: 8 jQuery CAPTCHA Plugin with Tutorial, listing different jQuery CAPTCHA libraries. For this article I chose to use the first plugin(QapTcha), however the same principle applies for the rest of the plugins and you can use any of them. Now let's proceed to the implementation part.
We are going to implement our custom widget as a script control, so we need to inherit from SimpleScriptView. This will allow us to use our control not only for Forms, but also for other places where we need CAPTCHA. The process of implementation is the same as the one for Book Widget part of the Siteifnity SDK, minus the implementation of a Silverligh control.
The only logic that our server side class will hold are just a few properties that are used by the QapTcha plugin to set up the UI. We need to expose those properties, set up the layout template path for the widget and refer the scripts on which this plugin depends. You can find the class implementation bellow:
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Web.UI;
using
System.Web.UI.HtmlControls;
using
Telerik.Sitefinity.Modules.Pages;
using
Telerik.Sitefinity.Web.UI;
namespace
Telerik.Sitefinity.Samples.Forms
{
class
FormQapTchaControl: SimpleScriptView
{
#region Properties
protected
override
string
LayoutTemplateName
{
get
{
return
null
; }
}
public
override
string
LayoutTemplatePath
{
get
{
return
this
.layoutTemplatePath;
}
set
{
this
.layoutTemplatePath = value;
}
}
[Category(
"QapTcha properites"
)]
public
bool
AutoRevert
{
get
{
return
this
.autoRevert;
}
set
{
this
.autoRevert = value;
}
}
[Category(
"QapTcha properites"
)]
public
bool
DisabledSubmit
{
get
{
return
this
.disabledSubmit;
}
set
{
this
.disabledSubmit = value;
}
}
[Category(
"QapTcha properites"
)]
public
string
TxtLock
{
get
{
return
this
.txtLock;
}
set
{
this
.txtLock = value;
}
}
[Category(
"QapTcha properites"
)]
public
string
TxtUnlock
{
get
{
return
this
.txtUnlock;
}
set
{
this
.txtUnlock = value;
}
}
#endregion
[Browsable(
false
)]
public
HtmlGenericControl QapTchaDiv
{
get
{
return
this
.Container.GetControl<HtmlGenericControl>(
"QaptCha"
,
true
);
}
}
#region Methods
protected
override
void
OnPreRender(EventArgs e)
{
base
.OnPreRender(e);
PageManager.ConfigureScriptManager(
this
.Page, ScriptRef.JQueryUI);
}
public
override
IEnumerable<System.Web.UI.ScriptDescriptor> GetScriptDescriptors()
{
var descriptors =
new
List<ScriptDescriptor>();
var descriptor =
new
ScriptControlDescriptor(
typeof
(FormQapTchaControl).FullName,
this
.ClientID);
//pass property values to the script component
descriptor.AddProperty(
"qapTchaDiv"
,
this
.QapTchaDiv.ClientID);
descriptor.AddProperty(
"autoRevert"
,
this
.AutoRevert);
descriptor.AddProperty(
"disabledSubmit"
,
this
.DisabledSubmit);
descriptor.AddProperty(
"txtLock"
,
this
.TxtLock);
descriptor.AddProperty(
"txtUnlock"
,
this
.TxtUnlock);
descriptors.Add(descriptor);
return
descriptors;
}
public
override
IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
{
var scripts =
new
List<ScriptReference>()
{
new
ScriptReference(FormQapTchaControl.componentScriptPath,
typeof
(FormQapTchaControl).Assembly.FullName),
new
ScriptReference(FormQapTchaControl.qapTchaScript,
typeof
(FormQapTchaControl).Assembly.FullName),
new
ScriptReference(FormQapTchaControl.jqueryUITouchScript,
typeof
(FormQapTchaControl).Assembly.FullName)
};
return
scripts;
}
protected
override
void
InitializeControls(GenericContainer container)
{
}
#endregion
#region Private fields
public
string
layoutTemplatePath =
"~/SfControls/Telerik.Sitefinity.Samples.Forms.Resources.Views.FormQapTchaControl.ascx"
;
private
bool
autoRevert =
true
;
private
bool
disabledSubmit =
true
;
private
string
txtLock =
"Locked : form can't be submited"
;
private
string
txtUnlock =
"Unlocked : form can be submited"
;
private
static
string
componentScriptPath =
"Telerik.Sitefinity.Samples.Forms.Resources.Scripts.FormQapTchaControl.js"
;
private
static
string
jqueryUITouchScript =
"Telerik.Sitefinity.Samples.Forms.Resources.Scripts.jquery.ui.touch.js"
;
private
static
string
qapTchaScript =
"Telerik.Sitefinity.Samples.Forms.Resources.Scripts.QapTcha.jquery.js"
;
#endregion
}
}
The purpose of the client side component is to simply initialize our QapTcha plugin. We need to provide getter and setter methods for our properties, and pass them to the plugin:
Type.registerNamespace(
"Telerik.Sitefinity.Samples.Forms"
);
Telerik.Sitefinity.Samples.Forms.FormQapTchaControl =
function
(element) {
Telerik.Sitefinity.Samples.Forms.FormQapTchaControl.initializeBase(
this
, [element]);
this
._qapTchaDiv =
null
;
this
._autoRevert =
null
;
this
._disabledSubmit =
null
;
this
._txtLock =
null
;
this
._txtUnlock =
null
;
}
Telerik.Sitefinity.Samples.Forms.FormQapTchaControl.prototype = {
initialize:
function
() {
Telerik.Sitefinity.Samples.Forms.FormQapTchaControl.callBaseMethod(
this
,
'initialize'
);
//set QapTcha settings
$(
'#'
+
this
.get_qapTchaDiv()).QapTcha(
{ disabledSubmit:
this
.get_disabledSubmit(),
autoRevert:
this
.get_autoRevert(),
txtLock:
this
.get_txtLock(),
txtUnlock:
this
.set_txtUnlock()
});
},
dispose:
function
() {
Telerik.Sitefinity.Samples.Forms.FormQapTchaControl.callBaseMethod(
this
,
'dispose'
);
},
// properties
get_qapTchaDiv:
function
() {
return
this
._qapTchaDiv; },
set_qapTchaDiv:
function
(value) {
this
._qapTchaDiv = value; },
get_autoRevert:
function
() {
return
this
._autoRevert; },
set_autoRevert:
function
(value) {
this
._autoRevert = value; },
get_disabledSubmit:
function
() {
return
this
._disabledSubmit; },
set_disabledSubmit:
function
(value) {
this
._disabledSubmit = value; },
get_txtLock:
function
() {
return
this
._txtLock; },
set_txtLock:
function
(value) {
this
._txtLock = value; },
get_txtUnlock:
function
() {
return
this
._txtUnlock; },
set_txtUnlock:
function
(value) {
this
._txtUnlock = value; }
}
Telerik.Sitefinity.Samples.Forms.FormQapTchaControl.registerClass(
'Telerik.Sitefinity.Samples.Forms.FormQapTchaControl'
, Sys.UI.Control);
The control template is used to refer the style sheet that defines the look an feel of the QapTcha plugin and define a placeholder div for the slider:
<%@ Control Language="C#" AutoEventWireup="true" %>
<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>
<
sf:ResourceLinks
id
=
"resourcesLinks1"
runat
=
"server"
UseEmbeddedThemes
=
"true"
>
<
sf:ResourceFile
Name
=
"Telerik.Sitefinity.Samples.Forms.Resources.CSS.QapTcha.jquery.css"
AssemblyInfo
=
"Telerik.Sitefinity.Samples.Forms.FormQapTchaControl, Telerik.Sitefinity.Samples.Forms"
Static
=
"true"
/>
</
sf:ResourceLinks
>
<
div
id
=
"QaptCha"
class
=
"QapTcha"
runat
=
"server"
></
div
>
After you have implemented your client-side and server-side components, the control template, and have added the dependent scripts, styles and images for the QapTcha plugin the project should look similar to the on the bellow image:
The last step in terms of the project is to register the embedded resources (CSS, image and script files) with our assembly. To do so edit the AssemblyInfo class:
[assembly: WebResource(
"Telerik.Sitefinity.Samples.Forms.Resources.Scripts.FormQapTchaControl.js"
,
"application/x-javascript"
)]
[assembly: WebResource(
"Telerik.Sitefinity.Samples.Forms.Resources.Scripts.jquery.ui.touch.js"
,
"application/x-javascript"
)]
[assembly: WebResource(
"Telerik.Sitefinity.Samples.Forms.Resources.Scripts.QapTcha.jquery.js"
,
"application/x-javascript"
)]
[assembly: WebResource(
"Telerik.Sitefinity.Samples.Forms.Resources.Images.bg_QapTcha.png"
,
"image/png"
)]
[assembly: WebResource(
"Telerik.Sitefinity.Samples.Forms.Resources.Images.sprites.png"
,
"image/png"
)]
[assembly: WebResource(
"Telerik.Sitefinity.Samples.Forms.Resources.CSS.QapTcha.jquery.css"
,
"text/css"
, PerformSubstitution = true)]
You can now build the code library project and add it to the bin folder of your Sitefinity project.
To be able to use the widget we must do two things:
You can download the project for the custom control from this location: Telerik.Sitefinity.Samples.Forms. Make sure that you resolve the references to Sitefinity and OpenAccess assemblies.
View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites
Progress collects the Personal Information set out in our Privacy Policy and the Supplemental Privacy notice for residents of California and other US States and uses it for the purposes stated in that policy.
You can also ask us not to share your Personal Information to third parties here: Do Not Sell or Share My Info
We see that you have already chosen to receive marketing materials from us. If you wish to change this at any time you may do so by clicking here.
Thank you for your continued interest in Progress. Based on either your previous activity on our websites or our ongoing relationship, we will keep you updated on our products, solutions, services, company news and events. If you decide that you want to be removed from our mailing lists at any time, you can change your contact preferences by clicking here.