4

This question is similar to How to call a standard controller action of a VF page from a VF component, but there are two differences I see:

  • I'm not using a standard controller
  • the <apex:form> tags are in my component

I am trying to get the commandButton on the component to call the addMethod method on my extension. For whatever reason, this isn't happening. Nothing shows in the debug logs, so it doesn't appear to be working. There are no errors or exceptions thrown.

Should this be possible?

Update: The page uses an apex:repeat element, there's an onClick on the commandButton, the rendered value looks at the record type

My page

<apex:page standardController="Custom_Object__c" extensions="CustomObjectExtension">
    ... some content
    <apex:repeat value="{!childObjects}" var="cObject">
        <c:componentWithForm addMethodAction="{!addMethod}" rendered="{!cObject.RecordType.Name == 'My Record Type'} />
    </apex:repeat>
    ... more content
</apex:page>

Where the childObjects in the repeat element is a List

My component

<apex:component>
    <apex:attribute name="addMethodAction" type="ApexPages.Action" ... />
    <apex:form>
        <apex:inputText ... />
        <apex:commandButton onclick="return someFunction();" action="{!addMethodAction}" />
    </apex:form>
</apex:component>

My extension

public class CustomObjectExtension
{
    public List<Child_Object__c> childObjects {get; set;}

    public CustomObjectExtension(ApexPages.StandardController stdController)
    {
        .. do stuff
        childObjects = [SELECT ... FROM Child_Object__c];
    }

    public PageReference addMethod()
    {
        .. do stuff
    }
}
  • Just so we're clear, this did actually compile, right? It's just not working? – sfdcfox Jan 20 '17 at 0:16
  • @sfdcfox yes, it compiled. (I re-wrote it for this post). I didn't get any errors/exceptions. The addMethod just isn't being called – Nick Cook Jan 20 '17 at 0:18
  • 1
    Okay, well... it worked for me when I replicated it in my dev org. – sfdcfox Jan 20 '17 at 0:27
  • I added an assertion in the method to cause the page to crash, which it promptly did as soon as I clicked the button. I suspect something else is wrong with your code. I'd be glad to share the code I used to see if there's any discrepancies. – sfdcfox Jan 20 '17 at 0:31
  • Ok, thanks for taking the time. There must be something simple I'm missing – Nick Cook Jan 20 '17 at 0:31
4

I found 3 strange reasons why the addMethod wasn't being called. I'd love to hear from anyone that has any ideas on the why, or where I might be wrong.

OnClick attribute

For some reason the onClick attribute on the apex:commandButton was preventing it being called. This includes if I left it empty, or just had a 'return true;' or 'return false;' in there.

No actionRegion

When the component was being called from within an apex:repeat element, the component needed an actionRegion element for it to correctly call the addMethod.

e.g.

<apex:component>
    <apex:attribute name="addMethodAction" type="ApexPages.Action" ... />
    <apex:form>
        <apex:actionRegion>
            <apex:inputText ... />
            <apex:commandButton onclick="return someFunction();" action="{!addMethodAction}" />
        </apex:actionRegion>
    </apex:form>
</apex:component>

rendered attribute on the component

This is really weird. When calling the component, the way the rendered attribute is populated seems to matter. For the component to render, the result of the rendered expression must be true, so you'd assume that if the button is on tha page, the behaviour should be the same.

That doesn't appear to be the case however. For some reason, if the rendered attribute is populated as the result of a variable-to-string comparison, addMethod isn't called.

I had: rendered="{!cObject.RecordType.Name == 'My Record Type'}" but this didn't work. The button would be displayed, but the addMethod method would not be called.

Changing it to rendered="true" worked. Delving deeper, 1==1 worked, '1'=='1' worked, today()==today() worked.

cObject.myTextField__c == 'expected value' did not work.

cObject.myBooleanField__c did work.

In the end I had to create a formula field on the Custom_Object__c that returned true if RecordType.Name == 'My Record Type'

I then called the rendered attribute as follows: rendered="{!cObject.myBooleanFormulaField__c}"


Has anyone seen behaviour like this? Does anyone have any idea why this is happening? Am I going crazy?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.