12

Can I pass a email value from a visualforce component to a Visualforce page? I have used components for reusing Company's logo and few images...

<apex:component>
    <apex:image value="{!$Resource.Logo}"> </apex:image>
</apex:component>

Is it possible to pass variable to a visualforce page?

Thanks.

4 Answers 4

9

The easiest way is to pass in the controller of your visualforce page. This means you'll need either a custom controller or an extension. When you pass in the controller, you can then call getters or setters on the controller given they are publicly accessible.

For example:

<apex:component>
    <apex:attribute name="ctrl" description="My controller" type="MyControllerClassName" required="true"/>
    <apex:image value="{!URLFOR(ctrl.ImageUrlGetter)}"> </apex:image>
</apex:component>
0
12

There is an extensive blog post on the Developerforce website here regarding this matter to help you out.

As a summary - you should pass in the controller of your page as an apex attribute of your component (just as James mentions). You will have your component look like

<apex:component controller="MyComponentController" >
    <apex:attribute name="pageController" type="PageControllerBase" assignTo="{!pageController}" required="true" description="The controller for the page." />
</apex:component>

Which on your page you will use as

<c:myComponent pageController="{!pageCont}" />

This will then assign the page controller returned in the "getPageCont" method on your page controller to the "pageController" parameter/property in your component. A method in your page's controller to return itself is needed for the "getPageCont" call.

public PageControllerBase getPageCont()
{
    return this;
}
5
  • 2
    Can you summarise here?
    – Keith C
    Commented Apr 8, 2014 at 13:14
  • 1
    Done :-) Uses snippets from the link.
    – pbattisson
    Commented Apr 8, 2014 at 13:29
  • What is pageCont in the component?
    – MnZ
    Commented Apr 8, 2014 at 13:35
  • 1
    Should be a bit clearer now hopefully - you are assigning the pageControllerBase instance used as the controller of your page to the pageController parameter in the component using an intermediary getPageCont method.
    – pbattisson
    Commented Apr 8, 2014 at 13:38
  • This is impossible to maintain, the view state of the page will be duplicated with each injection.
    – flor
    Commented Oct 28, 2015 at 1:08
8

If you feel passing the entire controller of your visualforce page is a bit too heavy-weighted, or if you need a generic component that can be reused across pages, you can also use a dedicated class to carry the data that you need to transport back and forth between page and component.

I.e. create a 'data' class like this:

public with sharing class ComponentData {
    public String theInput {get;set;}
    public String theOutput {get;set;}
}

In your page controller, instantiate the class:

public ComponentData theData {get;set;}

On your component, use the class as an attribute:

<apex:component controller="CompController">
<apex:attribute type="ComponentData" name="compData" required="true" description="The data going in and out" assignTo="{!cData}"/>

<apex:outputPanel id="banManagerPanel">
    <apex:inputText value="{!cData.input}">
        <apex:actionSupport event="onchange" action="{!updateData}"/>
    </apex:inputText>
</apex:outputPanel>
</apex:component>

On the component controller you can perform whatever logic that needs to be done:

public with sharing class ComponentController {
public ComponentData cData {get;set;}
public void updateData(){
    cData.theOutput = cData.theInput + ' with something extra';
}
}

And finally, on the VF page pass the instantiated data-class to the component:

<c:theComponent compData="{!theData}"/>
<apex:outputText value="{!theData.theOutput}" />

The theData on the VF page will get the updated value that was modified by the component controller, after the button inside the component is pressed.

5
  • I have a button on the page and not on the Component. I mean that I want to capture Component data as well as page data and save it. I'm not able to figure out how to do this...
    – Tasnim
    Commented Oct 1, 2014 at 17:16
  • Hi @helpSFDC, please post a new question on stackexchange, possibly referring this one and we will try helping you. Commented Oct 2, 2014 at 10:50
  • 1
    Thanks for the great answer @guy ! Thats a great way to work with components.
    – MnZ
    Commented Dec 9, 2014 at 12:29
  • 1
    Unfortunately, it looks like the apex:attribute's type attribute doesn't recognize internal classes (which I would normally use for a small class that is essentially a struct), but this is still a much cleaner model than passing around controller refs. Commented Apr 2, 2015 at 13:46
  • I think this is the best way to go.. It closely resembles using the DTO Pattern. Rather than pass the reference to the whole parent page's controller .
    – Soji
    Commented Feb 11, 2021 at 12:10
0

Simple, Create a div on page and assign value to that div from component after execution of component and its controller. Fetch value from that div mentioned in the page.

Let me know if you need example.

Example :-

Here, Assign value to the div with id --> "finalQueryId". You can access this div value on page.

<c:FilterComponent objectName="Contact" fieldsSeparatedByComma="Id,Name,Email" 
                                                                    divId="finalQueryId"/>

<div id="finalQueryId" style="display:none"/>

4
  • Interesting! Can you show the code for assigning the value to the div from component after execution of component and its controller? Commented Apr 15, 2016 at 7:38
  • If the component is referred in the page then you can assign the value to that div directly from component. Lemme add a snippet
    – Soury
    Commented Apr 16, 2016 at 6:41
  • ------- Page code ------ <apex:page> <c:component/> <div id="finalDivId"/> </apex:page> ------- Component code ------ <apex:component> <script> $('#finalDivId').html('Post value you want to -->' + {!controllerVariable}); </script> </apex:component>
    – Soury
    Commented Apr 16, 2016 at 6:45
  • has anyone tried the above approach? it does not work for me unless it needs to add more logic to it.
    – Nick
    Commented Dec 7, 2016 at 16:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .