The Silver Lining

Lessons & Learnings from a salesforce certified technical architect.

OOP in the Salesforce Cloud – ReCaptcha Revisited

with 5 comments

Can I get a OOP OOP?! That’s right folks, OOP is alive and well on the Force.com platform, and over the past few months I’ve had some pretty thrilling experiences implementing projects using those trusted sidekicks Encapsulation, Polymorphism and trusty ol’ Abstraction. There is some pretty sweet documentation on the subject, but I thought I’d demo something supercool I learnt by combining two articles from the Force.com wiki.

A few months back I first encountered a post on how to embed a ReCaptcha widgetExample within a Force.com application. This article is awesome and opened my eyes to the world of possibilities achievable using Apex and Visualforce. If you believe, then you can do it.. build it and they will come *ahem*. Since then I’ve used this same code in a few places, and this got me a-thinking.. ‘Wes, this code is modular, and it’s useful in many a sphere, you should schtick it in a component!’.

A good thought if I do say so myself, but I encountered the same problem time and time again viz. when I click the button that submits the captcha, how do I let the page controller know the component controller’s result?! Unfortunately, time and time again, I thought that I would need to combine the page controller and ReCaptcha class so that the two could have a nice chat. And I was wrong.. wrongidy-wrong-wrong. And this is why…

Some time later I came across a Force.com wiki article that detailed an object oriented framework that enable communication between Page and Component controllers. This is one of my favourite Force.com articles so far and I’ll tell you why, it’s simple, it’s elegant, it’s modular and reusable. I tip my hat to author(his name isn’t in the article), you sir are legend – wait for it - dary.

Combining these two technical articles I was finally able to create the ReCaptcha component I’d always dreamt of, and you can see them working in wonderous harmony in a demo page I’ve created. The code itself is quite long, so I’ll point out the highlights, and attach the code for you to peruse..

Starting with the Wiki articles, I’ve made no changes to the Page-Controller communications pattern and only one change to the ReCaptcha class,

public class ReCaptcha extends ComponentControllerBase

That is, is now extends the ComponentControllerBase class. I’ve also created a component to house the ReCaptcha widget which takes a reference to the Page Controller as an attribute,

<apex:attribute name=”PageController” type=”PageControllerBase” assignTo=”{!pageController}” description=”A reference to the page controller” required=”true”/>

And most of the remaining code is a cut-and-paste job from Ron Hess’ original article. The previous component attribute, together with the page that wraps it form the glue that binds the ReCaptcha Widget to the page. The page itself,

<!– The Good Stuff Starts HERE –>

<apex:outputPanel id=”msg” >

<apex:form rendered=”{!ISNULL(response)}”>

<!– Pass the component an instance of the page controller –>

<c:ReCaptcha pageController=”{!this}”/>

<!– And here is a bit of trickery. We need to verify the ReCaptcha that is used in the component, but the page controller presumably has to do some processing, and this processing is dependent on the ReCaptcha result. Because of these considerations we put the button on the page instead of within the controller. –>

<apex:commandButton onclick=”javascript:captureResponse(this);” value=”Page Controller: Verify” action=”{!verify}” rerender=”msg” style=”float:left”/>

</apex:form>

<!– Response Pane –>

<apex:outputPanel layout=”block” style=”clear:both;text-align:left”>

<apex:form rendered=”{!NOT(ISNULL(response))}”>

<apex:outputText value=”{!response}”  style=”font-family:Georgia;font-size:24px;padding:10px;”/>

<apex:commandButton value=”Try Again?” action=”{!URLFOR($Page.Page)}”/>

</apex:form>

</apex:outputPanel>

</apex:outputPanel>

<!– End of Good Stuff(TM) –>

And the here is the page controller,

public with sharing class PageController extends PageControllerBase{

public String response{get;set;}

public void verify(){

// Cast the controller correctly. Note: The method ‘getMyComponentController()’ is a member of PageControllerBase

ReCaptcha recaptcha = (ReCaptcha)this.getMyComponentController();

// Perform recaptcha verification on input values

recaptcha.verify();

// And then check the response

if(recaptcha.correctResponse)

response = ‘Page Controller: Correct. OOP FTW!';

else

response = ‘Page Controller: Wrong! But you can try again:)';

}

}

<!– The Good Stuff Starts HERE –>
<apex:outputPanel id=”msg” >
<apex:form rendered=”{!ISNULL(response)}”>
<!– Page the component an instance of the page controller –>
<c:ReCaptcha pageController=”{!this}”/>
<!– And here is a bit of trickery. We need to verify the ReCaptcha that is used in the component, but
the page controller presumably has to do some processing, and this processing is dependent on the ReCaptcha
result. Because of these considerations we put the button on the page instead of within the controller. –>
<apex:commandButton onclick=”javascript:captureResponse(this);” value=”Page Controller: Verify” action=”{!verify}” rerender=”msg” style=”float:left”/>
</apex:form>
<!– Response Pane –>
<apex:outputPanel layout=”block” style=”clear:both;text-align:left”>
<apex:form rendered=”{!NOT(ISNULL(response))}”>
<apex:outputText value=”{!response}”  style=”font-family:Georgia;font-size:24px;padding:10px;”/>
<apex:commandButton value=”Try Again?” action=”{!URLFOR($Page.Page)}”/>
</apex:form>
</apex:outputPanel>
</apex:outputPanel>
<!– End of Good Stuff(TM) –>

Admittedly this sort of framework can be difficult to comprehend initially, but understanding the fundamentals undertaken here, and realising their application can make you feel pretty darn smart. You could even take this sort of code to bars and and use it to get chicks, that’s how I got my lady.. Yes, she is real I swear.

Reading through this post alone probably won’t get the lightbulbs flashing unless you’ve previously worked with the mentioned concepts before. In either case I recommend grabbing the attached code and punching through it, I give you my 14-day money back guarantee it’ll make future-you happy that present-you did.

[Click Here to Download Source Files]

About these ads

Written by Wes

October 1, 2009 at 3:53 pm

5 Responses

Subscribe to comments with RSS.

  1. I am sooooo happy for you. Glad you found a use for the framework. Next hurdle is how to get the same joy out of nested components on a page :-)

    Dave Carroll

    October 1, 2009 at 8:57 pm

    • I was thinking that just yesterday:) There’s also a limitation on the Page-Controller comms framework that I realised while working with it. But I’ll save that for another post ;)

      Wes

      October 1, 2009 at 9:26 pm

  2. Great stuff Wes.

    d3developer

    October 1, 2009 at 9:34 pm

  3. Also a very useful technique to communicate between controllers and class extensions.

    Richard Tuttle

    October 17, 2009 at 12:31 am

  4. [...] curious problem had me befuddled because it’s not as clear-cut as the page-component controller comms situation. I realise this is quite a complex situation to consider without some visuals, so [...]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 2,204 other followers

%d bloggers like this: