[SalesForce] Can we use a custom Visualforce component twice on the same Visualforce page

I have created a custom Visualforce component, and I want to include in my Visualforce page two times. I will be passing certain attributes using apex:attribute so that component will function accordingly, but its not working.
When I embed component two times, the second time component works.
My VF page

<apex:page >
 <c:TreeView id="myj" rendered="true"   objectName="Contact"  toolTipField="FirstName">
 </c:TreeView> 
 hello 
 <c:TreeView id="my" rendered="true"  objectName="Account" toolTipField="Name">
 </c:TreeView>  
</apex:page>

My Component

<apex:component controller="treeController">
<apex:includeScript value="{!$Resource.Jquery}"/>   

  <apex:outputPanel id="JSRerender">
      <script type="text/javascript">
      var lazyHtml = "";
      function completionMethod()
      {

        $('input[type=checkbox]').change(function(){
            id = $(this).attr('id');
               fetchByParent(id);
            }
        });

      }     
      </script>
  </apex:outputPanel>

    <apex:form >
     <apex:actionFunction name="fetch" action="{!fetchRecords}" reRender="JSRerender,treePanel" oncomplete="fetchComplete()"/>
    </apex:form>
    <apex:attribute name="objectName" assignTo="{!objectName}" type="String" required="true" description="object Name of which data to be shown"/>

</apex:component>

My Controller

    public class treeController {

        //it contains objects of which tree to be shown    
        public String objectName{get;set;}

        //it contains comma sperated list of ToolTip shown on the node of a tree
        public String toolTipField{get;set;}

        public treeController(){
            //fetchRecords();
        }

        /*
        *it fetches all the records of objectName
        */  

        public void fetchRecords(){
//when i put system.debug(objectName)
//it prints Account as object name also it comes only once in this method while i have used two components so it should come twice
//i want once contact to be printed and once account
//where i am going wrong
    }

Best Answer

Because i don't realy understand your actual problem without any code provided i can only guess. But here are some general minds to this topic.

It works fine until the component don't have "static" elements like css styles or javascript functions whith remain the same (visualforce objects like output panels get unique ids).

For example we have the following component "MyComponent":

<apex:component>
    <apex:attribute name="customColor" type="String" required="false"/>

    <style>
        .myStyle { color:{!customColor}; }
    </style>

    <apex:outputText styleClass="myStyle" value="Please click here" />
</apex:component>

Now we will insert this component twice at our page and give two different values for the "customColor". First one we want to get red color, for the second one - green:

<apex:page>
    Text 1: <c:MyComponent customColor="red" /> <br/>
    Text 2: <c:MyComponent customColor="green" />
</apex:page>

The result looks like this:

enter image description here

This is because the same css style was rendered twice at the main page and the second one won, that is overrides the first style. The same thing happens with javascript functions.

To work around this problem just insert an unique id attribute to the component and provide each static object with this parameter. Our component will look then like this:

<apex:component>
    <apex:attribute name="id" description="The unique id" type="String" required="true"/>
    <apex:attribute name="customColor" description="" type="String" required="false"/>

    <style>
        .myStyle{!id} { color:{!customColor}; }
    </style>

    <apex:outputText styleClass="myStyle{!id}" value="Please click here" />
</apex:component>

At the page we must to enter an id for each instance of component:

<apex:page>
    Text 1: <c:MyComponent id="First" customColor="red" /> <br/>
    Text 2: <c:MyComponent id="Second" customColor="green" />
</apex:page>

And now our main page will be rendered correctly, because each has an unique id:

enter image description here

Related Topic