function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
MTBRiderMTBRider 

Encapsulating functionality with component controllers

I must be missing something very basic here.  I am trying to build a page with multiple components and want to encapsulate all of the functionality for each component into the component's own controller.  So a simplified version of it would look something like this:

 

-- VF page --
<apex:page controller="pageController">
   <c:myComponent/>
</apex:page>

-- myComponent.component--
<apex:component controller="compController" allowDML="true">
   <apex:attribute name="c" description=" " Type="Case" assignTo="{!cLookup}" required="required"/>
   
<apex:inputText label="Look Up a Case: " value="{!cNumber}"/> <apex:commandButton action="{!lookUpCase}" value=" Go "/>
<apex:messages/>
<apex:outputLabel value="Case Number: "/>
<apex:outputField value="{!c.CaseNumber}"/>
<apex:outputLabel value="Status: "/>
<apex:outputField value="{!c.status}"/>
</apex:component>

-- compController.cls --
public with sharing class compController {
private PageReference pageRef = ApexPages.currentPage();
public Case cLookup;
public String cNumber {get; set;}

public Case getcLookup() {
return cLookup;
}

public void setcLookup(Case cs) {
cLookup = cs;
}

public PageReference lookUpCase() {
if (cNumber.trim() != null) {
if ([Select COUNT() FROM Case WHERE caseNumber = :cNumber LIMIT 1] != 1) {
ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.INFO, 'The Case number indicated was not found.' ); ApexPages.addMessage(msg);
} else {
cLookup = ([Select CaseNumber, Status FROM Case WHERE caseNumber = :cNumber LIMIT 1]);
}
}
return pageRef;
}
}

 In the above example, I know the component controller is being called...if a bad case number is input the error message shows on the screen and I can see that the query is returning a record when a good case number is input by looking at the logs.  What is not happening is the case field values are not displaying on the screen.  If I copy all of the code in compController into pageController and change the controller reference in the component to pageController all is good.  

 

Again, I am not understanding something very basic here I am sure.  Please enlighten me.  Thanks

Best Answer chosen by Admin (Salesforce Developers) 
MTBRiderMTBRider

I found the problem with this if anyone is interested.  It was simply that the lookUpCase method was returning a pagereference which would result in a get request back to the server which would re-initialize all of the variables in the controller.  So even though cLookUp was being populated with the data of the Case I wanted, it was then being nulled out when the get request was executed when the lookUpCase method returned the pagereference. 

 

Changing lookUpCase to return void and then just doing a rerender in the VF component did the trick.

All Answers

bob_buzzardbob_buzzard

I think this is because you are updating the clookup property in the controller rather than the attribute that is passed in and used on the page, which will retain the original case reference.  

 

If you change the markup to use the controller property, that should pick up the revised details:

 

<apex:outputField value="{!cLookup.CaseNumber}"/>
<apex:outputLabel value="Status: "/>
<apex:outputField value="{!cLookup.status}"/>

 

MTBRiderMTBRider

That did not work.  I still get nothing displayed in the outputfields.  

 

My understanding of "name" and "assignTo" in the Attribute component was that the what you specify in "name" is assigned the values returned by the setter method specified in "assignTo". 

 

Any other thoughts?

MTBRiderMTBRider

I found the problem with this if anyone is interested.  It was simply that the lookUpCase method was returning a pagereference which would result in a get request back to the server which would re-initialize all of the variables in the controller.  So even though cLookUp was being populated with the data of the Case I wanted, it was then being nulled out when the get request was executed when the lookUpCase method returned the pagereference. 

 

Changing lookUpCase to return void and then just doing a rerender in the VF component did the trick.

This was selected as the best answer