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 widget 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:)’;
}
}
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.
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 🙂
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 😉
Great stuff Wes.
Also a very useful technique to communicate between controllers and class extensions.