0

I have a VisualForce page with a list of objects on one side and a section on the right that shows details about the objects. The section on the right is a VF Component. The component controller has a method that looks up the details based on the object's ID.

The idea is when the user clicks on the list, the component updates. Now, I know how to define an ActionFunction, and to call a method on the page controller via Javascript in response to the onclick. But how do I call a method on the component controller to update the ID and have it reload it's data?

0

The easiest way is to do so via an attribute on the component.

<apex:component controller="XYZ">
   <apex:attribute name="recordId" description="The record to view" assignTo="{!currentRecordId}" />

And in the controller:

public class XYZ {
    Id recordId;
    public void setCurrentRecordId(Id newRecordId) {
        if(newRecordId != recordId) {
            recordId = newRecordId;
            reloadData();
        }
    }
    // reloadData and related attributes not included
}

At that point, all you need to do is set the selected record Id in your page's controller/extension, and the assignTo function will notify your component of the change. Strictly speaking, you don't need an actionFunction, just a normal action method would work as well.


In the page:

<c:myComponent recordId="{!selectedRecordId}" />

...

<apex:repeat value="{!itemList}" var="item">
    {!item.name} <apex:commandLink action="{!item.selectRecordId}" />
</apex:repeat>

And in your controller:

public class pageController {
    public Id selectedRecordId { get; set; }
    public class Wrapper {
        pageController controller;
        public SObject record { get; set; }
        public void selectRecordId() {
            controller.selectedRecordId = record.Id;
        }
    }
    public Wrapper[] itemList { get; set; }
    // set itemList to the values for the wrapper
}
  • Hmmm. I am doing pretty much exactly as you suggest. But my page is not reloading. I used an ActionFunction so I could specify exactly what to rerender. I was under the impression that the component controller constructor (say that five times fast) would not be invoked again on the PostBack. Not true? – SalesForce Jedi May 26 '17 at 21:27
  • @SalesForceJedi Constructors are not, but assignTo attributes are evaluated each time the component is rendered. Also, commandLink/commandButton both support reRender targets. – sfdcfox May 26 '17 at 21:28
  • I see it now. You specify the method, not the property in the attribute. That's the missing piece. Thanks so much! – SalesForce Jedi May 26 '17 at 21:32
  • To clarify: I was trying to do this in two steps 1) update the attribute value and 2) call some method to refresh the data. Reading @sfdcfox's response I realized D'oh! Just use a setter for the attribute and do both. So my attribute: <apex:attribute name="AppID" description="Selected appointment." required="false" assignTo="{!AppointmentID}" type="ID"/> and in the controller: private ID myID {get; set;} public ID AppointmentID { get {return myID;} set { if (myID!=value) { myID=value; if (myID==null) clearData(); else getDetails(); } } } – SalesForce Jedi May 28 '17 at 14:46

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.