Search Articles


Sort By
  

Article Categories

Authors & MVPs

Kelly Ford

Introducing DNNDev University

The new DNNDev University doesn't have a winning football team. It is built on people - you and I and everyone who uses DotNetNuke and XMod Pro.

XModPro

Shooting Blanks at the CAPTCHA Control

I've gotten a few questions lately about the behavior of the CAPTCHA control in XMod Pro forms running in DNN 5. It's been discovered that if you leave the input blank on the CAPTCHA control, you are allowed to submit the form. Could this be true? Well, yes-and-no.

The XMod Pro CAPTCHA control is based on the DotNetNuke CAPTCHA control. Because of this, you automatically get the advantage of any advances they make in that control to help thwart 'bots. The downside of this equation is that the behavior of your control may change as new versions are implemented by DotNetNuke.

Being able to post back a form when the CAPTCHA control is left blank is a good case-in-point. In older versions of DNN, the control would display an error message when this happened. If you look at the code in these earlier versions (I looked at DNN 4.5.5), you'll see that it would become invalid if the value in the input box didn't equal the text being displayed in the CAPTCHA image. So, if the test value was "aH65j" and the user doesn't enter anything in the input box, the two values aren't going to be equal – thus failing the test.

Sometime later (I haven't tracked down the exact version), DNN implemented a change in the control. Now (referring to DNN 5) the control checks and only marks the input as invalid if there is text in the input control and that text doesn't equal the test value. So, if the user doesn't enter anything in the input box, the control does nothing. The reason for this change, most likely, is that this behavior enables the end-user to get a different CAPTCHA test if he/she cannot read the first set of characters displayed. Of course, this should properly be implemented in the control itself with a "fetch new value" type of button the user can press. By not having that button, the user experience is more confusing than it needs to be. The user clicks the Add button in your form, the page posts back, the CAPTCHA test changes, but no other information is provided.

The good news is that if no value is typed into the CAPTCHA control's input box, the form will be considered invalid by XMod Pro and the SubmitCommand will not execute. The information your user entered into other controls on the form should still be in the form, so they won't lose any work.

While I wish I could implement a solution to bypass the usability issue, I can't think of any, short of going in and editing the DNN CAPTCHA control. I'm not an expert on the CAPTCHA control, so I certainly could be overlooking something. You cannot use standard validation controls because the CAPTCHA control writes an HTML INPUT control to the page during rendering and it does not add that control to its controls collection. So, you can't add a required field validator. In addition, there is nothing exposed publicly or protected that can be used by an encapsulating control to get at that input control or any other data/methods that might be useful in developing a workaround.

For now, there are a couple of things you can do if your users are confused:

  • Provide some help text to them explaining that they can get a new CAPTCHA test value by pressing the Add button.

  • Add some Javascript to the Add button that notifies the user the CAPTCHA control is empty via the Confirm function. Let them know they can click Cancel to enter the proper value or they can click OK and the form will post back, retrieving a new value for the test.

So, here is a sample form using the CAPTCHA control, implementing the Javascript usability helper.

<addForm>

    <label for="txtFieldOne" text="Field One:" /> 

    <textbox id="txtFieldOne" datafield="FieldOne" datatype="string" /> <br />

    <captcha id="captOne" captchalength="5" errormessage="Wrong Captcha" errorstyle-forecolor="red" />
    

<ScriptBlock blocktype="ClientScript" scriptid="validateCaptcha">

  <script type="text/javascript">

    function validateCaptcha(captId){

      var captValue = jQuery('input[@name=' + captId.replace(/_/g,"$") + ']').val();

      if (captValue == ''){

        return confirm('You must enter a value for the CAPTCHA control. Would you like a new CAPTCHA value?');

      }

      return true;

    }

  </script>

</ScriptBlock>

    ...

    <addbutton text="Add" OnClientClick="return validateCaptcha(XMPForm.captOne);" /> &nbsp;<cancelbutton text="Cancel"/>

</addForm>

Explanation:

  • I've given the CAPTCHA control an ID of "captOne" (line 4)

  • I've used the ScriptBlock tag to add a Javascript function called "validateCaptcha" to the page that encapsulates most of the work (lines 6-15)

  • validateCaptcha uses jQuery to easily access and get the value of the CAPTCHA control's input box. Note: since the control does not assign a client ID to the input control, we have to access it via its "name" attribute. This complicates the script a bit since we only have the ID. All we have to do is replace all the underscores (_) in the ID with dollar signs ($) and we've got the name. We do that using Javascript's regular expression facility (line 9)

  • We then check the value of the input to see if it's empty. (line 10)

  • Only if it's empty, do we notify the user about the condition and get their input. When the user clicks the Cancel button in the Confirm dialog, it will return a value of false. Clicking OK will return true. (line 11)

  • If the input control is not empty, we want to process the form normally, so we return true. (line 12)

  • Finally, we call the validateCaptcha function from the Add button's OnClientClick event. We use XMod Pro's helper function (XMPForm.controlID) to get the client ID of the CAPTCHA control. (line 18)

This is merely a usability enhancement for the end user of your form if you think they would be confused by the CAPTCHA control's behavior. It is meant to be an example of one way to handle the situation. Feel free to use/not use/modify this to suit your particular needs.

Comments & Ratings

    (Ratings: 0   Avg: )
Rate It!
Share It!