CAPTCHA for Sitefinity Forms

CAPTCHA for Sitefinity Forms

December 14, 2011 0 Comments

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.

Implementing the CAPTCHA widget

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.

Implementing the server-side class

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
 
    }
}

Implement the client-side component

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); 

 Implementing the control template

 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>

Project overview

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.

Registering the QapTcha widget

To be able to use the widget we must do two things:

  1. Register our assembly with the Virtual Path Provider so that Sitefinity can resolve the widget template. To do so go to Administration -> Settings -> Advanced -> VirtualPathSettings -> Virtual paths and add a new virtual path for the control, then restart the website. Sample bellow:
  2. Register the custom control in the Forms toolbox. To so go to Administration -> Settings -> Advanced -> Toolboxes -> FormControls -> Sections -> Common -> Tools and register the custom control.

Download sample project

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.

progress-logo

The Progress Guys

View all posts from The Progress Guys on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.

Comments
Comments are disabled in preview mode.
Topics
 
 
Latest Stories in
Your Inbox
Subscribe
More From Progress
d12fcc0bdb669b804e7f71198c9619a7
5 Questions Automakers Should Ask to Improve Asset Uptime
Download Whitepaper
 
SF_MQ_WCM
2018 Gartner Magic Quadrant Web Content Management (WCM)
Download Whitepaper
 
What-Serverless-Means-For-Enterprice-Apps-Kinvey
What Serverless Means for Enterprise Apps
Watch Webinar